Thanks Gregg.

On 24/12/2013 3:04 AM, Gregg Wonderly wrote:
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