-
Notifications
You must be signed in to change notification settings - Fork 8
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
lib: move chan.cora out from cml.cora
CML is a general protocol, while the concept like channel implements on top of it. Later we can add net / io also on top it. So it's better to have separate libs
- Loading branch information
1 parent
ea4e7f1
commit 89bd384
Showing
3 changed files
with
72 additions
and
62 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
(@import "cora/lib/cml" cml) | ||
(@import "cora/lib/queue" queue) | ||
|
||
;; channel is a sendq and recvq | ||
;; sendq represent the coroutines blocked sending msg to the channel. | ||
;; recvq represent the coroutines blocked recving msg from the channel. | ||
(defun .make () | ||
[(queue.make) (queue.make)]) | ||
|
||
(func .recv-try | ||
[sendq recvq] => (if (queue.empty? sendq) | ||
false | ||
(match (queue.dequeue sendq) | ||
[state resume val wrap] | ||
(if (= 'Done (value state)) | ||
(.recv-try [sendq recvq]) ;; ignore stale item and continue | ||
(begin | ||
(cml.spawn (lambda () (resume (wrap ())))) | ||
(set state 'Done) | ||
val))))) | ||
|
||
(defun .recv-block (recvq k wrap) | ||
(let state (gensym 'state) | ||
(begin | ||
(set state 'Wait) | ||
(queue.enqueue recvq [state k wrap])))) | ||
|
||
;; recv on channel is an operation | ||
(defun .recv (ch) | ||
(let try (lambda () (.recv-try ch)) | ||
block (lambda (k wrap) (.recv-block (cadr ch) k wrap)) | ||
[try block default-wrap])) | ||
|
||
(func .send-try | ||
[sendq recvq] val => (if (queue.empty? recvq) | ||
false | ||
(match (queue.dequeue recvq) | ||
[state resume wrap] | ||
(if (= 'Done (value state)) | ||
(.send-try [sendq recvq]) ;; ignore stale | ||
(begin | ||
(cml.spawn (lambda () | ||
(begin | ||
;; (io.display "resume recv op\n") | ||
(resume (wrap val))))) | ||
(set state 'Done) | ||
()))))) | ||
|
||
(defun .send-block (sendq k val wrap) | ||
(let state (gensym 'state) | ||
(begin | ||
(set state 'Wait) | ||
(queue.enqueue sendq [state k val wrap])))) | ||
|
||
;; send on channel is an operation | ||
(defun .send (ch val) | ||
(let try (lambda () (.send-try ch val)) | ||
block (lambda (k wrap) (.send-block (car ch) k val wrap)) | ||
[try block default-wrap])) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters