[ASYNC-72] CLJS: mult becomes blocked after putting to a closed channel Created: 15/May/14 Updated: 06/Jun/14
A mult can become blocked after a putting to a closed tap channel due to an off-by-one error in triggering the end condition.
It appears the issue was recently fixed in the Clojure version of mult, but not the ClojureScript version.
The issue occurs because the counter that indicates the mult has finished a putting to all taps, dctr is decremented out of band and the zero? triggering condition in done function is missed.
The done function passed to put! appears to be called regardless of whether the channel is closed. Because of this, we don't need to (swap! dctr dec) or necessarily call (done nil) (the CLJ fix) to fix this issue.
|Comment by Gijs Stuurman [ 06/Jun/14 11:03 AM ]|
The title of this issue says it's CLJS only, but the double done/counter-decrement applies to the CLJ version as well. As is briefly mentioned at the end of this issue.
For closed channels the done function is called twice in mult, because put! returns false for closed channels and calls the callback:
In the CLJ version this will not lead to blocking but it violates the behavior in the docstring of "each tap must accept before the next item is distributed" when a tap is closed.