Skip to content

Commit 76b25bf

Browse files
author
Timothy Baldridge
committed
fixed putret to work on cljs
1 parent 0317520 commit 76b25bf

File tree

6 files changed

+76
-67
lines changed

6 files changed

+76
-67
lines changed

project.clj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
:url "http://www.eclipse.org/legal/epl-v10.html"}
66
:parent [org.clojure/pom.contrib "0.1.2"]
77
:dependencies [[org.clojure/clojure "1.5.1"]
8-
[org.clojure/clojurescript "0.0-2080" :scope "provided"]]
8+
[org.clojure/clojurescript "0.0-2138" :scope "provided"]]
99
:global-vars {*warn-on-reflection* true}
1010
:source-paths ["src/main/clojure"]
1111
:test-paths ["src/test/clojure"]

src/main/clojure/cljs/core/async.cljs

Lines changed: 61 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,8 @@
5757

5858
(defn <!
5959
"takes a val from port. Must be called inside a (go ...) block. Will
60-
return nil if closed. Will park if nothing is available."
60+
return nil if closed. Will park if nothing is available.
61+
Returns true unless port is already closed"
6162
[port]
6263
(assert nil "<! used not in (go ...) block"))
6364

@@ -76,11 +77,13 @@
7677
(dispatch/run #(fn1 val)))))
7778
nil)))
7879

79-
(defn- nop [])
80+
(defn- nop [_])
81+
(def ^:private fhnop (fn-handler nop))
8082

8183
(defn >!
8284
"puts a val into port. nil values are not allowed. Must be called
83-
inside a (go ...) block. Will park if no buffer space is available."
85+
inside a (go ...) block. Will park if no buffer space is available.
86+
Returns true unless port is already closed."
8487
[port val]
8588
(assert nil ">! used not in (go ...) block"))
8689

@@ -89,15 +92,19 @@
8992
complete. nil values are not allowed. Will throw if closed. If
9093
on-caller? (default true) is true, and the put is immediately
9194
accepted, will call fn0 on calling thread. Returns nil."
92-
([port val] (put! port val nop))
93-
([port val fn0] (put! port val fn0 true))
94-
([port val fn0 on-caller?]
95-
(let [ret (impl/put! port val (fn-handler fn0))]
96-
(when (and ret (not= fn0 nop))
95+
([port val]
96+
(if-let [ret (impl/put! port val fhnop)]
97+
@ret
98+
true))
99+
([port val fn1] (put! port val fn1 true))
100+
([port val fn1 on-caller?]
101+
(if-let [retb (impl/put! port val (fn-handler fn1))]
102+
(let [ret @retb]
97103
(if on-caller?
98-
(fn0)
99-
(dispatch/run fn0)))
100-
nil)))
104+
(fn1 ret)
105+
(dispatch/run #(fn1 ret)))
106+
ret)
107+
true)))
101108

102109
(defn close!
103110
([port]
@@ -150,7 +157,7 @@
150157
wport (when (vector? port) (port 0))
151158
vbox (if wport
152159
(let [val (port 1)]
153-
(impl/put! wport val (alt-handler flag #(fret [nil wport]))))
160+
(impl/put! wport val (alt-handler flag #(fret [% wport]))))
154161
(impl/take! port (alt-handler flag #(fret [% port]))))]
155162
(if vbox
156163
(channels/box [@vbox (or wport port)])
@@ -163,16 +170,17 @@
163170

164171
(defn alts!
165172
"Completes at most one of several channel operations. Must be called
166-
inside a (go ...) block. ports is a vector of channel endpoints, which
167-
can be either a channel to take from or a vector of
173+
inside a (go ...) block. ports is a vector of channel endpoints,
174+
which can be either a channel to take from or a vector of
168175
[channel-to-put-to val-to-put], in any combination. Takes will be
169176
made as if by <!, and puts will be made as if by >!. Unless
170177
the :priority option is true, if more than one port operation is
171178
ready a non-deterministic choice will be made. If no operation is
172179
ready and a :default value is supplied, [default-val :default] will
173180
be returned, otherwise alts! will park until the first operation to
174181
become ready completes. Returns [val port] of the completed
175-
operation, where val is the value taken for takes, and nil for puts.
182+
operation, where val is the value taken for takes, and a
183+
boolean (true unless already closed, as per put!) for puts.
176184
177185
opts are passed as :key val ... Supported options:
178186
@@ -197,6 +205,7 @@
197205
(reify
198206
impl/Channel
199207
(close! [_] (impl/close! ch))
208+
(closed? [_] (impl/closed? ch))
200209

201210
impl/ReadPort
202211
(take! [_ fn1]
@@ -214,7 +223,7 @@
214223
ret)))
215224

216225
impl/WritePort
217-
(put! [_ val fn0] (impl/put! ch val fn0))))
226+
(put! [_ val fn1] (impl/put! ch val fn1))))
218227

219228
(defn map>
220229
"Takes a function and a target channel, and returns a channel which
@@ -228,8 +237,8 @@
228237
(take! [_ fn1] (impl/take! ch fn1))
229238

230239
impl/WritePort
231-
(put! [_ val fn0]
232-
(impl/put! ch (f val) fn0))))
240+
(put! [_ val fn1]
241+
(impl/put! ch (f val) fn1))))
233242

234243

235244

@@ -241,15 +250,16 @@
241250
(reify
242251
impl/Channel
243252
(close! [_] (impl/close! ch))
253+
(closed? [_] (impl/closed? ch))
244254

245255
impl/ReadPort
246256
(take! [_ fn1] (impl/take! ch fn1))
247257

248258
impl/WritePort
249-
(put! [_ val fn0]
259+
(put! [_ val fn1]
250260
(if (p val)
251-
(impl/put! ch val fn0)
252-
(channels/box nil)))))
261+
(impl/put! ch val fn1)
262+
(channels/box (not (impl/closed? ch)))))))
253263

254264
(defn remove>
255265
"Takes a predicate and a target channel, and returns a channel which
@@ -290,10 +300,10 @@
290300
(let [val (<! in)]
291301
(if (nil? val)
292302
(close! out)
293-
(let [vals (f val)]
294-
(doseq [v vals]
295-
(>! out v))
296-
(recur))))))
303+
(do (doseq [v (f val)]
304+
(>! out v))
305+
(when-not (impl/closed? out)
306+
(recur)))))))
297307

298308
(defn mapcat<
299309
"Takes a function and a source channel, and returns a channel which
@@ -327,16 +337,17 @@
327337

328338
(defn pipe
329339
"Takes elements from the from channel and supplies them to the to
330-
channel. By default, the to channel will be closed when the
331-
from channel closes, but can be determined by the close?
332-
parameter."
340+
channel. By default, the to channel will be closed when the from
341+
channel closes, but can be determined by the close? parameter. Will
342+
stop consuming the from channel if the to channel closes"
343+
333344
([from to] (pipe from to true))
334345
([from to close?]
335346
(go-loop []
336347
(let [v (<! from)]
337348
(if (nil? v)
338349
(when close? (close! to))
339-
(do (>! to v)
350+
(when (>! to v)
340351
(recur)))))
341352
to))
342353

@@ -354,11 +365,11 @@
354365
(let [tc (chan t-buf-or-n)
355366
fc (chan f-buf-or-n)]
356367
(go-loop []
357-
(let [v (<! ch)]
358-
(if (nil? v)
359-
(do (close! tc) (close! fc))
360-
(do (>! (if (p v) tc fc) v)
361-
(recur)))))
368+
(let [v (<! ch)]
369+
(if (nil? v)
370+
(do (close! tc) (close! fc))
371+
(when (>! (if (p v) tc fc) v)
372+
(recur)))))
362373
[tc fc])))
363374

364375
(defn reduce
@@ -385,11 +396,10 @@
385396
([ch coll] (onto-chan ch coll true))
386397
([ch coll close?]
387398
(go-loop [vs (seq coll)]
388-
(if vs
389-
(do (>! ch (first vs))
390-
(recur (next vs)))
391-
(when close?
392-
(close! ch))))))
399+
(if (and vs (>! ch (first vs)))
400+
(recur (next vs))
401+
(when close?
402+
(close! ch))))))
393403

394404

395405
(defn to-chan
@@ -420,7 +430,7 @@
420430
421431
Items received when there are no taps get dropped.
422432
423-
If a tap put throws an exception, it will be removed from the mult."
433+
If a tap puts to a closed channel, it will be removed from the mult."
424434
[ch]
425435
(let [cs (atom {}) ;;ch->close?
426436
m (reify
@@ -433,8 +443,8 @@
433443
(untap-all* [_] (reset! cs {}) nil))
434444
dchan (chan 1)
435445
dctr (atom nil)
436-
done #(when (zero? (swap! dctr dec))
437-
(put! dchan true))]
446+
done (fn [_] (when (zero? (swap! dctr dec))
447+
(put! dchan true)))]
438448
(go-loop []
439449
(let [val (<! ch)]
440450
(if (nil? val)
@@ -443,11 +453,9 @@
443453
(let [chs (keys @cs)]
444454
(reset! dctr (count chs))
445455
(doseq [c chs]
446-
(try
447-
(put! c val done)
448-
(catch js/Object e
449-
(swap! dctr dec)
450-
(untap* m c))))
456+
(when-not (put! c val done)
457+
(swap! dctr dec)
458+
(untap* m c)))
451459
;;wait for all
452460
(when (seq chs)
453461
(<! dchan))
@@ -541,9 +549,10 @@
541549
(do (when (nil? v)
542550
(swap! cs dissoc c))
543551
(recur (calc-state)))
544-
(do (when (or (solos c)
545-
(and (empty? solos) (not (mutes c))))
546-
(>! out v))
552+
(if (or (solos c)
553+
(and (empty? solos) (not (mutes c))))
554+
(when (>! out v)
555+
(recur state))
547556
(recur state)))))
548557
m))
549558

