Cleanup proc_had_barrier

Ensure we don't try to do a universal barrier off of the main thread
This commit is contained in:
ridiculousfish 2012-03-31 15:33:34 -07:00
parent ff17101316
commit 268fb37517
5 changed files with 63 additions and 45 deletions

88
env.cpp
View file

@ -730,6 +730,7 @@ static env_node_t *env_get_node( const wcstring &key )
int env_set(const wchar_t *key, const wchar_t *val, int var_mode) int env_set(const wchar_t *key, const wchar_t *val, int var_mode)
{ {
ASSERT_IS_MAIN_THREAD();
env_node_t *node = NULL; env_node_t *node = NULL;
bool has_changed_old = has_changed; bool has_changed_old = has_changed;
bool has_changed_new = false; bool has_changed_new = false;
@ -840,9 +841,9 @@ int env_set(const wchar_t *key, const wchar_t *val, int var_mode)
} }
else else
{ {
if( !proc_had_barrier) if( ! get_proc_had_barrier())
{ {
proc_had_barrier=1; set_proc_had_barrier(true);
env_universal_barrier(); env_universal_barrier();
} }
@ -1062,7 +1063,8 @@ const wchar_t *env_var_t::c_str(void) const {
env_var_t env_get_string( const wcstring &key ) env_var_t env_get_string( const wcstring &key )
{ {
/* Big hack...we only allow getting the history on the main thread. Note that history_t may ask for an environment variable, so don't take the lock here (we don't need it) */ /* Big hack...we only allow getting the history on the main thread. Note that history_t may ask for an environment variable, so don't take the lock here (we don't need it) */
if( key == L"history" && is_main_thread()) const bool is_main = is_main_thread();
if( key == L"history" && is_main)
{ {
env_var_t result; env_var_t result;
@ -1100,42 +1102,44 @@ env_var_t env_get_string( const wcstring &key )
wcstring result; wcstring result;
while( env != 0 ) while( env != 0 )
{
var_table_t::iterator result = env->env.find(key);
if ( result != env->env.end() )
{
res = result->second;
}
else
{
res = 0;
}
if( res != 0 )
{
if( res->val == ENV_NULL )
{
return env_var_t::missing_var();
}
else
{
return res->val;
}
}
if( env->new_scope )
{
env = global_env;
}
else
{
env = env->next;
}
}
if( !proc_had_barrier)
{ {
proc_had_barrier=1; var_table_t::iterator result = env->env.find(key);
if ( result != env->env.end() )
{
res = result->second;
}
else
{
res = 0;
}
if( res != 0 )
{
if( res->val == ENV_NULL )
{
return env_var_t::missing_var();
}
else
{
return res->val;
}
}
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) */
if(is_main && ! get_proc_had_barrier())
{
set_proc_had_barrier(true);
env_universal_barrier(); env_universal_barrier();
} }
@ -1211,9 +1215,9 @@ int env_exist( const wchar_t *key, int mode )
if( ! (mode & ENV_LOCAL) && ! (mode & ENV_GLOBAL) ) if( ! (mode & ENV_LOCAL) && ! (mode & ENV_GLOBAL) )
{ {
if( !proc_had_barrier) if( ! get_proc_had_barrier())
{ {
proc_had_barrier=1; set_proc_had_barrier(true);
env_universal_barrier(); env_universal_barrier();
} }
@ -1453,9 +1457,9 @@ static void export_func(const std::map<wcstring, wcstring> &envs, std::vector<st
static void update_export_array_if_necessary(bool recalc) { static void update_export_array_if_necessary(bool recalc) {
ASSERT_IS_MAIN_THREAD(); ASSERT_IS_MAIN_THREAD();
if( recalc && !proc_had_barrier) if( recalc && ! get_proc_had_barrier())
{ {
proc_had_barrier=1; set_proc_had_barrier(true);
env_universal_barrier(); env_universal_barrier();
} }

View file

@ -338,6 +338,7 @@ int env_universal_get_export( const wchar_t *name )
void env_universal_barrier() void env_universal_barrier()
{ {
ASSERT_IS_MAIN_THREAD();
message_t *msg; message_t *msg;
fd_set fds; fd_set fds;

View file

@ -2251,6 +2251,7 @@ void parser_t::skipped_exec( job_t * j )
void parser_t::eval_job( tokenizer *tok ) void parser_t::eval_job( tokenizer *tok )
{ {
ASSERT_IS_MAIN_THREAD();
job_t *j; job_t *j;
int start_pos = job_start_pos = tok_get_pos( tok ); int start_pos = job_start_pos = tok_get_pos( tok );
@ -2340,7 +2341,7 @@ void parser_t::eval_job( tokenizer *tok )
/* Only external commands require a new fishd barrier */ /* Only external commands require a new fishd barrier */
if( !was_builtin ) if( !was_builtin )
proc_had_barrier=0; set_proc_had_barrier(false);
} }
else else
{ {

View file

@ -122,18 +122,29 @@ int is_subshell=0;
int is_block=0; int is_block=0;
int is_login=0; int is_login=0;
int is_event=0; int is_event=0;
int proc_had_barrier;
pid_t proc_last_bg_pid = 0; pid_t proc_last_bg_pid = 0;
int job_control_mode = JOB_CONTROL_INTERACTIVE; int job_control_mode = JOB_CONTROL_INTERACTIVE;
int no_exec=0; int no_exec=0;
static int is_interactive = -1; static int is_interactive = -1;
static bool proc_had_barrier = false;
int get_is_interactive(void) { int get_is_interactive(void) {
ASSERT_IS_MAIN_THREAD(); ASSERT_IS_MAIN_THREAD();
return is_interactive; return is_interactive;
} }
bool get_proc_had_barrier() {
ASSERT_IS_MAIN_THREAD();
return proc_had_barrier;
}
void set_proc_had_barrier(bool flag) {
ASSERT_IS_MAIN_THREAD();
proc_had_barrier = flag;
}
/** /**
The event variable used to send all process event The event variable used to send all process event
*/ */

3
proc.h
View file

@ -464,7 +464,8 @@ class job_iterator_t {
Both setting it to one when it should be zero and the opposite may Both setting it to one when it should be zero and the opposite may
cause concurrency bugs. cause concurrency bugs.
*/ */
extern int proc_had_barrier; bool get_proc_had_barrier();
void set_proc_had_barrier(bool flag);
/** /**
Pid of last process to be started in the background Pid of last process to be started in the background