Welcome! Please see the About page for a little more info on how this works.

0 votes
in core.async by

Closing a tap without a pending item is OK but closing a tap with a pending item blocks the mult input channel:

(require '[clojure.core.async :refer :all]) (def c (chan)) (def m (mult c)) (def t (chan)) (tap m t) (>!! c :a) (close! t) (>!! c :b) ; BLOCKS

3 Answers

0 votes

Comment made by: klauswuestefeld

A more general case:

Doing this:

(go (println (>! c 42)))

and then closing c will cause the >! to block, instead of returning false.

If c is closed before that, >! will return false.

Is this race condition the intended behavior?

0 votes

Comment made by: andrewhr

As far as I could understand, the close! implementation follows all takes and run their respective callbacks for releasing.

The approach I follow was doing the same for puts, so we guarantee previously parked put will be release - like demonstrated by the general case of this error.

In the same patch, I added a single test to assert this behavior and ported the same code to ClojureScript implementation. I could split both impls on different patches, but I judged having everything together will ease the screening.

0 votes
Reference: https://clojure.atlassian.net/browse/ASYNC-125 (reported by alex+import)