Skip to content

Commit 423014c

Browse files
committed
module core.sync.event2 added
1 parent 4f59ece commit 423014c

File tree

1 file changed

+123
-0
lines changed

1 file changed

+123
-0
lines changed

druntime/src/core/sync/event2.d

+123
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
/**
2+
* The event module provides a primitive for lightweight signaling of other threads
3+
* (emulating Windows events on Posix)
4+
*
5+
* Copyright: Copyright (c) 2019 D Language Foundation
6+
* License: Distributed under the
7+
* $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost Software License 1.0).
8+
* (See accompanying file LICENSE)
9+
*/
10+
module core.sync.event2;
11+
12+
import core.time;
13+
14+
struct Event2
15+
{
16+
nothrow @nogc:
17+
/**
18+
* Creates an event object.
19+
*
20+
* Params:
21+
* manualReset = the state of the event is not reset automatically after resuming waiting clients
22+
* initialState = initial state of the signal
23+
*/
24+
this(bool manualReset, bool initialState)
25+
{
26+
osEvent = OsEvent(manualReset, initialState);
27+
}
28+
29+
// copying not allowed, can produce resource leaks
30+
@disable this(this);
31+
@disable void opAssign(Event);
32+
33+
/// Set the event to "signaled", so that waiting clients are resumed
34+
void set()
35+
{
36+
osEvent.set();
37+
}
38+
39+
/// Reset the event manually
40+
void reset()
41+
{
42+
osEvent.reset();
43+
}
44+
45+
/**
46+
* Wait for the event to be signaled without timeout.
47+
*
48+
* Returns:
49+
* `true` if the event is in signaled state, `false` if the event is uninitialized or another error occured
50+
*/
51+
bool wait()
52+
{
53+
return osEvent.wait();
54+
}
55+
56+
/**
57+
* Wait for the event to be signaled with timeout.
58+
*
59+
* Params:
60+
* tmout = the maximum time to wait
61+
* Returns:
62+
* `true` if the event is in signaled state, `false` if the event was nonsignaled for the given time or
63+
* the event is uninitialized or another error occured
64+
*/
65+
bool wait(Duration tmout)
66+
{
67+
return osEvent.wait(tmout);
68+
}
69+
70+
private:
71+
import rt.sys.config;
72+
73+
mixin("import " ~ osEventImport ~ ";");
74+
OsEvent osEvent;
75+
}
76+
77+
// Test single-thread (non-shared) use.
78+
@nogc nothrow unittest
79+
{
80+
// auto-reset, initial state false
81+
Event ev1 = Event2(false, false);
82+
assert(!ev1.wait(1.dur!"msecs"));
83+
ev1.set();
84+
assert(ev1.wait());
85+
assert(!ev1.wait(1.dur!"msecs"));
86+
87+
// manual-reset, initial state true
88+
Event ev2 = Event(true, true);
89+
assert(ev2.wait());
90+
assert(ev2.wait());
91+
ev2.reset();
92+
assert(!ev2.wait(1.dur!"msecs"));
93+
}
94+
95+
unittest
96+
{
97+
import core.thread, core.atomic;
98+
99+
scope event = new Event2(true, false);
100+
int numThreads = 10;
101+
shared int numRunning = 0;
102+
103+
void testFn()
104+
{
105+
event.wait(8.dur!"seconds"); // timeout below limit for druntime test_runner
106+
numRunning.atomicOp!"+="(1);
107+
}
108+
109+
auto group = new ThreadGroup;
110+
111+
for (int i = 0; i < numThreads; ++i)
112+
group.create(&testFn);
113+
114+
auto start = MonoTime.currTime;
115+
assert(numRunning == 0);
116+
117+
event.set();
118+
group.joinAll();
119+
120+
assert(numRunning == numThreads);
121+
122+
assert(MonoTime.currTime - start < 5.dur!"seconds");
123+
}

0 commit comments

Comments
 (0)