aboutsummaryrefslogtreecommitdiff
path: root/guile/starlet/state.scm
diff options
context:
space:
mode:
Diffstat (limited to 'guile/starlet/state.scm')
-rw-r--r--guile/starlet/state.scm20
1 files changed, 19 insertions, 1 deletions
diff --git a/guile/starlet/state.scm b/guile/starlet/state.scm
index 13888e8..a889d0c 100644
--- a/guile/starlet/state.scm
+++ b/guile/starlet/state.scm
@@ -48,7 +48,8 @@
blackout
sel
selection-hook
- value->number))
+ value->number
+ atomically-overlay-state!))
;; A "state" is an atomically-updating container for an immutable
@@ -231,6 +232,23 @@ pre-existing contents."
(state-for-each at state))
+(define (atomically-overlay-state! state newbits)
+ "Apply 'newbits' within 'state', as a single atomic operation."
+ (let* ((old-ht (atomic-box-ref (get-ht-box state)))
+ (new-ht (copy-hash-table old-ht)))
+ (state-for-each (lambda (fix attr val)
+ (hash-set! new-ht
+ (cons fix attr)
+ val))
+ newbits)
+ (unless (eq? (atomic-box-compare-and-swap!
+ (get-ht-box state)
+ old-ht
+ new-ht)
+ old-ht)
+ (atomically-overlay-state! state newbits)))) ;; Try again
+
+
(define current-state (make-parameter programmer-state))