diff --git a/guix/monads.scm b/guix/monads.scm index 6ae616aca..c9c5da3bb 100644 --- a/guix/monads.scm +++ b/guix/monads.scm @@ -20,6 +20,7 @@ #:use-module ((system syntax) #:select (syntax-local-binding)) #:use-module (ice-9 match) + #:use-module (ice-9 threads) #:use-module (srfi srfi-1) #:use-module (srfi srfi-9) #:use-module (srfi srfi-26) @@ -117,6 +118,7 @@ ;; the syntax object of the parameter over which it is templated, and (2) ;; the syntax of its body. (define-once %templates (make-hash-table)) + (define-once %template-lock (make-mutex)) (define (register-template! name param body) (hash-set! %templates name (cons param body))) @@ -139,8 +141,9 @@ template instances." (syntax-source s)) (define current-info-port - ;; Port for debugging info. - (const (%make-void-port "w"))) + ;; Port for debugging info. Return a fresh port at each call to make + ;; sure we're thread-safe. + (lambda () (%make-void-port "w"))) (define location-string (format #f "~a:~a:~a" @@ -204,12 +207,14 @@ template instances." ;; Search for an instance of template NAME for this ACTUAL parameter. ;; On success, expand to the identifier of the instance; otherwise ;; expand to #f. - (any (matching-instance? #'name #'actual) %template-instances)) + (with-mutex %template-lock + (any (matching-instance? #'name #'actual) %template-instances))) ((_ exists? name actual) ;; Likewise, but return a Boolean. (let ((result (->bool - (any (matching-instance? #'name #'actual) - %template-instances)))) + (with-mutex %template-lock + (any (matching-instance? #'name #'actual) + %template-instances))))) (unless result (format (current-warning-port) "~a: warning: no specialization of template '~a' for '~a'~%" @@ -220,8 +225,9 @@ template instances." ;; Expand to the definitions of all the existing templates ;; specialized for ACTUAL. #`(begin - #,@(hash-map->list (cut instance-definition <> <> #'actual) - %templates)))))) + #,@(with-mutex %template-lock + (hash-map->list (cut instance-definition <> <> #'actual) + %templates))))))) (define-syntax define-template (lambda (s)