aboutsummaryrefslogtreecommitdiffhomepage
path: root/env.cpp
diff options
context:
space:
mode:
authorGravatar ridiculousfish <corydoras@ridiculousfish.com>2012-04-23 11:08:29 -0700
committerGravatar ridiculousfish <corydoras@ridiculousfish.com>2012-04-23 11:08:29 -0700
commit3aeadd9fb7e2290afa2426b46e83aef44b366dfb (patch)
tree53837d2163b4aac5ea4979431345f58454182091 /env.cpp
parent0e3eb38f1185078662ee44c3120326cdb88274b4 (diff)
Fix for a deadlock when env_get_string ends up calling env_get_string
Diffstat (limited to 'env.cpp')
-rw-r--r--env.cpp65
1 files changed, 31 insertions, 34 deletions
diff --git a/env.cpp b/env.cpp
index a7a26398..813df860 100644
--- a/env.cpp
+++ b/env.cpp
@@ -1092,58 +1092,55 @@ env_var_t env_get_string( const wcstring &key )
{
return format_string(L"0%0.3o", get_umask() );
}
- else {
-
- scoped_lock lock(env_lock);
-
- var_entry_t *res;
- env_node_t *env = top;
- wchar_t *item;
- wcstring result;
-
- while( env != 0 )
+ else
+ {
{
- var_table_t::iterator result = env->env.find(key);
- if ( result != env->env.end() )
- {
- res = result->second;
- }
- else
- {
- res = 0;
- }
+ /* Lock around a local region */
+ scoped_lock lock(env_lock);
+ var_entry_t *res = NULL;
+ env_node_t *env = top;
+ wcstring result;
- if( res != 0 )
+ while( env != NULL )
{
- if( res->val == ENV_NULL )
+ var_table_t::iterator result = env->env.find(key);
+ if ( result != env->env.end() )
+ res = result->second;
+
+
+ if( res != NULL )
{
- return env_var_t::missing_var();
+ if( res->val == ENV_NULL )
+ {
+ return env_var_t::missing_var();
+ }
+ else
+ {
+ return res->val;
+ }
+ }
+
+ if( env->new_scope )
+ {
+ env = global_env;
}
else
{
- return res->val;
+ env = env->next;
}
}
-
- if( env->new_scope )
- {
- env = global_env;
- }
- else
- {
- env = env->next;
- }
}
- /* Another big hack - only do a universal barrier on the main thread (since it can change variable values) */
+ /* Another big hack - only do a universal barrier on the main thread (since it can change variable values)
+ Make sure we do this outside the env_lock because it may itself call env_get_string */
if(is_main && ! get_proc_had_barrier())
{
set_proc_had_barrier(true);
env_universal_barrier();
}
- item = env_universal_get( key );
+ wchar_t *item = env_universal_get( key );
if( !item || (wcscmp( item, ENV_NULL )==0))
{