[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PATCH] Fix thread-unsafe lazy initializations
From: |
Mark H Weaver |
Subject: |
[PATCH] Fix thread-unsafe lazy initializations |
Date: |
Thu, 28 Feb 2013 18:20:40 -0500 |
User-agent: |
Gnus/5.13 (Gnus v5.13) Emacs/24.2 (gnu/linux) |
Here's my proposed patch to fix these problems.
What do you think?
Mark
>From dadcb1512569c1be039fc75f0a2967e370939e42 Mon Sep 17 00:00:00 2001
From: Mark H Weaver <address@hidden>
Date: Thu, 28 Feb 2013 17:56:58 -0500
Subject: [PATCH] Fix thread-unsafe lazy initializations.
* libguile/debug.c (scm_local_eval):
libguile/ports.c (scm_current_warning_port):
libguile/strports.c (scm_eval_string_in_module): Perform
lazy-initialization while holding a mutex. Use SCM_UNDEFINED as the
uninitialized value. Use 'scm_c_*_variable'.
* doc/ref/api-modules.texi (Accessing Modules from C): Fix
'my_eval_string' example to be thread-safe.
---
doc/ref/api-modules.texi | 13 +++++++------
libguile/debug.c | 8 ++++++--
libguile/ports.c | 12 ++++++++----
libguile/strports.c | 9 ++++++---
4 files changed, 27 insertions(+), 15 deletions(-)
diff --git a/doc/ref/api-modules.texi b/doc/ref/api-modules.texi
index 17ab462..3d111c4 100644
--- a/doc/ref/api-modules.texi
+++ b/doc/ref/api-modules.texi
@@ -942,14 +942,15 @@ the @var{name} is not bound in the module, signals an
error. Returns a
variable, always.
@example
-SCM my_eval_string (SCM str)
address@hidden
- static SCM eval_string_var = SCM_BOOL_F;
+static SCM eval_string_var;
- if (scm_is_false (eval_string_var))
- eval_string_var =
- scm_c_public_lookup ("ice-9 eval-string", "eval-string");
+void my_init (void)
address@hidden
+ eval_string_var = scm_c_public_lookup ("ice-9 eval-string", "eval-string");
address@hidden
+SCM my_eval_string (SCM str)
address@hidden
return scm_call_1 (scm_variable_ref (eval_string_var), str);
@}
@end example
diff --git a/libguile/debug.c b/libguile/debug.c
index b1a90d8..9e6328b 100644
--- a/libguile/debug.c
+++ b/libguile/debug.c
@@ -211,10 +211,14 @@ SCM_DEFINE (scm_debug_hang, "debug-hang", 0, 1, 0,
SCM
scm_local_eval (SCM exp, SCM env)
{
- static SCM local_eval_var = SCM_BOOL_F;
+ static SCM local_eval_var = SCM_UNDEFINED;
+ static scm_i_pthread_mutex_t local_eval_var_mutex
+ = SCM_I_PTHREAD_MUTEX_INITIALIZER;
- if (scm_is_false (local_eval_var))
+ scm_i_scm_pthread_mutex_lock (&local_eval_var_mutex);
+ if (SCM_UNBNDP (local_eval_var))
local_eval_var = scm_c_public_variable ("ice-9 local-eval", "local-eval");
+ scm_i_pthread_mutex_unlock (&local_eval_var_mutex);
return scm_call_2 (SCM_VARIABLE_REF (local_eval_var), exp, env);
}
diff --git a/libguile/ports.c b/libguile/ports.c
index 55808e2..8737a76 100644
--- a/libguile/ports.c
+++ b/libguile/ports.c
@@ -418,10 +418,14 @@ SCM_DEFINE (scm_current_error_port, "current-error-port",
0, 0, 0,
SCM
scm_current_warning_port (void)
{
- static SCM cwp_var = SCM_BOOL_F;
-
- if (scm_is_false (cwp_var))
- cwp_var = scm_c_private_lookup ("guile", "current-warning-port");
+ static SCM cwp_var = SCM_UNDEFINED;
+ static scm_i_pthread_mutex_t cwp_var_mutex
+ = SCM_I_PTHREAD_MUTEX_INITIALIZER;
+
+ scm_i_scm_pthread_mutex_lock (&cwp_var_mutex);
+ if (SCM_UNBNDP (cwp_var))
+ cwp_var = scm_c_private_variable ("guile", "current-warning-port");
+ scm_i_pthread_mutex_unlock (&cwp_var_mutex);
return scm_call_0 (scm_variable_ref (cwp_var));
}
diff --git a/libguile/strports.c b/libguile/strports.c
index 14cc93f..d1b293c 100644
--- a/libguile/strports.c
+++ b/libguile/strports.c
@@ -534,13 +534,16 @@ SCM_DEFINE (scm_eval_string_in_module, "eval-string", 1,
1, 0,
"procedure returns.")
#define FUNC_NAME s_scm_eval_string_in_module
{
- static SCM eval_string = SCM_BOOL_F, k_module = SCM_BOOL_F;
+ static SCM eval_string = SCM_UNDEFINED, k_module = SCM_UNDEFINED;
+ static scm_i_pthread_mutex_t init_mutex = SCM_I_PTHREAD_MUTEX_INITIALIZER;
- if (scm_is_false (eval_string))
+ scm_i_scm_pthread_mutex_lock (&init_mutex);
+ if (SCM_UNBNDP (eval_string))
{
- eval_string = scm_c_public_lookup ("ice-9 eval-string", "eval-string");
+ eval_string = scm_c_public_variable ("ice-9 eval-string", "eval-string");
k_module = scm_from_locale_keyword ("module");
}
+ scm_i_pthread_mutex_unlock (&init_mutex);
if (SCM_UNBNDP (module))
module = scm_current_module ();
--
1.7.10.4