mirror of
https://git.savannah.gnu.org/git/guile.git
synced 2025-04-30 11:50:28 +02:00
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.
This commit is contained in:
parent
29ace173b1
commit
f57ea23ac8
4 changed files with 29 additions and 14 deletions
|
@ -945,14 +945,18 @@ the @var{name} is not bound in the module, signals an error. Returns a
|
||||||
variable, always.
|
variable, always.
|
||||||
|
|
||||||
@example
|
@example
|
||||||
|
static SCM eval_string_var;
|
||||||
|
|
||||||
|
/* NOTE: It is important that the call to 'my_init'
|
||||||
|
happens-before all calls to 'my_eval_string'. */
|
||||||
|
void my_init (void)
|
||||||
|
@{
|
||||||
|
eval_string_var = scm_c_public_lookup ("ice-9 eval-string",
|
||||||
|
"eval-string");
|
||||||
|
@}
|
||||||
|
|
||||||
SCM my_eval_string (SCM str)
|
SCM my_eval_string (SCM str)
|
||||||
@{
|
@{
|
||||||
static SCM eval_string_var = SCM_BOOL_F;
|
|
||||||
|
|
||||||
if (scm_is_false (eval_string_var))
|
|
||||||
eval_string_var =
|
|
||||||
scm_c_public_lookup ("ice-9 eval-string", "eval-string");
|
|
||||||
|
|
||||||
return scm_call_1 (scm_variable_ref (eval_string_var), str);
|
return scm_call_1 (scm_variable_ref (eval_string_var), str);
|
||||||
@}
|
@}
|
||||||
@end example
|
@end example
|
||||||
|
|
|
@ -211,10 +211,14 @@ SCM_DEFINE (scm_debug_hang, "debug-hang", 0, 1, 0,
|
||||||
SCM
|
SCM
|
||||||
scm_local_eval (SCM exp, SCM env)
|
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");
|
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);
|
return scm_call_2 (SCM_VARIABLE_REF (local_eval_var), exp, env);
|
||||||
}
|
}
|
||||||
|
|
|
@ -418,10 +418,14 @@ SCM_DEFINE (scm_current_error_port, "current-error-port", 0, 0, 0,
|
||||||
SCM
|
SCM
|
||||||
scm_current_warning_port (void)
|
scm_current_warning_port (void)
|
||||||
{
|
{
|
||||||
static SCM cwp_var = SCM_BOOL_F;
|
static SCM cwp_var = SCM_UNDEFINED;
|
||||||
|
static scm_i_pthread_mutex_t cwp_var_mutex
|
||||||
|
= SCM_I_PTHREAD_MUTEX_INITIALIZER;
|
||||||
|
|
||||||
if (scm_is_false (cwp_var))
|
scm_i_scm_pthread_mutex_lock (&cwp_var_mutex);
|
||||||
cwp_var = scm_c_private_lookup ("guile", "current-warning-port");
|
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));
|
return scm_call_0 (scm_variable_ref (cwp_var));
|
||||||
}
|
}
|
||||||
|
|
|
@ -534,13 +534,16 @@ SCM_DEFINE (scm_eval_string_in_module, "eval-string", 1, 1, 0,
|
||||||
"procedure returns.")
|
"procedure returns.")
|
||||||
#define FUNC_NAME s_scm_eval_string_in_module
|
#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");
|
k_module = scm_from_locale_keyword ("module");
|
||||||
}
|
}
|
||||||
|
scm_i_pthread_mutex_unlock (&init_mutex);
|
||||||
|
|
||||||
if (SCM_UNBNDP (module))
|
if (SCM_UNBNDP (module))
|
||||||
module = scm_current_module ();
|
module = scm_current_module ();
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue