Real nREPL interrupt + thread-local *ns* (jolt-amzy, jolt-6rld)
Two nREPL divergences the library shakeout surfaced — both have a real host
mechanism on Chez.
Interrupt (jolt-amzy): Chez's engine timer (set-timer + thread-local
timer-interrupt-handler) is polled at procedure-call / loop back-edges, so a
running computation — even a tight loop — can be aborted from another thread.
concurrency.ss adds jolt.host/{make-interrupt, interrupt!, run-interruptible}: an
interrupt token is a shared box; run-interruptible arms a periodic timer whose
handler escapes (call/cc) when the token is set, throwing {:jolt/interrupted true}.
The eval thread is reused, not abandoned. (A thread blocked in a __collect_safe
foreign call only sees it on return — like the JVM not killing native code.)
Thread-local *ns* (jolt-6rld): chez-current-ns is now a Chez thread-parameter, so
each session worker / future has its own current ns (vars stay global, only the
pointer is per-thread). *ns* reads derive from it (dyn-binding.ss), and a bound
*ns* drives chez-current-ns — so (binding [*ns* the-ns] (load-string code))
resolves against the-ns, and concurrent in-ns across threads don't clobber each
other. Single-threaded behaviour is unchanged. All runtime .ss — no re-mint.
This commit is contained in:
parent
f30a517cf7
commit
c18f8087f0
6 changed files with 79 additions and 8 deletions
|
|
@ -21,9 +21,23 @@
|
|||
;; so they agree with defmulti. Loaded from rt.ss after seq.ss (jolt-invoke),
|
||||
;; collections.ss (jolt=/key-hash/jolt-hash-map) and the var-cell machinery.
|
||||
|
||||
(define chez-current-ns-box (vector "user"))
|
||||
(define (chez-current-ns) (vector-ref chez-current-ns-box 0))
|
||||
(define (set-chez-ns! ns) (vector-set! chez-current-ns-box 0 ns))
|
||||
;; THREAD-LOCAL (jolt-6rld): a Chez thread-parameter, so each OS thread (an nREPL
|
||||
;; session worker / future) has its own current ns — vars stay global, only the
|
||||
;; "current ns" pointer is per-thread, matching Clojure's thread-local *ns*. A new
|
||||
;; thread inherits the forking thread's value. `star-ns-cell` (the *ns* var cell,
|
||||
;; captured by dyn-binding.ss once *ns* exists) lets chez-current-ns DERIVE from a
|
||||
;; thread-local (binding [*ns* ..]) so a bound *ns* drives load-string/analyzer
|
||||
;; resolution; bootstrap-safe (it's #f until then, so we just read the parameter).
|
||||
(define chez-current-ns-param (make-thread-parameter "user"))
|
||||
(define star-ns-cell #f)
|
||||
(define (chez-current-ns)
|
||||
(if star-ns-cell
|
||||
(let ((bv (dyn-binding-value star-ns-cell)))
|
||||
(if (and (not (eq? bv dyn-no-binding)) (jns? bv))
|
||||
(jns-name bv)
|
||||
(chez-current-ns-param)))
|
||||
(chez-current-ns-param)))
|
||||
(define (set-chez-ns! ns) (chez-current-ns-param ns))
|
||||
|
||||
(define-record-type jolt-multifn
|
||||
(fields name dispatch-fn methods default hierarchy prefers)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue