The value for “now” needs to be reestablished in the loop, or else this loop 
will wait too long on a spurious wake up.

Gregg

On Dec 23, 2013, at 5:52 AM, peter_firmst...@apache.org wrote:

> Author: peter_firmstone
> Date: Mon Dec 23 11:52:40 2013
> New Revision: 1553097
> 
> URL: http://svn.apache.org/r1553097
> Log:
> After considerable testing using a multi threaded Executor and Runnable tasks 
> to CAS an AtomicLong to generate 100% cpu load, no data races were found, it 
> is suspected that Object.wait is subject to spurious wake-up's on some 
> platforms when they are not contained within a loop that checks the present 
> condition and this is causing the test failures:
> 
> 
> 
> 
> Modified:
>    
> river/jtsk/skunk/qa_refactor/trunk/qa/src/com/sun/jini/qa/harness/QAConfig.java
>    
> river/jtsk/skunk/qa_refactor/trunk/qa/src/com/sun/jini/test/impl/norm/LeaseExpirationTest.java
>    
> river/jtsk/skunk/qa_refactor/trunk/qa/src/com/sun/jini/test/impl/outrigger/notify/ThrowRuntimeException.java
>    
> river/jtsk/skunk/qa_refactor/trunk/qa/src/com/sun/jini/test/share/BaseQATest.java
>    
> river/jtsk/skunk/qa_refactor/trunk/qa/src/com/sun/jini/test/spec/jeri/mux/ClientFlowControlTest.java
>    
> river/jtsk/skunk/qa_refactor/trunk/qa/src/com/sun/jini/test/spec/jeri/mux/CloseTest.java
>    
> river/jtsk/skunk/qa_refactor/trunk/qa/src/com/sun/jini/test/spec/jeri/mux/MuxClientTest.java
>    
> river/jtsk/skunk/qa_refactor/trunk/qa/src/com/sun/jini/test/spec/renewalmanager/EventTest.java
>    
> river/jtsk/skunk/qa_refactor/trunk/src/net/jini/discovery/AbstractLookupDiscovery.java
> 
> Modified: 
> river/jtsk/skunk/qa_refactor/trunk/qa/src/com/sun/jini/qa/harness/QAConfig.java
> URL: 
> http://svn.apache.org/viewvc/river/jtsk/skunk/qa_refactor/trunk/qa/src/com/sun/jini/qa/harness/QAConfig.java?rev=1553097&r1=1553096&r2=1553097&view=diff
> ==============================================================================
> --- 
> river/jtsk/skunk/qa_refactor/trunk/qa/src/com/sun/jini/qa/harness/QAConfig.java
>  (original)
> +++ 
> river/jtsk/skunk/qa_refactor/trunk/qa/src/com/sun/jini/qa/harness/QAConfig.java
>  Mon Dec 23 11:52:40 2013
> @@ -2213,7 +2213,7 @@ public class QAConfig implements Seriali
>             if (fqHostName.contains(nxdomain)) return hostName;
>             return fqHostName;
>       } catch (UnknownHostException ignore) {
> -            logger.severe("InetAddress threw unknown host exception: " + 
> hostName);
> +            logger.info("InetAddress threw unknown host exception: " + 
> hostName);
>       }
>       return hostName;
>     }
> 
> Modified: 
> river/jtsk/skunk/qa_refactor/trunk/qa/src/com/sun/jini/test/impl/norm/LeaseExpirationTest.java
> URL: 
> http://svn.apache.org/viewvc/river/jtsk/skunk/qa_refactor/trunk/qa/src/com/sun/jini/test/impl/norm/LeaseExpirationTest.java?rev=1553097&r1=1553096&r2=1553097&view=diff
> ==============================================================================
> --- 
> river/jtsk/skunk/qa_refactor/trunk/qa/src/com/sun/jini/test/impl/norm/LeaseExpirationTest.java
>  (original)
> +++ 
> river/jtsk/skunk/qa_refactor/trunk/qa/src/com/sun/jini/test/impl/norm/LeaseExpirationTest.java
>  Mon Dec 23 11:52:40 2013
> @@ -360,12 +360,13 @@ public class LeaseExpirationTest extends
>           if (count != 0) 
>               return false;
> 
> -         final long now = System.currentTimeMillis();
> +         long now = System.currentTimeMillis();
>           synchronized (this) {
> -             if (setExpiration > now) {
> +             while (setExpiration > now) {
>                   logger.log(Level.INFO, "Waiting for " + (setExpiration - 
> now) 
>                         + " ms for set lease to expire");
>                   wait(setExpiration - now);
> +                    now = System.currentTimeMillis();
>                 }
>           }
>           return true;
> 
> Modified: 
> river/jtsk/skunk/qa_refactor/trunk/qa/src/com/sun/jini/test/impl/outrigger/notify/ThrowRuntimeException.java
> URL: 
> http://svn.apache.org/viewvc/river/jtsk/skunk/qa_refactor/trunk/qa/src/com/sun/jini/test/impl/outrigger/notify/ThrowRuntimeException.java?rev=1553097&r1=1553096&r2=1553097&view=diff
> ==============================================================================
> --- 
> river/jtsk/skunk/qa_refactor/trunk/qa/src/com/sun/jini/test/impl/outrigger/notify/ThrowRuntimeException.java
>  (original)
> +++ 
> river/jtsk/skunk/qa_refactor/trunk/qa/src/com/sun/jini/test/impl/outrigger/notify/ThrowRuntimeException.java
>  Mon Dec 23 11:52:40 2013
> @@ -196,14 +196,16 @@ public class ThrowRuntimeException exten
>          */
>         long listener1Rcvd;
>         synchronized (listener1) {
> -
> +            long duration = wait;
> +            long finish = System.currentTimeMillis() + duration;
> +            
>             // Did it already happen?
>             listener1Rcvd = listener1.lastEvent();
> 
> -            if (listener1Rcvd < ev1) {
> +            while (listener1Rcvd < ev1) {
> 
>                 // No, wait
> -                listener1.wait(wait);
> +                listener1.wait(duration);
>                 listener1Rcvd = listener1.lastEvent();
> 
>                 if (listener1Rcvd < 0) {
> @@ -214,6 +216,8 @@ public class ThrowRuntimeException exten
>                             "First listener received too many events");
>                 }
>                 logger.log(Level.INFO, "Received correct event");
> +                duration = finish - System.currentTimeMillis();
> +                if (duration <= 0) break;
>             }
>         }
> 
> @@ -254,12 +258,14 @@ public class ThrowRuntimeException exten
> 
>         // Wait for event and check to see if it is the right one
>         synchronized (listener2) {
> -
> +            long duration = wait;
> +            long finish = System.currentTimeMillis() + duration;
> +            
>             // Did it already happen?
> -            if (listener2.lastEvent() < ev1) {
> +            while (listener2.lastEvent() < ev1) {
> 
>                 // No wait
> -                listener2.wait(wait);
> +                listener2.wait(duration);
> 
>                 if (listener2.lastEvent() < 0) {
>                     throw new TestException(
> @@ -268,6 +274,8 @@ public class ThrowRuntimeException exten
>                     throw new TestException(
>                             "Second listener received too many events");
>                 }
> +                duration = finish - System.currentTimeMillis();
> +                if (duration <= 0) break;
>             }
>         }
>         logger.log(Level.INFO, "2nd handler received correct event");
> 
> Modified: 
> river/jtsk/skunk/qa_refactor/trunk/qa/src/com/sun/jini/test/share/BaseQATest.java
> URL: 
> http://svn.apache.org/viewvc/river/jtsk/skunk/qa_refactor/trunk/qa/src/com/sun/jini/test/share/BaseQATest.java?rev=1553097&r1=1553096&r2=1553097&view=diff
> ==============================================================================
> --- 
> river/jtsk/skunk/qa_refactor/trunk/qa/src/com/sun/jini/test/share/BaseQATest.java
>  (original)
> +++ 
> river/jtsk/skunk/qa_refactor/trunk/qa/src/com/sun/jini/test/share/BaseQATest.java
>  Mon Dec 23 11:52:40 2013
> @@ -1638,7 +1638,13 @@ abstract public class BaseQATest extends
>                     }//endif
>                 }//endif(nEventsReceived == nEventsExpected)
>                 try {
> -                    listener.wait(1000); // Wait for discovery for up to 
> 1000 ms.
> +                    long startTime = System.currentTimeMillis();
> +                    long finishTime = startTime + 1000;
> +                    long remain = 1000;
> +                    do {
> +                        listener.wait(remain); // Wait for discovery for 
> 1000 ms.
> +                        remain = finishTime - System.currentTimeMillis();
> +                    } while (remain > 0); //To avoid spurious wakeup
>                 } catch (InterruptedException ex) {
>                     throw new TestException("Interrupted while waiting for 
> discovery", ex);
>                 }
> @@ -1794,7 +1800,13 @@ abstract public class BaseQATest extends
>                     }//endif
>                 }//endif(nEventsReceived == nEventsExpected)
>                 try {
> -                    listener.wait(1000);
> +                    long startTime = System.currentTimeMillis();
> +                    long finishTime = startTime + 1000;
> +                    long remain = 1000;
> +                    do {
> +                        listener.wait(remain); // Wait for discovery for 
> 1000 ms.
> +                        remain = finishTime - System.currentTimeMillis();
> +                    } while (remain > 0); //To avoid spurious wakeup
>                 } catch (InterruptedException ex) {
>                     throw new TestException("Test interrupted while waiting 
> for discard", ex);
>                 }
> @@ -1948,10 +1960,17 @@ abstract public class BaseQATest extends
>                     }//endif
>                 }//endif(nEventsReceived == nEventsExpected)
>                 try {
> -                    listener.wait(1000);
> +                    long startTime = System.currentTimeMillis();
> +                    long finishTime = startTime + 1000;
> +                    long remain = 1000;
> +                    do {
> +                        listener.wait(remain); // Wait for discovery for 
> 1000 ms.
> +                        remain = finishTime - System.currentTimeMillis();
> +                    } while (remain > 0); //To avoid spurious wakeup
>                 } catch (InterruptedException ex) {
>                     throw new TestException("Test interrupted while waiting 
> for change event", ex);
>                 }
> +                // can't do this anymore because we need to release sync 
> first.
>                 //DiscoveryServiceUtil.delayMS(1000);
>                 showCompInfo = false;//display comparison info only when i = 0
>             }//end loop(iLoop)
> 
> Modified: 
> river/jtsk/skunk/qa_refactor/trunk/qa/src/com/sun/jini/test/spec/jeri/mux/ClientFlowControlTest.java
> URL: 
> http://svn.apache.org/viewvc/river/jtsk/skunk/qa_refactor/trunk/qa/src/com/sun/jini/test/spec/jeri/mux/ClientFlowControlTest.java?rev=1553097&r1=1553096&r2=1553097&view=diff
> ==============================================================================
> --- 
> river/jtsk/skunk/qa_refactor/trunk/qa/src/com/sun/jini/test/spec/jeri/mux/ClientFlowControlTest.java
>  (original)
> +++ 
> river/jtsk/skunk/qa_refactor/trunk/qa/src/com/sun/jini/test/spec/jeri/mux/ClientFlowControlTest.java
>  Mon Dec 23 11:52:40 2013
> @@ -171,7 +171,12 @@ public class ClientFlowControlTest exten
>     private Socket getConnection() throws InterruptedException {
>         if (s==null) {
>             synchronized (lock) {
> -                lock.wait(2 * getTimeout());
> +                long duration = 2 * getTimeout();
> +                long finish = System.currentTimeMillis() + duration;
> +                do {
> +                    lock.wait(duration);
> +                    duration = finish - System.currentTimeMillis();
> +                } while ( s == null && duration > 0);
>             }
>         }
>         Socket temp = s;
> 
> Modified: 
> river/jtsk/skunk/qa_refactor/trunk/qa/src/com/sun/jini/test/spec/jeri/mux/CloseTest.java
> URL: 
> http://svn.apache.org/viewvc/river/jtsk/skunk/qa_refactor/trunk/qa/src/com/sun/jini/test/spec/jeri/mux/CloseTest.java?rev=1553097&r1=1553096&r2=1553097&view=diff
> ==============================================================================
> --- 
> river/jtsk/skunk/qa_refactor/trunk/qa/src/com/sun/jini/test/spec/jeri/mux/CloseTest.java
>  (original)
> +++ 
> river/jtsk/skunk/qa_refactor/trunk/qa/src/com/sun/jini/test/spec/jeri/mux/CloseTest.java
>  Mon Dec 23 11:52:40 2013
> @@ -158,7 +158,12 @@ public class CloseTest extends AbstractM
>     private Socket getConnection() throws InterruptedException {
>         if (s==null) {
>             synchronized (lock) {
> -                lock.wait(2 * getTimeout());
> +                long duration = 2 * getTimeout();
> +                long finish = System.currentTimeMillis() + duration;
> +                do {
> +                    lock.wait(duration);
> +                    duration = finish - System.currentTimeMillis();
> +                } while ( s == null && duration > 0);
>             }
>         }
>         Socket temp = s;
> 
> Modified: 
> river/jtsk/skunk/qa_refactor/trunk/qa/src/com/sun/jini/test/spec/jeri/mux/MuxClientTest.java
> URL: 
> http://svn.apache.org/viewvc/river/jtsk/skunk/qa_refactor/trunk/qa/src/com/sun/jini/test/spec/jeri/mux/MuxClientTest.java?rev=1553097&r1=1553096&r2=1553097&view=diff
> ==============================================================================
> --- 
> river/jtsk/skunk/qa_refactor/trunk/qa/src/com/sun/jini/test/spec/jeri/mux/MuxClientTest.java
>  (original)
> +++ 
> river/jtsk/skunk/qa_refactor/trunk/qa/src/com/sun/jini/test/spec/jeri/mux/MuxClientTest.java
>  Mon Dec 23 11:52:40 2013
> @@ -218,7 +218,12 @@ public class MuxClientTest extends Abstr
>     private Socket getConnection() throws InterruptedException {
>         if (s==null) {
>             synchronized (lock) {
> -                lock.wait(2 * getTimeout());
> +                long duration = 2 * getTimeout();
> +                long finish = System.currentTimeMillis() + duration;
> +                do {
> +                    lock.wait(duration);
> +                    duration = finish - System.currentTimeMillis();
> +                } while ( s == null && duration > 0);
>             }
>         }
>         Socket temp = s;
> 
> Modified: 
> river/jtsk/skunk/qa_refactor/trunk/qa/src/com/sun/jini/test/spec/renewalmanager/EventTest.java
> URL: 
> http://svn.apache.org/viewvc/river/jtsk/skunk/qa_refactor/trunk/qa/src/com/sun/jini/test/spec/renewalmanager/EventTest.java?rev=1553097&r1=1553096&r2=1553097&view=diff
> ==============================================================================
> --- 
> river/jtsk/skunk/qa_refactor/trunk/qa/src/com/sun/jini/test/spec/renewalmanager/EventTest.java
>  (original)
> +++ 
> river/jtsk/skunk/qa_refactor/trunk/qa/src/com/sun/jini/test/spec/renewalmanager/EventTest.java
>  Mon Dec 23 11:52:40 2013
> @@ -356,7 +356,11 @@ public class EventTest extends QATestEnv
>       synchronized (this) {
>           if (null == (failedComponet = hadEarlyFailure(leases))) {
>               // let run() propogate InterruptedException
> -             wait(waitUntil - System.currentTimeMillis());
> +                long duration = waitUntil - System.currentTimeMillis();
> +                do {
> +                    wait(duration);
> +                    duration = waitUntil - System.currentTimeMillis();
> +                } while (duration > 0);
>               failedComponet = hadEarlyFailure(leases);
>           }
>       }
> 
> Modified: 
> river/jtsk/skunk/qa_refactor/trunk/src/net/jini/discovery/AbstractLookupDiscovery.java
> URL: 
> http://svn.apache.org/viewvc/river/jtsk/skunk/qa_refactor/trunk/src/net/jini/discovery/AbstractLookupDiscovery.java?rev=1553097&r1=1553096&r2=1553097&view=diff
> ==============================================================================
> --- 
> river/jtsk/skunk/qa_refactor/trunk/src/net/jini/discovery/AbstractLookupDiscovery.java
>  (original)
> +++ 
> river/jtsk/skunk/qa_refactor/trunk/src/net/jini/discovery/AbstractLookupDiscovery.java
>  Mon Dec 23 11:52:40 2013
> @@ -816,11 +816,12 @@ abstract class AbstractLookupDiscovery i
>                     sleep(multicastAnnouncementInterval);
>                     long curTime = System.currentTimeMillis();
>                     synchronized (registrars) {
> -                        /* can't modify regInfo while iterating over it, 
> -                         * so clone it
> +                        /* Previously regInfo was cloned to avoid 
> synchronizing
> +                         * this was changed to a simple synchronized block 
> during code
> +                         * auditing as it appeared like an unnecessary 
> +                         * performance optimisation that risked atomicity.
>                          */
> -                        HashMap<ServiceID,AnnouncementInfo> regInfoClone = 
> (HashMap<ServiceID,AnnouncementInfo>) regInfo.clone();
> -                        Set<Map.Entry<ServiceID,AnnouncementInfo>> eSet = 
> regInfoClone.entrySet();
> +                        Set<Map.Entry<ServiceID,AnnouncementInfo>> eSet = 
> regInfo.entrySet();
>                         for(Iterator<Map.Entry<ServiceID,AnnouncementInfo>> 
> itr = eSet.iterator(); itr.hasNext(); ) {
>                             Map.Entry<ServiceID,AnnouncementInfo> pair   = 
> itr.next();
>                             ServiceID srvcID = pair.getKey();
> 
> 

Reply via email to