Condition

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.

Constructors

this
this(Mutex m)

Initializes a condition object which is associated with the supplied mutex object.

Destructor

A destructor is present on this object, but not explicitly documented in the source.

Members

Functions

notify
void notify()
void notify(bool _unused_)

Notifies one waiter.

notifyAll
void notifyAll()
void notifyAll(bool _unused_)

Notifies all waiters.

wait
void wait()
void wait(bool _unused_)

Wait until notified.

wait
bool wait(Duration val)
bool wait(Duration val, bool _unused_)

Suspends the calling thread until a notification occurs or until the supplied time period has elapsed.

Properties

mutex
Mutex mutex [@property getter]
shared(Mutex) mutex [@property getter]

Gets the mutex associated with this condition.

Examples

///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////

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();

Meta