Initializes a condition object which is associated with the supplied mutex object.
A destructor is present on this object, but not explicitly documented in the source.
Notifies one waiter.
Notifies all waiters.
Wait until notified.
Suspends the calling thread until a notification occurs or until the supplied time period has elapsed.
Gets the mutex associated with this condition.
///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////
1 import core.thread; 2 import core.sync.mutex; 3 import core.sync.semaphore; 4 5 6 void testNotify() 7 { 8 auto mutex = new Mutex; 9 auto condReady = new Condition( mutex ); 10 auto semDone = new Semaphore; 11 auto synLoop = new Object; 12 int numWaiters = 10; 13 int numTries = 10; 14 int numReady = 0; 15 int numTotal = 0; 16 int numDone = 0; 17 int numPost = 0; 18 19 void waiter() 20 { 21 for ( int i = 0; i < numTries; ++i ) 22 { 23 synchronized( mutex ) 24 { 25 while ( numReady < 1 ) 26 { 27 condReady.wait(); 28 } 29 --numReady; 30 ++numTotal; 31 } 32 33 synchronized( synLoop ) 34 { 35 ++numDone; 36 } 37 semDone.wait(); 38 } 39 } 40 41 auto group = new ThreadGroup; 42 43 for ( int i = 0; i < numWaiters; ++i ) 44 group.create( &waiter ); 45 46 for ( int i = 0; i < numTries; ++i ) 47 { 48 for ( int j = 0; j < numWaiters; ++j ) 49 { 50 synchronized( mutex ) 51 { 52 ++numReady; 53 condReady.notify(); 54 } 55 } 56 while ( true ) 57 { 58 synchronized( synLoop ) 59 { 60 if ( numDone >= numWaiters ) 61 break; 62 } 63 Thread.yield(); 64 } 65 for ( int j = 0; j < numWaiters; ++j ) 66 { 67 semDone.notify(); 68 } 69 } 70 71 group.joinAll(); 72 assert( numTotal == numWaiters * numTries ); 73 } 74 75 76 void testNotifyAll() 77 { 78 auto mutex = new Mutex; 79 auto condReady = new Condition( mutex ); 80 int numWaiters = 10; 81 int numReady = 0; 82 int numDone = 0; 83 bool alert = false; 84 85 void waiter() 86 { 87 synchronized( mutex ) 88 { 89 ++numReady; 90 while ( !alert ) 91 condReady.wait(); 92 ++numDone; 93 } 94 } 95 96 auto group = new ThreadGroup; 97 98 for ( int i = 0; i < numWaiters; ++i ) 99 group.create( &waiter ); 100 101 while ( true ) 102 { 103 synchronized( mutex ) 104 { 105 if ( numReady >= numWaiters ) 106 { 107 alert = true; 108 condReady.notifyAll(); 109 break; 110 } 111 } 112 Thread.yield(); 113 } 114 group.joinAll(); 115 assert( numReady == numWaiters && numDone == numWaiters ); 116 } 117 118 119 void testWaitTimeout() 120 { 121 auto mutex = new Mutex; 122 auto condReady = new Condition( mutex ); 123 bool waiting = false; 124 bool alertedOne = true; 125 bool alertedTwo = true; 126 127 void waiter() 128 { 129 synchronized( mutex ) 130 { 131 waiting = true; 132 // we never want to miss the notification (30s) 133 alertedOne = condReady.wait( dur!"seconds"(30) ); 134 // but we don't want to wait long for the timeout (10ms) 135 alertedTwo = condReady.wait( dur!"msecs"(10) ); 136 } 137 } 138 139 auto thread = new Thread( &waiter ); 140 thread.start(); 141 142 while ( true ) 143 { 144 synchronized( mutex ) 145 { 146 if ( waiting ) 147 { 148 condReady.notify(); 149 break; 150 } 151 } 152 Thread.yield(); 153 } 154 thread.join(); 155 assert( waiting ); 156 assert( alertedOne ); 157 assert( !alertedTwo ); 158 } 159 160 testNotify(); 161 testNotifyAll(); 162 testWaitTimeout();
This class represents a condition variable as conceived by C.A.R. Hoare. As per Mesa type monitors however, "signal" has been replaced with "notify" to indicate that control is not transferred to the waiter when a notification is sent.