[jboss-cvs] JBoss Messaging SVN: r4206 - in trunk/src/main/org/jboss/messaging: util and 1 other directory.
jboss-cvs-commits at lists.jboss.org
jboss-cvs-commits at lists.jboss.org
Thu May 15 10:25:42 EDT 2008
Author: jmesnil
Date: 2008-05-15 10:25:42 -0400 (Thu, 15 May 2008)
New Revision: 4206
Added:
trunk/src/main/org/jboss/messaging/util/UUID.java
trunk/src/main/org/jboss/messaging/util/UUIDGenerator.java
trunk/src/main/org/jboss/messaging/util/UUIDTimer.java
Modified:
trunk/src/main/org/jboss/messaging/jms/client/JBossMessageProducer.java
Log:
used our custom UUID to generate JMS Message IDs in JBossMessageProducer.
the UUID is generated in JBossMessageProducer ctor and a sequence number is appended and incremented for every JMS message sent
Modified: trunk/src/main/org/jboss/messaging/jms/client/JBossMessageProducer.java
===================================================================
--- trunk/src/main/org/jboss/messaging/jms/client/JBossMessageProducer.java 2008-05-15 13:02:45 UTC (rev 4205)
+++ trunk/src/main/org/jboss/messaging/jms/client/JBossMessageProducer.java 2008-05-15 14:25:42 UTC (rev 4206)
@@ -21,7 +21,10 @@
*/
package org.jboss.messaging.jms.client;
+import java.net.InetAddress;
+import java.net.UnknownHostException;
import java.util.UUID;
+import java.util.concurrent.atomic.AtomicLong;
import javax.jms.BytesMessage;
import javax.jms.DeliveryMode;
@@ -45,6 +48,7 @@
import org.jboss.messaging.core.logging.Logger;
import org.jboss.messaging.jms.JBossDestination;
import org.jboss.messaging.util.SimpleString;
+import org.jboss.messaging.util.UUIDGenerator;
/**
* @author <a href="mailto:ovidiu at feodorov.com">Ovidiu Feodorov</a>
@@ -75,7 +79,11 @@
private int defaultDeliveryMode = DeliveryMode.PERSISTENT;
- private JBossDestination defaultDestination;
+ private JBossDestination defaultDestination;
+
+ private final String messageIDPrefix;
+
+ private final AtomicLong sequenceNumber = new AtomicLong(0);
// Constructors --------------------------------------------------
@@ -84,6 +92,19 @@
this.producer = producer;
this.defaultDestination = defaultDestination;
+
+ //TODO the UUID should be generated at the JMS Connection level,
+ // then session, producers & messages ID could be created using simple sequences
+ String uuid = null;
+ try
+ {
+ UUIDGenerator gen = UUIDGenerator.getInstance();
+ uuid = gen.generateTimeBasedUUID(InetAddress.getLocalHost()).toString();
+ } catch (UnknownHostException e)
+ {
+ uuid = java.util.UUID.randomUUID().toString();
+ }
+ messageIDPrefix = "ID:" + uuid + ":";
}
// MessageProducer implementation --------------------------------
@@ -396,10 +417,7 @@
if (!disableMessageID)
{
// Generate an id
-
- String id = UUID.randomUUID().toString();
-
- jbm.setJMSMessageID("ID:" + id);
+ jbm.setJMSMessageID(messageIDPrefix + sequenceNumber.incrementAndGet());
}
if (foreign)
Added: trunk/src/main/org/jboss/messaging/util/UUID.java
===================================================================
--- trunk/src/main/org/jboss/messaging/util/UUID.java (rev 0)
+++ trunk/src/main/org/jboss/messaging/util/UUID.java 2008-05-15 14:25:42 UTC (rev 4206)
@@ -0,0 +1,217 @@
+/* JUG Java Uuid Generator
+ *
+ * Copyright (c) 2002- Tatu Saloranta, tatu.saloranta at iki.fi
+ *
+ * Licensed under the License specified in the file LICENSE which is
+ * included with the source code.
+ * You may not use this file except in compliance with the License.
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.jboss.messaging.util;
+
+
+/**
+ * UUID represents Universally Unique Identifiers (aka Global UID in Windows
+ * world). UUIDs are usually generated via UUIDGenerator (or in case of 'Null
+ * UUID', 16 zero bytes, via static method getNullUUID()), or received from
+ * external systems.
+ *
+ * By default class caches the string presentations of UUIDs so that description
+ * is only created the first time it's needed. For memory stingy applications
+ * this caching can be turned off (note though that if uuid.toString() is never
+ * called, desc is never calculated so only loss is the space allocated for the
+ * desc pointer... which can of course be commented out to save memory).
+ *
+ * Similarly, hash code is calculated when it's needed for the first time, and
+ * from thereon that value is just returned. This means that using UUIDs as keys
+ * should be reasonably efficient.
+ *
+ * UUIDs can be compared for equality, serialized, cloned and even sorted.
+ * Equality is a simple bit-wise comparison. Ordering (for sorting) is done by
+ * first ordering based on type (in the order of numeric values of types),
+ * secondarily by time stamp (only for time-based time stamps), and finally by
+ * straight numeric byte-by-byte comparison (from most to least significant
+ * bytes).
+ */
+
+public class UUID
+{
+ private final static String kHexChars = "0123456789abcdefABCDEF";
+
+ public final static byte INDEX_CLOCK_HI = 6;
+ public final static byte INDEX_CLOCK_MID = 4;
+ public final static byte INDEX_CLOCK_LO = 0;
+
+ public final static byte INDEX_TYPE = 6;
+ // Clock seq. & variant are multiplexed...
+ public final static byte INDEX_CLOCK_SEQUENCE = 8;
+ public final static byte INDEX_VARIATION = 8;
+
+ public final static byte TYPE_NULL = 0;
+ public final static byte TYPE_TIME_BASED = 1;
+ public final static byte TYPE_DCE = 2; // Not used
+ public final static byte TYPE_NAME_BASED = 3;
+ public final static byte TYPE_RANDOM_BASED = 4;
+
+ /*
+ * 'Standard' namespaces defined (suggested) by UUID specs:
+ */
+ public final static String NAMESPACE_DNS = "6ba7b810-9dad-11d1-80b4-00c04fd430c8";
+ public final static String NAMESPACE_URL = "6ba7b811-9dad-11d1-80b4-00c04fd430c8";
+ public final static String NAMESPACE_OID = "6ba7b812-9dad-11d1-80b4-00c04fd430c8";
+ public final static String NAMESPACE_X500 = "6ba7b814-9dad-11d1-80b4-00c04fd430c8";
+
+ /*
+ * By default let's cache desc, can be turned off. For hash code there's no
+ * point in turning it off (since the int is already part of the instance
+ * memory allocation); if you want to save those 4 bytes (or possibly bit
+ * more if alignment is bad) just comment out hash caching.
+ */
+ private static boolean sDescCaching = true;
+
+ private final byte[] mId = new byte[16];
+ // Both string presentation and hash value may be cached...
+ private transient String mDesc = null;
+ private transient int mHashCode = 0;
+
+ /**
+ * Protected constructor used by UUIDGenerator
+ *
+ * @param type
+ * UUID type
+ * @param data
+ * 16 byte UUID contents
+ */
+ UUID(int type, byte[] data)
+ {
+ for (int i = 0; i < 16; ++i)
+ {
+ mId[i] = data[i];
+ }
+ // Type is multiplexed with time_hi:
+ mId[INDEX_TYPE] &= (byte) 0x0F;
+ mId[INDEX_TYPE] |= (byte) (type << 4);
+ // Variant masks first two bits of the clock_seq_hi:
+ mId[INDEX_VARIATION] &= (byte) 0x3F;
+ mId[INDEX_VARIATION] |= (byte) 0x80;
+ }
+
+ /**
+ * Could use just the default hash code, but we can probably create a better
+ * identity hash (ie. same contents generate same hash) manually, without
+ * sacrificing speed too much. Although multiplications with modulos would
+ * generate better hashing, let's use just shifts, and do 2 bytes at a time.
+ * <p>
+ * Of course, assuming UUIDs are randomized enough, even simpler approach
+ * might be good enough?
+ * <p>
+ * Is this a good hash? ... one of these days I better read more about basic
+ * hashing techniques I swear!
+ */
+ private final static int[] kShifts = { 3, 7, 17, 21, 29, 4, 9 };
+
+ public int hashCode()
+ {
+ if (mHashCode == 0)
+ {
+ // Let's handle first and last byte separately:
+ int result = mId[0] & 0xFF;
+
+ result |= (result << 16);
+ result |= (result << 8);
+
+ for (int i = 1; i < 15; i += 2)
+ {
+ int curr = (mId[i] & 0xFF) << 8 | (mId[i + 1] & 0xFF);
+ int shift = kShifts[i >> 1];
+
+ if (shift > 16)
+ {
+ result ^= (curr << shift) | (curr >>> (32 - shift));
+ } else
+ {
+ result ^= (curr << shift);
+ }
+ }
+
+ // and then the last byte:
+ int last = mId[15] & 0xFF;
+ result ^= (last << 3);
+ result ^= (last << 13);
+
+ result ^= (last << 27);
+ // Let's not accept hash 0 as it indicates 'not hashed yet':
+ if (result == 0)
+ {
+ mHashCode = -1;
+ } else
+ {
+ mHashCode = result;
+ }
+ }
+ return mHashCode;
+ }
+
+ public String toString()
+ {
+ /*
+ * Could be synchronized, but there isn't much harm in just taking our
+ * chances (ie. in the worst case we'll form the string more than once...
+ * but result is the same)
+ */
+
+ if (mDesc == null)
+ {
+ StringBuffer b = new StringBuffer(36);
+
+ for (int i = 0; i < 16; ++i)
+ {
+ // Need to bypass hyphens:
+ switch (i)
+ {
+ case 4:
+ case 6:
+ case 8:
+ case 10:
+ b.append('-');
+ }
+ int hex = mId[i] & 0xFF;
+ b.append(kHexChars.charAt(hex >> 4));
+ b.append(kHexChars.charAt(hex & 0x0f));
+ }
+ if (!sDescCaching)
+ {
+ return b.toString();
+ }
+ mDesc = b.toString();
+ }
+ return mDesc;
+ }
+
+ /**
+ * Checking equality of UUIDs is easy; just compare the 128-bit number.
+ */
+ public boolean equals(Object o)
+ {
+ if (!(o instanceof UUID))
+ {
+ return false;
+ }
+ byte[] otherId = ((UUID) o).mId;
+ byte[] thisId = mId;
+ for (int i = 0; i < 16; ++i)
+ {
+ if (otherId[i] != thisId[i])
+ {
+ return false;
+ }
+ }
+ return true;
+ }
+}
Added: trunk/src/main/org/jboss/messaging/util/UUIDGenerator.java
===================================================================
--- trunk/src/main/org/jboss/messaging/util/UUIDGenerator.java (rev 0)
+++ trunk/src/main/org/jboss/messaging/util/UUIDGenerator.java 2008-05-15 14:25:42 UTC (rev 4206)
@@ -0,0 +1,97 @@
+/* JUG Java Uuid Generator
+ *
+ * Copyright (c) 2002- Tatu Saloranta, tatu.saloranta at iki.fi
+ *
+ * Licensed under the License specified in the file LICENSE which is
+ * included with the source code.
+ * You may not use this file except in compliance with the License.
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.jboss.messaging.util;
+
+import java.net.InetAddress;
+import java.security.SecureRandom;
+import java.util.Random;
+
+public final class UUIDGenerator
+{
+ private final static UUIDGenerator sSingleton = new UUIDGenerator();
+
+ /**
+ * Random-generator, used by various UUID-generation methods:
+ */
+ private Random mRnd = null;
+
+ private final Object mTimerLock = new Object();
+ private UUIDTimer mTimer = null;
+
+ /**
+ * Constructor is private to enforce singleton access.
+ */
+ private UUIDGenerator()
+ {
+ }
+
+ /**
+ * Method used for accessing the singleton generator instance.
+ */
+ public static UUIDGenerator getInstance()
+ {
+ return sSingleton;
+ }
+
+ /*
+ * ///////////////////////////////////////////////////// // Configuration
+ * /////////////////////////////////////////////////////
+ */
+
+ /**
+ * Method for getting the shared random number generator used for generating
+ * the UUIDs. This way the initialization cost is only taken once; access
+ * need not be synchronized (or in cases where it has to, SecureRandom takes
+ * care of it); it might even be good for getting really 'random' stuff to
+ * get shared access...
+ */
+ public Random getRandomNumberGenerator()
+ {
+ /*
+ * Could be synchronized, but since side effects are trivial (ie.
+ * possibility of generating more than one SecureRandom, of which all but
+ * one are dumped) let's not add synchronization overhead:
+ */
+ if (mRnd == null)
+ {
+ mRnd = new SecureRandom();
+ }
+ return mRnd;
+ }
+
+ public UUID generateTimeBasedUUID(InetAddress addr)
+ {
+ byte[] contents = new byte[16];
+ byte[] byteAddr = addr.getAddress();
+ int pos = 12;
+ for (int i = 0; i < 4; ++i)
+ {
+ contents[pos + i] = byteAddr[i];
+ }
+
+ synchronized (mTimerLock)
+ {
+ if (mTimer == null)
+ {
+ mTimer = new UUIDTimer(getRandomNumberGenerator());
+ }
+
+ mTimer.getTimestamp(contents);
+ }
+
+ return new UUID(UUID.TYPE_TIME_BASED, contents);
+ }
+}
Added: trunk/src/main/org/jboss/messaging/util/UUIDTimer.java
===================================================================
--- trunk/src/main/org/jboss/messaging/util/UUIDTimer.java (rev 0)
+++ trunk/src/main/org/jboss/messaging/util/UUIDTimer.java 2008-05-15 14:25:42 UTC (rev 4206)
@@ -0,0 +1,317 @@
+/* JUG Java Uuid Generator
+ *
+ * Copyright (c) 2002- Tatu Saloranta, tatu.saloranta at iki.fi
+ *
+ * Licensed under the License specified in the file LICENSE which is
+ * included with the source code.
+ * You may not use this file except in compliance with the License.
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.jboss.messaging.util;
+
+import java.util.Random;
+
+/**
+ * UUIDTimer produces the time stamps required for time-based UUIDs. It works as
+ * outlined in the UUID specification, with following implementation:
+ * <ul>
+ * <li>Java classes can only product time stamps with maximum resolution of one
+ * millisecond (at least before JDK 1.5). To compensate, an additional counter
+ * is used, so that more than one UUID can be generated between java clock
+ * updates. Counter may be used to generate up to 10000 UUIDs for each distrinct
+ * java clock value.
+ * <li>Due to even lower clock resolution on some platforms (older Windows
+ * versions use 55 msec resolution), timestamp value can also advanced ahead of
+ * physical value within limits (by default, up 100 millisecond ahead of
+ * reported), iff necessary (ie. 10000 instances created before clock time
+ * advances).
+ * <li>As an additional precaution, counter is initialized not to 0 but to a
+ * random 8-bit number, and each time clock changes, lowest 8-bits of counter
+ * are preserved. The purpose it to make likelyhood of multi-JVM multi-instance
+ * generators to collide, without significantly reducing max. UUID generation
+ * speed. Note though that using more than one generator (from separate JVMs) is
+ * strongly discouraged, so hopefully this enhancement isn't needed. This 8-bit
+ * offset has to be reduced from total max. UUID count to preserve ordering
+ * property of UUIDs (ie. one can see which UUID was generated first for given
+ * UUID generator); the resulting 9500 UUIDs isn't much different from the
+ * optimal choice.
+ * <li>Finally, as of version 2.0 and onwards, optional external timestamp
+ * synchronization can be done. This is done similar to the way UUID
+ * specification suggests; except that since there is no way to lock the whole
+ * system, file-based locking is used. This works between multiple JVMs and Jug
+ * instances.
+ * </ul>
+ * <p>
+ * Some additional assumptions about calculating the timestamp:
+ * <ul>
+ * <li>System.currentTimeMillis() is assumed to give time offset in UTC, or at
+ * least close enough thing to get correct timestamps. The alternate route would
+ * have to go through calendar object, use TimeZone offset to get to UTC, and
+ * then modify. Using currentTimeMillis should be much faster to allow rapid
+ * UUID creation.
+ * <li>Similarly, the constant used for time offset between 1.1.1970 and start
+ * of Gregorian calendar is assumed to be correct (which seems to be the case
+ * when testing with Java calendars).
+ * </ul>
+ * <p>
+ * Note about synchronization: this class is assumed to always be called from a
+ * synchronized context (caller locks on either this object, or a similar timer
+ * lock), and so has no method synchronization.
+ */
+public class UUIDTimer
+{
+ // // // Constants
+
+ /**
+ * Since System.longTimeMillis() returns time from january 1st 1970, and
+ * UUIDs need time from the beginning of gregorian calendar (15-oct-1582),
+ * need to apply the offset:
+ */
+ private final static long kClockOffset = 0x01b21dd213814000L;
+ /**
+ * Also, instead of getting time in units of 100nsecs, we get something with
+ * max resolution of 1 msec... and need the multiplier as well
+ */
+ private final static long kClockMultiplier = 10000;
+ private final static long kClockMultiplierL = 10000L;
+
+ /**
+ * Let's allow "virtual" system time to advance at most 100 milliseconds
+ * beyond actual physical system time, before adding delays.
+ */
+ private final static long kMaxClockAdvance = 100L;
+
+ // // // Configuration
+
+ private final Random mRnd;
+
+ // // // Clock state:
+
+ /**
+ * Additional state information used to protect against anomalous cases
+ * (clock time going backwards, node id getting mixed up). Third byte is
+ * actually used for seeding counter on counter overflow.
+ */
+ private final byte[] mClockSequence = new byte[3];
+
+ /**
+ * Last physical timestamp value <code>System.currentTimeMillis()</code>
+ * returned: used to catch (and report) cases where system clock goes
+ * backwards. Is also used to limit "drifting", that is, amount timestamps
+ * used can differ from the system time value. This value is not guaranteed
+ * to be monotonically increasing.
+ */
+ private long mLastSystemTimestamp = 0L;
+
+ /**
+ * Timestamp value last used for generating a UUID (along with
+ * {@link #mClockCounter}. Usually the same as {@link #mLastSystemTimestamp},
+ * but not always (system clock moved backwards). Note that this value is
+ * guaranteed to be monotonically increasing; that is, at given absolute time
+ * points t1 and t2 (where t2 is after t1), t1 <= t2 will always hold true.
+ */
+ private long mLastUsedTimestamp = 0L;
+
+ /**
+ * Counter used to compensate inadequate resolution of JDK system timer.
+ */
+ private int mClockCounter = 0;
+
+ UUIDTimer(Random rnd)
+ {
+ mRnd = rnd;
+ initCounters(rnd);
+ mLastSystemTimestamp = 0L;
+ // This may get overwritten by the synchronizer
+ mLastUsedTimestamp = 0L;
+ }
+
+ private void initCounters(Random rnd)
+ {
+ /*
+ * Let's generate the clock sequence field now; as with counter, this
+ * reduces likelihood of collisions (as explained in UUID specs)
+ */
+ rnd.nextBytes(mClockSequence);
+ /*
+ * Ok, let's also initialize the counter... Counter is used to make it
+ * slightly less likely that two instances of UUIDGenerator (from separate
+ * JVMs as no more than one can be created in one JVM) would produce
+ * colliding time-based UUIDs. The practice of using multiple generators,
+ * is strongly discouraged, of course, but just in case...
+ */
+ mClockCounter = mClockSequence[2] & 0xFF;
+ }
+
+ public void getTimestamp(byte[] uuidData)
+ {
+ // First the clock sequence:
+ uuidData[UUID.INDEX_CLOCK_SEQUENCE] = mClockSequence[0];
+ uuidData[UUID.INDEX_CLOCK_SEQUENCE + 1] = mClockSequence[1];
+
+ long systime = System.currentTimeMillis();
+
+ /*
+ * Let's first verify that the system time is not going backwards;
+ * independent of whether we can use it:
+ */
+ if (systime < mLastSystemTimestamp)
+ {
+ // Logger.logWarning("System time going backwards! (got value
+ // "+systime+", last "+mLastSystemTimestamp);
+ // Let's write it down, still
+ mLastSystemTimestamp = systime;
+ }
+
+ /*
+ * But even without it going backwards, it may be less than the last one
+ * used (when generating UUIDs fast with coarse clock resolution; or if
+ * clock has gone backwards over reboot etc).
+ */
+ if (systime <= mLastUsedTimestamp)
+ {
+ /*
+ * Can we just use the last time stamp (ok if the counter hasn't hit
+ * max yet)
+ */
+ if (mClockCounter < kClockMultiplier)
+ { // yup, still have room
+ systime = mLastUsedTimestamp;
+ } else
+ { // nope, have to roll over to next value and maybe wait
+ long actDiff = mLastUsedTimestamp - systime;
+ long origTime = systime;
+ systime = mLastUsedTimestamp + 1L;
+
+ // Logger.logWarning("Timestamp over-run: need to reinitialize
+ // random sequence");
+
+ /*
+ * Clock counter is now at exactly the multiplier; no use just
+ * anding its value. So, we better get some random numbers
+ * instead...
+ */
+ initCounters(mRnd);
+
+ /*
+ * But do we also need to slow down? (to try to keep virtual time
+ * close to physical time; ie. either catch up when system clock has
+ * been moved backwards, or when coarse clock resolution has forced
+ * us to advance virtual timer too far)
+ */
+ if (actDiff >= kMaxClockAdvance)
+ {
+ slowDown(origTime, actDiff);
+ }
+ }
+ } else
+ {
+ /*
+ * Clock has advanced normally; just need to make sure counter is reset
+ * to a low value (need not be 0; good to leave a small residual to
+ * further decrease collisions)
+ */
+ mClockCounter &= 0xFF;
+ }
+
+ mLastUsedTimestamp = systime;
+
+ /*
+ * Now, let's translate the timestamp to one UUID needs, 100ns unit offset
+ * from the beginning of Gregorian calendar...
+ */
+ systime *= kClockMultiplierL;
+ systime += kClockOffset;
+
+ // Plus add the clock counter:
+ systime += mClockCounter;
+ // and then increase
+ ++mClockCounter;
+
+ /*
+ * Time fields are nicely split across the UUID, so can't just linearly
+ * dump the stamp:
+ */
+ int clockHi = (int) (systime >>> 32);
+ int clockLo = (int) systime;
+
+ uuidData[UUID.INDEX_CLOCK_HI] = (byte) (clockHi >>> 24);
+ uuidData[UUID.INDEX_CLOCK_HI + 1] = (byte) (clockHi >>> 16);
+ uuidData[UUID.INDEX_CLOCK_MID] = (byte) (clockHi >>> 8);
+ uuidData[UUID.INDEX_CLOCK_MID + 1] = (byte) clockHi;
+
+ uuidData[UUID.INDEX_CLOCK_LO] = (byte) (clockLo >>> 24);
+ uuidData[UUID.INDEX_CLOCK_LO + 1] = (byte) (clockLo >>> 16);
+ uuidData[UUID.INDEX_CLOCK_LO + 2] = (byte) (clockLo >>> 8);
+ uuidData[UUID.INDEX_CLOCK_LO + 3] = (byte) clockLo;
+ }
+
+ /*
+ * /////////////////////////////////////////////////////////// // Private
+ * methods ///////////////////////////////////////////////////////////
+ */
+
+ private final static int MAX_WAIT_COUNT = 50;
+
+ /**
+ * Simple utility method to use to wait for couple of milliseconds, to let
+ * system clock hopefully advance closer to the virtual timestamps used.
+ * Delay is kept to just a millisecond or two, to prevent excessive blocking;
+ * but that should be enough to eventually synchronize physical clock with
+ * virtual clock values used for UUIDs.
+ *
+ * @param msecs
+ * Number of milliseconds to wait for from current time point
+ */
+ private final static void slowDown(long startTime, long actDiff)
+ {
+ /*
+ * First, let's determine how long we'd like to wait. This is based on how
+ * far ahead are we as of now.
+ */
+ long ratio = actDiff / kMaxClockAdvance;
+ long delay;
+
+ if (ratio < 2L)
+ { // 200 msecs or less
+ delay = 1L;
+ } else if (ratio < 10L)
+ { // 1 second or less
+ delay = 2L;
+ } else if (ratio < 600L)
+ { // 1 minute or less
+ delay = 3L;
+ } else
+ {
+ delay = 5L;
+ }
+ // Logger.logWarning("Need to wait for "+delay+" milliseconds; virtual
+ // clock advanced too far in the future");
+ long waitUntil = startTime + delay;
+ int counter = 0;
+ do
+ {
+ try
+ {
+ Thread.sleep(delay);
+ } catch (InterruptedException ie)
+ {
+ }
+ delay = 1L;
+ /*
+ * This is just a sanity check: don't want an "infinite" loop if clock
+ * happened to be moved backwards by, say, an hour...
+ */
+ if (++counter > MAX_WAIT_COUNT)
+ {
+ break;
+ }
+ } while (System.currentTimeMillis() < waitUntil);
+ }
+}
More information about the jboss-cvs-commits
mailing list