<< Back to previous view

[ASYNC-72] CLJS: mult becomes blocked after putting to a closed channel Created: 15/May/14  Updated: 14/Oct/14  Resolved: 14/Oct/14

Status: Closed
Project: core.async
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Defect Priority: Major
Reporter: Logan Linn Assignee: Unassigned
Resolution: Completed Votes: 0
Labels: None

Attachments: Text File cljs_mult_dec.patch    
Patch: Code


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.

Demonstration: https://gist.github.com/loganlinn/e840139a9ab5503970fd

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.

Comment by David Nolen [ 14/Oct/14 6:09 AM ]

As far as I can tell the original issue has been fixed in master?

Comment by Logan Linn [ 14/Oct/14 12:02 PM ]

Yeah. It appears https://github.com/clojure/core.async/commit/40ab7edacac747af1108c80223039e8a0b1c2ca9 resolved the issue. Thanks!

Generated at Thu Jan 18 08:34:26 CST 2018 using JIRA 4.4#649-r158309.