summaryrefslogtreecommitdiff
path: root/libguile/modules.c
diff options
context:
space:
mode:
authorLudovic Courtès <ludo@gnu.org>2018-06-18 17:39:35 +0200
committerAndy Wingo <wingo@pobox.com>2018-08-07 12:10:05 +0200
commitedc80bd595a442d059098fd6b605bbe1aa7e81ca (patch)
tree0c2f293482c218c0f441b0fa3187b3b28a50a1cd /libguile/modules.c
parentf075641051e638cfb7493b695ace4e9f5f600c1c (diff)
downloadguile-edc80bd595a442d059098fd6b605bbe1aa7e81ca.tar.gz
Module import obarrays are accessed in a critical section.
Fixes <https://bugs.gnu.org/31879>. * libguile/modules.c (import_obarray_mutex): New variable. (resolve_duplicate_binding, module_imported_variable): Acquire it before accessing an obarray.
Diffstat (limited to 'libguile/modules.c')
-rw-r--r--libguile/modules.c17
1 files changed, 17 insertions, 0 deletions
diff --git a/libguile/modules.c b/libguile/modules.c
index 751d9070c..b0327fced 100644
--- a/libguile/modules.c
+++ b/libguile/modules.c
@@ -275,6 +275,13 @@ default_duplicate_binding_handlers (void)
return (scm_call_0 (get_handlers));
}
+/* Each module has an "import obarray" that may be accessed concurrently
+ by several threads. This mutex protects access to any obarray. This
+ is coarse-grain but (1) pthread mutexes are quite cheap, and (2)
+ Scheme "programs" have a cache for free variables anyway. */
+static scm_i_pthread_mutex_t import_obarray_mutex =
+ SCM_I_PTHREAD_MUTEX_INITIALIZER;
+
/* Resolve the import of SYM in MODULE, where SYM is currently provided by
both IFACE1 as VAR1 and IFACE2 as VAR2. Return the variable chosen by the
duplicate binding handlers or `#f'. */
@@ -300,7 +307,11 @@ resolve_duplicate_binding (SCM module, SCM sym,
args[5] = SCM_VARIABLE_REF (var2);
if (SCM_UNBNDP (args[5]))
args[5] = SCM_BOOL_F;
+
+ scm_i_pthread_mutex_lock (&import_obarray_mutex);
args[6] = scm_hashq_ref (SCM_MODULE_IMPORT_OBARRAY (module), sym, SCM_BOOL_F);
+ scm_i_pthread_mutex_unlock (&import_obarray_mutex);
+
args[7] = SCM_BOOL_F;
handlers = SCM_MODULE_DUPLICATE_HANDLERS (module);
@@ -338,7 +349,11 @@ module_imported_variable (SCM module, SCM sym)
/* Search cached imported bindings. */
imports = SCM_MODULE_IMPORT_OBARRAY (module);
+
+ scm_i_pthread_mutex_lock (&import_obarray_mutex);
var = scm_hashq_ref (imports, sym, SCM_UNDEFINED);
+ scm_i_pthread_mutex_unlock (&import_obarray_mutex);
+
if (SCM_BOUND_THING_P (var))
return var;
@@ -386,7 +401,9 @@ module_imported_variable (SCM module, SCM sym)
if (SCM_BOUND_THING_P (found_var))
{
/* Save the lookup result for future reference. */
+ scm_i_pthread_mutex_lock (&import_obarray_mutex);
(void) scm_hashq_set_x (imports, sym, found_var);
+ scm_i_pthread_mutex_unlock (&import_obarray_mutex);
return found_var;
}
}