@@ -634,11 +643,8 @@
634643
(close! (muxch* m)))
635644
(let [topic (topic-fn val)
636645
m (get @mults topic)]
637-
(when m
638-
(try
639-
(>! (muxch* m) val)
640-
(catch js/Object e
641-
(swap! mults dissoc topic))))
646+
(when-not (>! (muxch* m) val)
647+
(swap! mults dissoc topic))
642648
(recur)))))
643649
p)))
644650

src/main/clojure/cljs/core/async/impl/channels.cljs

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -32,22 +32,22 @@
3232
(let [^boolean closed closed]
3333
(if (or closed
3434
(not ^boolean (impl/active? handler)))
35-
(box nil)
35+
(box (not closed))
3636
(loop []
3737
(let [^not-native taker (.pop takes)]
3838
(if-not (nil? taker)
3939
(if ^boolean (impl/active? taker)
4040
(let [take-cb (impl/commit taker)
4141
_ (impl/commit handler)]
4242
(dispatch/run (fn [] (take-cb val)))
43-
(box nil))
43+
(box true))
4444
(recur))
4545

4646
(if (not (or (nil? buf)
4747
^boolean (impl/full? buf)))
4848
(let [_ (impl/commit handler)]
4949
(do (impl/add! buf val)
50-
(box nil)))
50+
(box true)))
5151
(do
5252
(if (> dirty-puts MAX_DIRTY)
5353
(do (set! dirty-puts 0)
@@ -75,7 +75,7 @@
7575
(if ^boolean (impl/active? put-handler)
7676
(let [put-cb (impl/commit put-handler)
7777
_ (impl/commit handler)]
78-
(dispatch/run put-cb)
78+
(dispatch/run #(put-cb true))
7979
(box val))
8080
(recur)))
8181
(if ^boolean closed
@@ -94,6 +94,7 @@
9494
nil))))))))
9595

9696
impl/Channel
97+
(closed? [_] closed)
9798
(close! [this]
9899
(if ^boolean closed
99100
nil
@@ -108,4 +109,4 @@
108109
nil))))
109110

110111
(defn chan [buf]
111-
(ManyToManyChannel. (buffers/ring-buffer 32) 0 (buffers/ring-buffer 32) 0 buf nil))
112+
(ManyToManyChannel. (buffers/ring-buffer 32) 0 (buffers/ring-buffer 32) 0 buf false))

src/main/clojure/cljs/core/async/impl/ioc_helpers.cljs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,8 +50,8 @@
5050
nil))
5151

5252
(defn put! [state blk ^not-native c val]
53-
(if-let [cb (impl/put! c val (fn-handler (fn []
54-
(ioc/aset-all! state VALUE-IDX nil STATE-IDX blk)
53+
(if-let [cb (impl/put! c val (fn-handler (fn [ret-val]
54+
(ioc/aset-all! state VALUE-IDX ret-val STATE-IDX blk)
5555
(run-state-machine-wrapped state))))]
5656
(do (ioc/aset-all! state VALUE-IDX @cb STATE-IDX blk)
5757
:recur)

src/main/clojure/cljs/core/async/impl/protocols.cljs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,12 @@
1414
(take! [port fn1-handler] "derefable val if taken, nil if take was enqueued"))
1515

1616
(defprotocol WritePort
17-
(put! [port val fn0-handler] "derefable nil if put, nil if put was enqueued. Must throw on nil val."))
17+
(put! [port val fn1-handler] "derefable boolean (false if already closed) if handled, nil if put was enqueued.
18+
Must throw on nil val."))
1819

1920
(defprotocol Channel
20-
(close! [chan]))
21+
(close! [chan])
22+
(closed? [chan]))
2123

2224
(defprotocol Handler
2325
(active? [h] "returns true if has callback. Must work w/o lock")

src/test/cljs/cljs/core/async/tests.cljs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,11 @@
88
[cljs.core.async.macros :as m :refer [go alt!]]))
99

1010
(let [c (chan 1)]
11-
(put! c 42 #(is true) true)
11+
(put! c 42 (fn [_] (is true)) true)
1212
(take! c #(is (= 42 %)) true))
1313

1414
(let [c (chan)]
15-
(put! c 42 #(is true) true)
15+
(put! c 42 (fn [_] (is true)) true)
1616
(take! c #(is (= 42 %)) true))
1717

1818
(defn identity-chan

0 commit comments

Comments
 (0)