Skip to content

Commit d6b666c

Browse files
authored
Merge pull request #201 from /issues/200
fix(channel): reset state to EmptyChannelState after unsetting
2 parents 9e07d5a + 8c61da5 commit d6b666c

File tree

2 files changed

+57
-2
lines changed

2 files changed

+57
-2
lines changed

await-generator/src/SOFe/AwaitGenerator/Channel.php

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,15 @@ public function sendAndWait($value) : Generator{
6767
});
6868
} finally {
6969
if($key !== null) {
70-
unset($this->state->queue[spl_object_id($key)]);
70+
if($this->state instanceof SendingChannelState) {
71+
// our key may still exist in the channel state
72+
73+
unset($this->state->queue[spl_object_id($key)]);
74+
if(count($this->state->queue) === 0) {
75+
$this->state = new EmptyChannelState;
76+
}
77+
}
78+
// else, state already changed means our key has been shifted already.
7179
}
7280
}
7381
}
@@ -134,7 +142,15 @@ public function receive() : Generator{
134142
});
135143
} finally {
136144
if($key !== null) {
137-
unset($this->state->queue[spl_object_id($key)]);
145+
if($this->state instanceof ReceivingChannelState) {
146+
// our key may still exist in the channel state
147+
148+
unset($this->state->queue[spl_object_id($key)]);
149+
if(count($this->state->queue) === 0) {
150+
$this->state = new EmptyChannelState;
151+
}
152+
}
153+
// else, state already changed means our key has been shifted already.
138154
}
139155
}
140156
}

tests/SOFe/AwaitGenerator/ChannelTest.php

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -331,4 +331,43 @@ public function testTryReceive() : void{
331331

332332
self::assertSame("a", $receive);
333333
}
334+
335+
public function testTryCancelSender() : void{
336+
$ok = false;
337+
Await::f2c(function() use(&$ok){
338+
/** @var Channel<null> $channel */
339+
$channel = new Channel;
340+
341+
[$which, $_] = yield from Await::safeRace([
342+
$channel->sendAndWait(null),
343+
GeneratorUtil::empty(null),
344+
]);
345+
self::assertSame(1, $which);
346+
347+
$ret = $channel->tryReceiveOr("no sender");
348+
self::assertSame("no sender", $ret);
349+
$ok = true;
350+
});
351+
352+
self::assertTrue($ok, "test run complete");
353+
}
354+
355+
public function testTryCancelReceiver() : void{
356+
$ok = false;
357+
Await::f2c(function() use(&$ok){
358+
/** @var Channel<null> $channel */
359+
$channel = new Channel;
360+
361+
[$which, $_] = yield from Await::safeRace([
362+
$channel->receive(),
363+
GeneratorUtil::empty(null),
364+
]);
365+
self::assertSame(1, $which);
366+
367+
$channel->sendWithoutWait(null);
368+
$ok = true;
369+
});
370+
371+
self::assertTrue($ok, "test run complete");
372+
}
334373
}

0 commit comments

Comments
 (0)