-
Notifications
You must be signed in to change notification settings - Fork 116
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Port net/json-rpc from clan to std (#826)
Adds support for JSON-RPC to the stdlib, both client and server side. Fixes #815 - [x] Code - [x] Tests - [ ] Docs --------- Co-authored-by: vyzo <[email protected]>
- Loading branch information
Showing
24 changed files
with
1,062 additions
and
129 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
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 |
---|---|---|
|
@@ -4,6 +4,7 @@ gambit-source | |
attic | ||
bin | ||
lib | ||
/build | ||
*.o | ||
*.o? | ||
*.so | ||
|
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
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,118 @@ | ||
;;; -*- Gerbil -*- | ||
;;; © fare, vyzo | ||
;;; Atoms in the style of clojure: shared, synchronous, independent state | ||
|
||
;; NB: Compared to the Clojure atom API, we: | ||
;; - Do not support the meta field and the functions alter-meta! reset-meta! | ||
;; - Replace swap-vals! and reset-vals! by swap-values! and reset-values! | ||
;; returning values rather than vectors. | ||
;; - Rename add-watch and remove-watch to add-watch! and remove-watch! | ||
;; - Do not have generic functions that work on multiple kinds of "references" | ||
;; but only one set of functions for atoms. | ||
;; - Also export atom-increment! and atomic-counter for the common case. | ||
|
||
(import :gerbil/gambit/threads | ||
:std/sugar) | ||
|
||
(export atom | ||
(rename: Atom-value atom-deref) | ||
(rename: swap! atom-swap!) | ||
(rename: swap-values! atom-swap-values!) | ||
(rename: reset! atom-reset!) | ||
(rename: reset-values! atom-reset-values!) | ||
(rename: compare-and-set! atom-compare-and-set!) | ||
(rename: Atom-validator atom-validator) | ||
(rename: Atom-validator-set! atom-validator-set!) | ||
(rename: add-watch! atom-add-watch!) | ||
(rename: remove-watch! atom-remove-watch!) | ||
atom-increment! atomic-counter) | ||
|
||
(defstruct Atom | ||
(mutex value validator watchers) | ||
final: #t unchecked: #t) | ||
|
||
(def (atom (initial-value (void)) validator: (validator #f)) | ||
(Atom (make-mutex 'atom) initial-value validator (hash))) | ||
|
||
(defalias &deref &Atom-value) | ||
|
||
;; Internal helper to ensure atomicity | ||
(defrule (with-atom-lock a body ...) | ||
(with-lock (Atom-mutex a) (lambda () body ...))) | ||
|
||
;; Internal helper to be called inside with-atom-lock | ||
(def (update-atom! a new-val (values? #t)) | ||
(with ((Atom _ old-val validator watchers) a) | ||
(when validator | ||
(unless (validator new-val) | ||
(error "invalid atom value" new-val))) | ||
(set! (&Atom-value a) new-val) | ||
(hash-for-each (lambda (key watch) (watch key a old-val new-val)) watchers) | ||
(if values? | ||
(values old-val new-val) | ||
new-val))) | ||
|
||
;; analog to Clojure swap-values!, but returning (values old-val new-val) rather than [old-val new-val] | ||
(def* swap-values! | ||
((a f) | ||
(with-atom-lock a (update-atom! a (f (&deref a))))) | ||
((a f val) | ||
(with-atom-lock a (update-atom! a (f (&deref a) val)))) | ||
((a f val . rest) | ||
(with-atom-lock a (update-atom! a (apply f (&deref a) val rest))))) | ||
|
||
(def* swap-value! | ||
((a f) | ||
(with-atom-lock a (update-atom! a (f (&deref a)) #f))) | ||
((a f val) | ||
(with-atom-lock a (update-atom! a (f (&deref a) val) #f))) | ||
((a f val . rest) | ||
(with-atom-lock a (update-atom! a (apply f (&deref a) val rest) #f)))) | ||
|
||
;; same as Clojure swap! | ||
(def* swap! | ||
((a f) | ||
(swap-value! a f)) | ||
((a f val) | ||
(swap-value! a f val)) | ||
((a f val . rest) | ||
(apply swap-value! a f rest))) | ||
|
||
;; analog to Clojure reset-values!, but returning (values old-val new-val) rather than [old-val new-val] | ||
(def (reset-values! a new-val) | ||
(with-atom-lock a (update-atom! a new-val))) | ||
|
||
;; same as Clojure reset! | ||
(def (reset! a new-val) | ||
(with-atom-lock a (update-atom! a new-val #f))) | ||
|
||
;; same as Clojure compare-and-set! | ||
(def (compare-and-set! a old-val new-val) | ||
(with-atom-lock a | ||
(and (eq? (&deref a) old-val) | ||
(update-atom! a new-val #f) | ||
#t))) | ||
|
||
;; same as Clojure add-watch | ||
(def (add-watch! a key fn) | ||
(with-atom-lock a | ||
(hash-put! (&Atom-watchers a) key fn))) | ||
|
||
;; same as Clojure remove-watch | ||
(def (remove-watch! a key) | ||
(with-atom-lock a | ||
(hash-remove! (&Atom-watchers a) key))) | ||
|
||
(def (atom-increment! atom (increment 1)) | ||
(swap! atom + increment)) | ||
|
||
(def (atomic-counter (initial-value -1)) | ||
(let (a (atom initial-value)) | ||
(lambda () | ||
(let (mx (&Atom-mutex a)) | ||
(mutex-lock! mx) | ||
(let (new (1+ (&Atom-value a))) | ||
(set! (&Atom-value a) | ||
new) | ||
(mutex-unlock! mx) | ||
new))))) |
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
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
Oops, something went wrong.