Commit 1cd7425
committed
fix(threading): AutoResetEvent and ManualResetEvent are WaitHandles (#1958, SR-AUD-209)
This closes #1958, the last of its eight members.
Both types had no base class and no vtable, each carrying its own mutex,
condition variable and signalled flag -- a third and fourth copy of logic
EventWaitHandle already had. They are now what .NET declares: sealed classes
deriving from EventWaitHandle whose ENTIRE BODY is one constructor
(AutoResetEvent.cs:6-9, ManualResetEvent.cs:6-9). Neither declares a member of
its own, so this deletes the duplicated bodies rather than adding a base to
them.
WHY IT MATTERED: because they were not WaitHandles, WaitHandle::WaitAll and
WaitAny -- repaired by #1952 and documented ever since -- could not accept them
at all. Not a wrong answer: the code did not compile.
TWO THINGS THE FINDING DID NOT NAME, both required:
1. EventWaitHandle had no closed state. #1956 gave Mutex, AutoResetEvent and
ManualResetEvent a closed_ flag; EventWaitHandle was its fourth case and
was missed, so Close() reached WaitHandle's EMPTY Dispose() and did
nothing. Deriving without fixing that would have silently reverted #1956
for both events.
2. EventWaitHandle::Set() lost wakeups -- it stored and notified without
holding mtx_, so a waiter that had evaluated the predicate as false but
not yet slept missed the notification. AutoResetEvent::Set() took the
lock, so deriving would have INTRODUCED the race into a type that did not
have it. Probed over 900 single-waiter rounds: EventWaitHandle lost 2,
AutoResetEvent lost 0. cna holds this type by value in six places, all for
async completion.
Layout: both events 96 -> 112, EventWaitHandle 104 -> 112; consumers rebuild.
112 was measured after 104 was asserted and the build rejected it. The pin
asserts the relationship -- both events must be exactly sizeof(EventWaitHandle)
-- as well as the figures.
WaitOne() returns bool rather than void, a widening at every call site. The
initialState parameter loses its default, as .NET has none and it had zero
call sites.
Seven mutations, six caught. M6 (revert Set() to the unlocked form) is NOT
caught and cannot be caught deterministically: ~0.2% per round means a bounded
test would catch it about a third of the time. A first cut carried exactly such
a 200-round case and it was REMOVED rather than kept, on the reasoning
#1957/SR-AUD-201 and #2031 recorded. A multi-waiter amplification was tried and
is invalid -- it reports 100% "loss" for the locked form too, because repeated
Set() calls on an AutoReset event coalesce into one signal.
Downstream: zero AutoResetEvent/ManualResetEvent sites in both consumers; all
14 hits are EventWaitHandle and need a rebuild, not an edit. cna builds against
the sibling checkout on develop, so both repairs reach it at the merge.
Gate: 17,594 run / 17,594 passed / 0 failed / 0 skipped across 38 executables,
recounted from the per-executable logs (+4, Threading 523 -> 527).
Build: build/ only, --parallel 2 throughout.1 parent ea74a4b commit 1cd7425
7 files changed
Lines changed: 312 additions & 181 deletions
File tree
- docs
- modules/threading
- include/System/Threading
- tests/System/Threading
Large diffs are not rendered by default.
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
| 68 | + | |
| 69 | + | |
| 70 | + | |
| 71 | + | |
| 72 | + | |
| 73 | + | |
| 74 | + | |
| 75 | + | |
| 76 | + | |
| 77 | + | |
| 78 | + | |
| 79 | + | |
| 80 | + | |
| 81 | + | |
| 82 | + | |
| 83 | + | |
| 84 | + | |
| 85 | + | |
| 86 | + | |
| 87 | + | |
| 88 | + | |
| 89 | + | |
| 90 | + | |
| 91 | + | |
| 92 | + | |
| 93 | + | |
| 94 | + | |
| 95 | + | |
| 96 | + | |
| 97 | + | |
| 98 | + | |
| 99 | + | |
| 100 | + | |
| 101 | + | |
Lines changed: 27 additions & 91 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
2 | 2 | | |
3 | 3 | | |
4 | 4 | | |
5 | | - | |
6 | | - | |
7 | | - | |
8 | 5 | | |
9 | | - | |
10 | | - | |
11 | | - | |
| 6 | + | |
| 7 | + | |
12 | 8 | | |
13 | 9 | | |
14 | 10 | | |
15 | | - | |
16 | | - | |
17 | 11 | | |
18 | | - | |
19 | | - | |
20 | | - | |
21 | | - | |
22 | | - | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
23 | 30 | | |
24 | | - | |
25 | | - | |
26 | | - | |
27 | | - | |
28 | | - | |
29 | | - | |
30 | | - | |
31 | | - | |
32 | | - | |
33 | | - | |
34 | | - | |
35 | | - | |
36 | | - | |
37 | | - | |
38 | | - | |
39 | | - | |
40 | | - | |
41 | | - | |
42 | | - | |
43 | | - | |
| 31 | + | |
44 | 32 | | |
45 | | - | |
46 | | - | |
47 | | - | |
48 | | - | |
49 | | - | |
50 | | - | |
51 | | - | |
52 | | - | |
53 | | - | |
54 | | - | |
55 | | - | |
56 | | - | |
57 | | - | |
58 | | - | |
59 | | - | |
60 | | - | |
61 | | - | |
62 | | - | |
63 | | - | |
64 | | - | |
65 | | - | |
66 | | - | |
67 | | - | |
68 | | - | |
69 | | - | |
70 | | - | |
71 | | - | |
72 | | - | |
73 | | - | |
74 | | - | |
75 | | - | |
76 | | - | |
77 | | - | |
78 | | - | |
79 | | - | |
80 | | - | |
81 | | - | |
82 | | - | |
83 | | - | |
84 | | - | |
85 | | - | |
86 | | - | |
87 | | - | |
88 | | - | |
89 | | - | |
90 | | - | |
91 | | - | |
92 | | - | |
93 | | - | |
94 | | - | |
95 | | - | |
96 | | - | |
97 | | - | |
98 | | - | |
99 | 33 | | |
100 | | - | |
101 | | - | |
| 34 | + | |
102 | 35 | | |
103 | | - | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
104 | 39 | | |
105 | | - | |
| 40 | + | |
| 41 | + | |
106 | 42 | | |
107 | 43 | | |
108 | 44 | | |
Lines changed: 48 additions & 4 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
7 | 7 | | |
8 | 8 | | |
9 | 9 | | |
| 10 | + | |
10 | 11 | | |
11 | 12 | | |
12 | 13 | | |
| |||
20 | 21 | | |
21 | 22 | | |
22 | 23 | | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
23 | 36 | | |
24 | 37 | | |
25 | 38 | | |
| |||
56 | 69 | | |
57 | 70 | | |
58 | 71 | | |
59 | | - | |
| 72 | + | |
| 73 | + | |
| 74 | + | |
| 75 | + | |
| 76 | + | |
| 77 | + | |
| 78 | + | |
| 79 | + | |
| 80 | + | |
| 81 | + | |
| 82 | + | |
| 83 | + | |
60 | 84 | | |
61 | | - | |
| 85 | + | |
| 86 | + | |
62 | 87 | | |
63 | 88 | | |
64 | 89 | | |
65 | 90 | | |
66 | 91 | | |
67 | 92 | | |
68 | | - | |
69 | | - | |
| 93 | + | |
| 94 | + | |
| 95 | + | |
| 96 | + | |
| 97 | + | |
| 98 | + | |
| 99 | + | |
| 100 | + | |
| 101 | + | |
| 102 | + | |
| 103 | + | |
| 104 | + | |
| 105 | + | |
| 106 | + | |
| 107 | + | |
| 108 | + | |
| 109 | + | |
| 110 | + | |
| 111 | + | |
70 | 112 | | |
71 | 113 | | |
72 | 114 | | |
| 115 | + | |
73 | 116 | | |
74 | 117 | | |
75 | 118 | | |
| |||
82 | 125 | | |
83 | 126 | | |
84 | 127 | | |
| 128 | + | |
85 | 129 | | |
86 | 130 | | |
87 | 131 | | |
| |||
0 commit comments