From: ludo@gnu.org (Ludovic Courtès)
To: 31878@debbugs.gnu.org, Andy Wingo <wingo@igalia.com>
Subject: bug#31878: Module autoloading is not thread safe
Date: Mon, 18 Jun 2018 13:11:37 +0200 [thread overview]
Message-ID: <878t7cwdqu.fsf@gnu.org> (raw)
In-Reply-To: <87k1qwwhu2.fsf@gnu.org> ("Ludovic \=\?utf-8\?Q\?Court\=C3\=A8s\=22'\?\= \=\?utf-8\?Q\?s\?\= message of "Mon, 18 Jun 2018 11:43:17 +0200")
[-- Attachment #1: Type: text/plain, Size: 274 bytes --]
ludo@gnu.org (Ludovic Courtès) skribis:
> I believe this comes from the fact that ‘autoloads-done’ and related
> alists in (ice-9 boot-9) are manipulated in a non-thread-safe fashion.
Here’s a proposed fix for ‘stable-2.2’ as discussed on #guile, Andy:
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: Type: text/x-patch, Size: 5282 bytes --]
diff --git a/module/ice-9/boot-9.scm b/module/ice-9/boot-9.scm
index 4e51e9281..960cb9fa3 100644
--- a/module/ice-9/boot-9.scm
+++ b/module/ice-9/boot-9.scm
@@ -1,6 +1,6 @@
;;; -*- mode: scheme; coding: utf-8; -*-
-;;;; Copyright (C) 1995-2014, 2016-2017 Free Software Foundation, Inc.
+;;;; Copyright (C) 1995-2014, 2016-2018 Free Software Foundation, Inc.
;;;;
;;;; This library is free software; you can redistribute it and/or
;;;; modify it under the terms of the GNU Lesser General Public
@@ -2952,8 +2952,11 @@ module '(ice-9 q) '(make-q q-length))}."
;;; {Autoloading modules}
;;;
-;;; XXX FIXME autoloads-in-progress and autoloads-done
-;;; are not handled in a thread-safe way.
+(define (call-with-module-autoload-lock thunk)
+ ;; This binding is overridden when (ice-9 threads) is available to
+ ;; implement a critical section around the call to THUNK. It must be
+ ;; used anytime the autoload variables below are used.
+ (thunk))
(define autoloads-in-progress '())
@@ -2973,37 +2976,40 @@ but it fails to load."
file-name-separator-string))
dir-hint-module-name))))
(resolve-module dir-hint-module-name #f)
- (and (not (autoload-done-or-in-progress? dir-hint name))
- (let ((didit #f))
- (dynamic-wind
- (lambda () (autoload-in-progress! dir-hint name))
- (lambda ()
- (with-fluids ((current-reader #f))
- (save-module-excursion
- (lambda ()
- (define (call/ec proc)
- (let ((tag (make-prompt-tag)))
- (call-with-prompt
- tag
- (lambda ()
- (proc (lambda () (abort-to-prompt tag))))
- (lambda (k) (values)))))
- ;; The initial environment when loading a module is a fresh
- ;; user module.
- (set-current-module (make-fresh-user-module))
- ;; Here we could allow some other search strategy (other than
- ;; primitive-load-path), for example using versions encoded
- ;; into the file system -- but then we would have to figure
- ;; out how to locate the compiled file, do auto-compilation,
- ;; etc. Punt for now, and don't use versions when locating
- ;; the file.
- (call/ec
- (lambda (abort)
- (primitive-load-path (in-vicinity dir-hint name)
- abort)
- (set! didit #t)))))))
- (lambda () (set-autoloaded! dir-hint name didit)))
- didit))))
+
+ (call-with-module-autoload-lock
+ (lambda ()
+ (and (not (autoload-done-or-in-progress? dir-hint name))
+ (let ((didit #f))
+ (dynamic-wind
+ (lambda () (autoload-in-progress! dir-hint name))
+ (lambda ()
+ (with-fluids ((current-reader #f))
+ (save-module-excursion
+ (lambda ()
+ (define (call/ec proc)
+ (let ((tag (make-prompt-tag)))
+ (call-with-prompt
+ tag
+ (lambda ()
+ (proc (lambda () (abort-to-prompt tag))))
+ (lambda (k) (values)))))
+ ;; The initial environment when loading a module is a fresh
+ ;; user module.
+ (set-current-module (make-fresh-user-module))
+ ;; Here we could allow some other search strategy (other than
+ ;; primitive-load-path), for example using versions encoded
+ ;; into the file system -- but then we would have to figure
+ ;; out how to locate the compiled file, do auto-compilation,
+ ;; etc. Punt for now, and don't use versions when locating
+ ;; the file.
+ (call/ec
+ (lambda (abort)
+ (primitive-load-path (in-vicinity dir-hint name)
+ abort)
+ (set! didit #t)))))))
+ (lambda () (set-autoloaded! dir-hint name didit)))
+ didit))))))
\f
@@ -4061,6 +4067,19 @@ when none is available, reading FILE-NAME with READER."
;; Load (ice-9 threads), initializing some internal data structures.
(resolve-interface '(ice-9 threads))
+(set! call-with-module-autoload-lock
+ (let* ((threads (resolve-module '(ice-9 threads)))
+ (mutex ((module-ref threads 'make-mutex) 'recursive))
+ (lock (module-ref threads 'lock-mutex))
+ (unlock (module-ref threads 'unlock-mutex)))
+ (lambda (thunk)
+ (dynamic-wind
+ (lambda ()
+ (lock mutex))
+ thunk
+ (lambda ()
+ (unlock mutex))))))
+
\f
;;; SRFI-4 in the default environment. FIXME: we should figure out how
[-- Attachment #3: Type: text/plain, Size: 44 bytes --]
How does that look?
Thanks,
Ludo’.
next prev parent reply other threads:[~2018-06-18 11:11 UTC|newest]
Thread overview: 12+ messages / expand[flat|nested] mbox.gz Atom feed top
2018-06-18 9:43 bug#31878: Module autoloading is not thread safe Ludovic Courtès
2018-06-18 11:11 ` Ludovic Courtès [this message]
2018-06-18 12:17 ` Ludovic Courtès
2018-08-22 23:22 ` Mark H Weaver
2018-08-23 2:18 ` Mark H Weaver
2018-08-23 13:54 ` Ludovic Courtès
2018-08-23 19:40 ` Mark H Weaver
2018-08-24 8:45 ` Ludovic Courtès
2018-10-21 18:16 ` Mark H Weaver
2018-10-22 10:10 ` Ludovic Courtès
[not found] ` <876002dm18.fsf@netris.org>
2018-08-23 13:51 ` Ludovic Courtès
2022-04-04 11:47 ` Calvin Heim
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
List information: https://www.gnu.org/software/guile/
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=878t7cwdqu.fsf@gnu.org \
--to=ludo@gnu.org \
--cc=31878@debbugs.gnu.org \
--cc=wingo@igalia.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).