aboutsummaryrefslogtreecommitdiffhomepage
path: root/parse_util.c
diff options
context:
space:
mode:
authorGravatar axel <axel@liljencrantz.se>2006-10-29 02:41:22 +1000
committerGravatar axel <axel@liljencrantz.se>2006-10-29 02:41:22 +1000
commitc5eaefc8b5a615c5559bb50510625d2a025dafb8 (patch)
tree4f746fa3f00d074fcef3d319a403d120191aafbe /parse_util.c
parentf16bb285be7edc4abc75fc32348459eda79c7cf0 (diff)
Update autoloader to fix concurrency issues when changing loader path in autoloaded function
darcs-hash:20061028164122-ac50b-25f978df9afeb370a06ef7576ef03183034bc057.gz
Diffstat (limited to 'parse_util.c')
-rw-r--r--parse_util.c67
1 files changed, 40 insertions, 27 deletions
diff --git a/parse_util.c b/parse_util.c
index dc3ae9a5..af4b20c5 100644
--- a/parse_util.c
+++ b/parse_util.c
@@ -2,6 +2,10 @@
Various mostly unrelated utility functions related to parsing,
loading and evaluating fish code.
+
+ This library can be seen as a 'toolbox' for functions that are
+ used in many places in fish and that are somehow related to
+ parsing the code.
*/
#include "config.h"
@@ -491,9 +495,18 @@ static void clear_hash_value( void *key, void *data, void *aux )
if( aux )
{
wchar_t *name = (wchar_t *)key;
+ time_t *time = (time_t *)data;
void (*handler)(const wchar_t *)= (void (*)(const wchar_t *))aux;
- if( handler )
+
+ /*
+ If time[0] is 0, that means the file really doesn't exist,
+ it's simply been checked before. We should not unload it.
+ */
+ if( time[0] && handler )
+ {
+// debug( 0, L"Unloading function %ls", name );
handler( name );
+ }
}
free( (void *)data );
@@ -540,14 +553,8 @@ static void parse_util_destroy()
void parse_util_load_reset( const wchar_t *path_var_name,
void (*on_load)(const wchar_t *cmd) )
{
- wchar_t *path_var;
-
CHECK( path_var_name, );
- path_var = env_get( path_var_name );
- if( !path_var )
- return;
-
if( all_loaded )
{
void *key, *data;
@@ -654,7 +661,6 @@ static void parse_util_autounload( const wchar_t *path_var_name,
}
}
-
static int parse_util_load_internal( const wchar_t *cmd,
void (*on_load)(const wchar_t *cmd),
int reload,
@@ -679,10 +685,10 @@ int parse_util_load( const wchar_t *cmd,
CHECK( path_var_name, 0 );
CHECK( cmd, 0 );
- parse_util_autounload( path_var_name, cmd, on_load );
-
// debug( 0, L"Autoload %ls in %ls", cmd, path_var_name );
+ parse_util_autounload( path_var_name, cmd, on_load );
+
path_var = env_get( path_var_name );
/*
@@ -712,6 +718,18 @@ int parse_util_load( const wchar_t *cmd,
if( loaded )
{
+ /*
+ Check if the lookup path has changed. If so, drop all loaded
+ files and start from scratch.
+ */
+ if( wcscmp( path_var, loaded->old_path ) != 0 )
+ {
+ debug( 0, L"path change, new path is %ls", path_var );
+ parse_util_load_reset( path_var_name, on_load);
+ reload = parse_util_load( cmd, path_var_name, on_load, reload );
+ return reload;
+ }
+
/**
Warn and fail on infinite recursion
*/
@@ -724,17 +742,7 @@ int parse_util_load( const wchar_t *cmd,
return 1;
}
- /*
- Check if the lookup path has changed. If so, drop all loaded
- files and start from scratch.
- */
- if( wcscmp( path_var, loaded->old_path ) != 0 )
- {
- parse_util_load_reset( path_var_name, on_load);
- reload = parse_util_load( cmd, path_var_name, on_load, reload );
-// debug( 0, L"Reload" );
- return reload;
- }
+
}
else
{
@@ -742,6 +750,7 @@ int parse_util_load( const wchar_t *cmd,
We have never tried to autoload using this path name before,
set up initial data
*/
+// debug( 0, L"Create brand new autoload_t for %ls->%ls", path_var_name, path_var );
loaded = malloc( sizeof( autoload_t ) );
if( !loaded )
{
@@ -819,7 +828,6 @@ static int parse_util_load_internal( const wchar_t *cmd,
{
if(time(0)-tm[1]<=1)
{
-// debug( 0, L"Cached" );
return 0;
}
}
@@ -829,8 +837,6 @@ static int parse_util_load_internal( const wchar_t *cmd,
*/
if( !reload && tm )
{
-// debug( 0, L"Weak check" );
-
return 0;
}
@@ -871,10 +877,10 @@ static int parse_util_load_internal( const wchar_t *cmd,
intern( cmd ),
tm );
-
if( on_load )
on_load(cmd );
+
/*
Source the completion file for the specified completion
*/
@@ -888,6 +894,15 @@ static int parse_util_load_internal( const wchar_t *cmd,
free(src_cmd);
reloaded = 1;
}
+ else if( tm )
+ {
+ /*
+ If we are rechecking an autoload file, and it hasn't
+ changed, update the 'last check' timestamp.
+ */
+ tm[1] = time(0);
+ }
+
break;
}
}
@@ -908,8 +923,6 @@ static int parse_util_load_internal( const wchar_t *cmd,
hash_put( &loaded->load_time, intern( cmd ), tm );
}
-// debug( 0, L"Regular return" );
-
return reloaded;
}