From c4f3b5e9efcd9661ec0b5e156f5a74ef7bacbb17 Mon Sep 17 00:00:00 2001 From: axel Date: Wed, 11 Oct 2006 08:45:46 +1000 Subject: [PATCH] Unload older autoloaded functions darcs-hash:20061010224546-ac50b-7c3f38d32d4a413a9c0d8436bb13a5d65235f3a7.gz --- parse_util.c | 76 +++++++++++++++++++++++++++++++++++++++++++++++++--- parse_util.h | 6 +++-- 2 files changed, 77 insertions(+), 5 deletions(-) diff --git a/parse_util.c b/parse_util.c index d4b821464..ab08bd8c2 100644 --- a/parse_util.c +++ b/parse_util.c @@ -33,6 +33,18 @@ #include "wildcard.h" #include "halloc_util.h" +/** + Maximum number of autoloaded items opf a specific type to keep in + memory at a time. +*/ +#define AUTOLOAD_MAX 10 + +/** + Minimum time, in seconds, before an autoloaded item will be + unloaded +*/ +#define AUTOLOAD_MIN_AGE 60 + /** A structure representing the autoload state for a specific variable, e.g. fish_complete_path */ @@ -580,7 +592,63 @@ int parse_util_unload( const wchar_t *cmd, return !!val; } -static int path_util_load_internal( const wchar_t *cmd, +static void parse_util_autounload( wchar_t *path_var_name, + wchar_t *skip, + void (*on_load)(const wchar_t *cmd) ) +{ + autoload_t *loaded; + int loaded_count=0; + + if( !all_loaded ) + { + return; + } + + loaded = (autoload_t *)hash_get( all_loaded, path_var_name ); + if( !loaded ) + { + return; + } + + if( hash_get_count( &loaded->load_time ) >= AUTOLOAD_MAX ) + { + time_t oldest_access = time(0) - AUTOLOAD_MIN_AGE; + wchar_t *oldest_item=0; + int i; + array_list_t key; + al_init( &key ); + hash_get_keys( &loaded->load_time, &key ); + for( i=0; iload_time, item ); + + if( wcscmp( item, skip ) == 0 ) + { + continue; + } + + if( !tm[0] ) + continue; + + loaded_count++; + + if( tm[1] < oldest_access ) + { + oldest_access = tm[1]; + oldest_item = item; + } + } + + if( oldest_item && loaded_count > AUTOLOAD_MAX) + { + parse_util_unload( oldest_item, path_var_name, on_load ); + } + } +} + + +static int parse_util_load_internal( const wchar_t *cmd, void (*on_load)(const wchar_t *cmd), int reload, autoload_t *loaded, @@ -603,6 +671,8 @@ 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 ); @@ -690,7 +760,7 @@ int parse_util_load( const wchar_t *cmd, Do the actual work in the internal helper function */ - res = path_util_load_internal( cmd, on_load, reload, loaded, path_list ); + res = parse_util_load_internal( cmd, on_load, reload, loaded, path_list ); /** Cleanup @@ -718,7 +788,7 @@ int parse_util_load( const wchar_t *cmd, the code, and the caller can take care of various cleanup work. */ -static int path_util_load_internal( const wchar_t *cmd, +static int parse_util_load_internal( const wchar_t *cmd, void (*on_load)(const wchar_t *cmd), int reload, autoload_t *loaded, diff --git a/parse_util.h b/parse_util.h index c91151079..e2a5c1e65 100644 --- a/parse_util.h +++ b/parse_util.h @@ -98,14 +98,16 @@ int parse_util_lineno( const wchar_t *str, int len ); not load it multiple times unless it's timestamp changes or parse_util_unload is called. + Autoloading one file may unload another. + \param cmd the filename to search for. The suffix '.fish' is always added to this name \param path_var_name the environment variable giving the search path - \param on_load a callback function to run if a suitable file is found, which has not already been run + \param unload a callback function to run if a suitable file is found, which has not already been run. unload will also be called for old files which are unloaded. \param reload wheter to recheck file timestamps on already loaded files */ int parse_util_load( const wchar_t *cmd, const wchar_t *path_var_name, - void (*on_load)(const wchar_t *cmd), + void (*unload)(const wchar_t *cmd), int reload ); /**