aboutsummaryrefslogtreecommitdiff
path: root/guix/monads.scm
diff options
context:
space:
mode:
authorLudovic Courtès <ludo@gnu.org>2019-02-06 21:58:43 +0100
committerLudovic Courtès <ludo@gnu.org>2019-02-06 23:06:18 +0100
commit8245bb74fc7bdcdc2f9d458057cefc9cd982e489 (patch)
tree9485861a2715bb21173e80a1f4258eea1450326e /guix/monads.scm
parentd59124280851c5d62b6ecf5aa07f6b4f6520a0e5 (diff)
downloadguix-8245bb74fc7bdcdc2f9d458057cefc9cd982e489.tar
guix-8245bb74fc7bdcdc2f9d458057cefc9cd982e489.tar.gz
monads, gexp: Prevent redefinition of syntax parameters.
Fixes <https://bugs.gnu.org/27476>. This fixes multi-threaded compilation of this code where syntax parameters could end up being redefined and where a race condition could lead a thread to see the "wrong" value of the syntax parameter. * guix/monads.scm (define-syntax-parameter-once): New macro. (>>=, return): Use it. * guix/gexp.scm (define-syntax-parameter-once): New macro. (current-imported-modules, current-imported-extensions): Use it.
Diffstat (limited to 'guix/monads.scm')
-rw-r--r--guix/monads.scm15
1 files changed, 13 insertions, 2 deletions
diff --git a/guix/monads.scm b/guix/monads.scm
index 6ae616aca9..6924471345 100644
--- a/guix/monads.scm
+++ b/guix/monads.scm
@@ -274,12 +274,23 @@ more optimizations."
(_
#'generic-name))))))))))
-(define-syntax-parameter >>=
+(define-syntax-rule (define-syntax-parameter-once name proc)
+ ;; Like 'define-syntax-parameter' but ensure the top-level binding for NAME
+ ;; does not get redefined. This works around a race condition in a
+ ;; multi-threaded context with Guile <= 2.2.4: <https://bugs.gnu.org/27476>.
+ (eval-when (load eval expand compile)
+ (define name
+ (if (module-locally-bound? (current-module) 'name)
+ (module-ref (current-module) 'name)
+ (make-syntax-transformer 'name 'syntax-parameter
+ (list proc))))))
+
+(define-syntax-parameter-once >>=
;; The name 'bind' is already taken, so we choose this (obscure) symbol.
(lambda (s)
(syntax-violation '>>= ">>= (bind) used outside of 'with-monad'" s)))
-(define-syntax-parameter return
+(define-syntax-parameter-once return
(lambda (s)
(syntax-violation 'return "return used outside of 'with-monad'" s)))