Skip to content

Commit 456742e

Browse files
committed
Fix peekVar draining
1 parent 3cc2fa7 commit 456742e

File tree

2 files changed

+49
-19
lines changed

2 files changed

+49
-19
lines changed

src/Control/Monad/Aff/Internal.js

Lines changed: 34 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ exports._takeVar = function (nonCanceler, avar) {
2525

2626
producer(success, error);
2727
} else {
28-
avar.consumers.push({ success: success, error: error });
28+
avar.consumers.push({ peek: false, success: success, error: error });
2929
}
3030

3131
return nonCanceler;
@@ -50,28 +50,43 @@ exports._putVar = function (nonCanceler, avar, a) {
5050
return function (success, error) {
5151
if (avar.error !== undefined) {
5252
error(avar.error);
53-
} else if (avar.consumers.length === 0) {
54-
avar.producers.push(function (success, error) {
55-
try {
56-
success(a);
57-
} catch (err) {
58-
error(err);
59-
}
60-
});
61-
62-
success({});
6353
} else {
64-
54+
var shouldQueue = true;
55+
var consumers = [];
6556
var consumer;
66-
do {
57+
58+
while (true) {
6759
consumer = avar.consumers.shift();
68-
try {
69-
consumer.success(a);
70-
} catch (err) {
71-
error(err);
72-
return;
60+
if (consumer) {
61+
consumers.push(consumer);
62+
if (consumer.peek) {
63+
continue;
64+
} else {
65+
shouldQueue = false;
66+
}
67+
}
68+
break;
69+
}
70+
71+
if (shouldQueue) {
72+
avar.producers.push(function (success, error) {
73+
try {
74+
success(a);
75+
} catch (err) {
76+
error(err);
77+
}
78+
});
79+
}
80+
81+
if (consumers.length) {
82+
for (var i = 0; i < consumers.length; i++) {
83+
try {
84+
consumers[i].success(a);
85+
} catch (err) {
86+
consumers[i].error(err);
87+
}
7388
}
74-
} while (consumer.peek === true);
89+
}
7590

7691
success({});
7792
}

test/Test/Main.purs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,21 @@ test_peekVar = do
8484
throwError (error "Something horrible went wrong - peeked var is not true")
8585
log ("Success: Peeked value read from written var")
8686

87+
x <- makeVar
88+
res <- makeVar' 1
89+
forkAff do
90+
c <- peekVar x
91+
putVar x 1000
92+
d <- peekVar x
93+
modifyVar (_ + (c + d)) res
94+
putVar x 10
95+
count <- takeVar res
96+
e <- takeVar x
97+
f <- takeVar x
98+
when (not (count == 21 && e == 10 && f == 1000)) do
99+
throwError (error "Something horrible went wrong - peeked consumers/producer ordering")
100+
log "Success: peekVar consumer/producer order maintained"
101+
87102
test_killFirstForked :: Test Unit
88103
test_killFirstForked = do
89104
c <- forkAff (later' 100 $ pure "Failure: This should have been killed!")

0 commit comments

Comments
 (0)