From: Gonzalo A. <ga...@us...> - 2006-08-25 13:27:47
|
Update of /cvsroot/mod-c/mod_c/src In directory sc8-pr-cvs7.sourceforge.net:/tmp/cvs-serv16606 Modified Files: lib_cache.h lib_cache.cpp mod_c.c Log Message: * cosmetic change: define RDEBUG & SDEBUG macros. * cosmetic change: cached_ehtml is renamed to ehtml_rec. * ehtml_rec has two new fields: mtime & size (used for auto-reloading). * lib_cache: PutEHTMLIntoCache changes its signature (add ehtml_rec). * lib_cache: removed GetEHTMLEntry. * lib_cache: added LoadEHTMLFile (like GetEHTMLEntry, but uses ehtml_rec). * lib_cache: defined LoadAndCacheEHTML. * lib_cache functions smaller. * mod_c.c: defined c_[sdp]config() to get mod_c configuration. * mod_c.c: CHandler: changed behaviour, supporting auto cache & auto-refreshing ehtml files. * mod_c.c: cosmetic change in command record definitions. Index: lib_cache.cpp =================================================================== RCS file: /cvsroot/mod-c/mod_c/src/lib_cache.cpp,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** lib_cache.cpp 1 Feb 2006 21:37:58 -0000 1.3 --- lib_cache.cpp 25 Aug 2006 13:27:41 -0000 1.4 *************** *** 19,22 **** --- 19,23 ---- ***************************************************************************/ + #include "mod_c.h" #include "lib_cache.h" *************** *** 24,28 **** #include <dlfcn.h> #include <string.h> - #include "mod_c.h" #include <ehtml.h> --- 25,28 ---- *************** *** 37,48 **** }; ! struct cached_ehtml ! { ! void * handle; ! void * entry_func; ! int ref_count; ! }; ! ! typedef map< const char *, cached_ehtml, lib_cache_StringCompare > EHTMLCacheMap; #ifdef __cplusplus --- 37,41 ---- }; ! typedef map< const char *, ehtml_rec, lib_cache_StringCompare > EHTMLCacheMap; #ifdef __cplusplus *************** *** 56,108 **** } ! int PutEHTMLIntoCache( void * cache, const char * ehtml ) { ! pair< char *, cached_ehtml > _tmp; ! if ( ( _tmp.second.handle = dlopen( ehtml, RTLD_LAZY ) ) ) ! { ! if ( ( _tmp.second.entry_func = dlsym( _tmp.second.handle, EHTML_ENTRY_FUNC ) ) ) ! { ! _tmp.second.ref_count = 0; ! register int i = strlen( ehtml ) + 1; ! _tmp.first = new char[ i ]; ! memcpy( _tmp.first, ehtml, i ); ! EHTMLCacheMap * map = (EHTMLCacheMap *) cache; ! map->insert( _tmp ); ! return 0; ! } ! else ! { ! dlclose( _tmp.second.handle ); ! return 1; ! } ! } ! else ! return 1; } ! void* GetEHTMLEntry( void * cache, const char * ehtml ) { EHTMLCacheMap * map = (EHTMLCacheMap *) cache; EHTMLCacheMap::iterator itr = map->find( ehtml ); ! if ( itr != map->end() ) ! { ! itr->second.ref_count++; ! return itr->second.entry_func; ! } ! else ! return 0; } ! void ReleaseEHTMLEntry( void * cache, const char * ehtml ) { ! EHTMLCacheMap * map = (EHTMLCacheMap *) cache; ! EHTMLCacheMap::iterator itr = map->find( ehtml ); ! if ( itr != map->end() && itr->second.ref_count > 1 ) ! itr->second.ref_count--; } #ifdef __cplusplus --- 49,132 ---- } ! int LoadEHTMLFile(const char* ehtml, ehtml_rec* e) { ! e->fileh = dlopen(ehtml, RTLD_LAZY); ! if (e->fileh == NULL) ! return -1; ! e->entryf = dlsym(e->fileh, EHTML_ENTRY_FUNC); ! if (e->entryf == NULL) { ! ehtml_close(e); ! dlclose(e->fileh); ! e->fileh = NULL; ! return -1; ! } ! e->mtime = 0; ! e->size = 0; ! struct stat st; ! // If the stat fails, we simply ignore this. ! if (stat(ehtml, &st) == 0) { ! e->mtime = st.st_mtime; ! e->size = st.st_size; ! } ! return 0; ! } ! const char* LoadAndCacheEHTML(void* cache, const char* ehtml, ehtml_rec* e) ! { ! if (LoadEHTMLFile(ehtml, e) < 0) ! return dlerror(); ! if (PutEHTMLIntoCache(cache, ehtml, e) < 0) ! return strerror(errno); ! return NULL; ! } ! int PutEHTMLIntoCache(void * cache, const char* ehtml, ehtml_rec* e ) ! { ! pair< char *, ehtml_rec > _tmp; ! _tmp.first = strdup(ehtml); ! memcpy(&_tmp.second, e, sizeof(*e)); ! ! EHTMLCacheMap * map = (EHTMLCacheMap *) cache; ! bool ok = map->insert( _tmp ).second; ! if (!ok) { ! free(_tmp.first); ! _tmp.first = NULL; ! ehtml_close(&_tmp.second); ! } ! return ok ? 0 : -1; } ! int GetEHTMLEntry(void * cache, const char * ehtml, ehtml_rec* e) { EHTMLCacheMap * map = (EHTMLCacheMap *) cache; EHTMLCacheMap::iterator itr = map->find( ehtml ); ! if ( itr == map->end() ) ! return -1; ! memcpy(e, &itr->second, sizeof(*e)); ! return 0; } ! int ReleaseCachedEHTML(void* cache, const char* ehtml) { ! EHTMLCacheMap* map = (EHTMLCacheMap*)cache; ! EHTMLCacheMap::iterator i = map->find(ehtml); ! if (i != map->end()) { ! ehtml_close(&i->second); ! map->erase(i); ! return 0; ! } ! return -1; } + void ehtml_close(ehtml_rec* e) + { + if (e->fileh != NULL) + dlclose(e->fileh); + e->fileh = NULL; + e->entryf = NULL; + e->mtime = 0; + e->size = 0; + } #ifdef __cplusplus Index: mod_c.c =================================================================== RCS file: /cvsroot/mod-c/mod_c/src/mod_c.c,v retrieving revision 1.17 retrieving revision 1.18 diff -C2 -d -r1.17 -r1.18 *** mod_c.c 23 Aug 2006 10:43:38 -0000 1.17 --- mod_c.c 25 Aug 2006 13:27:41 -0000 1.18 *************** *** 35,39 **** static const char * ehtml_handler = "ehtml-bin"; ! //static const char * root_dir_id = "__root_dir_113"; /** --- 35,54 ---- static const char * ehtml_handler = "ehtml-bin"; ! mod_c_config* c_sconfig(server_rec* s) ! { ! return (mod_c_config*) ap_get_module_config(s->module_config, &c_module); ! } ! ! mod_c_dir_config* c_dconfig(request_rec* r) ! { ! return (mod_c_dir_config*) ! ap_get_module_config(r->per_dir_config, &c_module); ! } ! ! mod_c_dir_config* c_pconfig(cmd_parms* parms) ! { ! return (mod_c_dir_config*) ! ap_get_module_config(parms->context, &c_module); ! } /** *************** *** 48,93 **** static int CHandler( request_rec *r ) { ! int retVal = DECLINED; ! if ( r->handler && strncmp( r->handler, ehtml_handler, sizeof( ehtml_handler ) ) == 0 ) ! { ! ap_log_error( __FILE__, __LINE__, LOG_ERR, 0, r->server, "The file to open: '%s'", r->filename ); ! mod_c_config * config = ( mod_c_config * ) ap_get_module_config( r->server->module_config, &c_module ); ! mod_c_dir_config* dir_config = (mod_c_dir_config*) ap_get_module_config( r->per_dir_config, &c_module ); ! void * handle_to_lib = 0; ! // Try to load the handle to the loaded library from the cache ! void * handle = GetEHTMLEntry( config->ehtml_cache, r->filename ); ! // Was the handle present in the cache ! if ( !handle ) ! { ! // The handle wasn't there - load the library to memory ! if ( ( handle_to_lib = dlopen( r->filename, RTLD_LAZY ) ) ) ! { ! handle = dlsym( handle_to_lib, EHTML_ENTRY_FUNC ); ! if ( !handle ) ! dlclose( handle_to_lib ); ! } ! } ! // We have found the library that contains the EHTML application ! // execute its ehtml_run function ! if ( handle ) ! { ! ehtml_run_func _tmp = ( ehtml_run_func ) handle; ! request_context rc = { r, config, dir_config }; ! retVal = _tmp( &rc ); ! // TODO: We don't close the EHTML file as is seems to cause a crash ! // Why would closing a dl lib crash mod_c? ! // If the EHTML application wasn't loaded from the cache, close the handle ! /*if ( handle_to_lib ) ! dlclose( handle_to_lib );*/ ! } ! else ! retVal = HTTP_INTERNAL_SERVER_ERROR; ! } ! return retVal; } --- 63,120 ---- static int CHandler( request_rec *r ) { ! mod_c_config * config; ! mod_c_dir_config* dir_config; ! int retVal; ! ehtml_rec e = { NULL, NULL, 0, 0 }; ! const char* msg = NULL; ! if (r->handler == NULL || ! strncmp(r->handler, ehtml_handler, sizeof(ehtml_handler)) != 0) { ! return DECLINED; ! } ! // We must handle this request ! RDEBUG(LOG_INFO, r, "The file to open: '%s'", r->filename); ! config = c_sconfig(r->server); ! dir_config = c_dconfig(r); ! // Try to load the handle to the loaded library from the cache ! if (GetEHTMLEntry(config->ehtml_cache, r->filename, &e) <= 0) { ! // If it was not present in cache ! // Are we allowed to serve on demand requests? ! if (!config->allow_on_demand) ! return HTTP_SERVICE_UNAVAILABLE; ! ! } else { ! ! // It was present in the cache, check for auto-refresh ! if (config->allow_auto_refresh) { ! struct stat st; ! if (stat(r->filename, &st) == 0 && ! (st.st_mtime != e.mtime || st.st_size != e.size)) { ! ReleaseCachedEHTML(config->ehtml_cache, r->filename); ! } ! } ! } ! ! // Not cached || cached but stale ! if (e.entryf == NULL) { ! RDEBUG(LOG_ERR, r, "Loading %s", r->filename); ! msg = LoadAndCacheEHTML(config->ehtml_cache, r->filename, &e); ! if (msg != NULL) { ! RDEBUG(LOG_ERR, r, "Error caching %s: %s", r->filename, msg); ! return HTTP_INTERNAL_SERVER_ERROR; ! } ! } ! ! // We have found the library that contains the EHTML application ! // execute its ehtml_run function ! ehtml_run_func _tmp = ( ehtml_run_func ) e.entryf; ! request_context rc = { r, config, dir_config }; ! retVal = _tmp( &rc ); ! ! return retVal; } *************** *** 137,144 **** config->session_server_port = -1; config->disable_session_server = 0; // Add the default session driver to the driver list const char* retVal = PutSessionDriverEx( config->session_drivers, DefaultSessionIdFunc ); if ( retVal ) ! ap_log_error( __FILE__, __LINE__, LOG_ERR, 0, s, "The default driver could not have been imported. Error message: '%s'", retVal ); return config; --- 164,174 ---- config->session_server_port = -1; config->disable_session_server = 0; + config->allow_on_demand = 0; + config->allow_auto_refresh = 0; // Add the default session driver to the driver list const char* retVal = PutSessionDriverEx( config->session_drivers, DefaultSessionIdFunc ); if ( retVal ) ! SDEBUG(LOG_ERR, s, "The default driver could not have been imported. " ! "Error message: '%s'", retVal ); return config; *************** *** 193,202 **** static char* LoadEHTMLDirective( cmd_parms* parms, void *mconfig, const char * path ) { ! mod_c_config * config = ( mod_c_config * ) ap_get_module_config( parms->server->module_config, &c_module ); ! int retVal = PutEHTMLIntoCache( config->ehtml_cache, path ); ! if ( retVal ) { char * errorMsg = ( char * ) apr_palloc( parms->temp_pool, 512 ); ! snprintf( errorMsg, 512, "LoadEHTML: Could not load the specified file '%s'. Error: '%s'.", path, dlerror() ); return errorMsg; } --- 223,235 ---- static char* LoadEHTMLDirective( cmd_parms* parms, void *mconfig, const char * path ) { ! mod_c_config * config = c_sconfig(parms->server); ! ehtml_rec e; ! const char* msg = LoadAndCacheEHTML(config->ehtml_cache, path, &e); ! if (msg != NULL) { char * errorMsg = ( char * ) apr_palloc( parms->temp_pool, 512 ); ! snprintf( errorMsg, 512, ! "LoadEHTML: Could not load the specified file '%s'. " ! "Error: '%s'.", path, msg); return errorMsg; } *************** *** 205,208 **** --- 238,255 ---- } + static char* EHTMLSetAllowOnDemand(cmd_parms* parms, void *mconfig, int flag) + { + mod_c_config* config = c_sconfig(parms->server); + config->allow_on_demand = flag; + return NULL; + } + + static char* EHTMLSetCacheAutoRefresh(cmd_parms* parms, void *mconfig, int flag) + { + mod_c_config* config = c_sconfig(parms->server); + config->allow_auto_refresh = flag; + return NULL; + } + /** * Loads and registers a session driver. *************** *** 257,262 **** static char * EHTMLSessionTypeDirective( cmd_parms* parms, void *mconfig, const char * type, const char * arguments ) { ! mod_c_config * config = ( mod_c_config * ) ap_get_module_config( parms->server->module_config, &c_module ); ! mod_c_dir_config* dir_config = (mod_c_dir_config*) ap_get_module_config( parms->context, &c_module ); // Search for the session driver that supports the desired type of session management ses_dr_info_t* dr_info = GetSessionDriver( config->session_drivers, type ); --- 304,309 ---- static char * EHTMLSessionTypeDirective( cmd_parms* parms, void *mconfig, const char * type, const char * arguments ) { ! mod_c_config * config = c_sconfig(parms->server); ! mod_c_dir_config* dir_config = c_pconfig(parms); // Search for the session driver that supports the desired type of session management ses_dr_info_t* dr_info = GetSessionDriver( config->session_drivers, type ); *************** *** 310,314 **** static char * EHTMLCookielessDirective( cmd_parms * parms, void *mconfig, int on) { ! mod_c_dir_config* dir_config = (mod_c_dir_config*) ap_get_module_config( parms->context, &c_module ); dir_config->cookieless = ( on != 0 ); return 0; --- 357,361 ---- static char * EHTMLCookielessDirective( cmd_parms * parms, void *mconfig, int on) { ! mod_c_dir_config* dir_config = c_pconfig(parms); dir_config->cookieless = ( on != 0 ); return 0; *************** *** 329,333 **** else { ! mod_c_dir_config* dir_config = (mod_c_dir_config*) ap_get_module_config( parms->context, &c_module ); dir_config->key_size = bytes; return 0; --- 376,380 ---- else { ! mod_c_dir_config* dir_config = c_pconfig(parms); dir_config->key_size = bytes; return 0; *************** *** 337,347 **** command_rec c_commands[] = { ! AP_INIT_TAKE1("LoadEHTML", (void*)LoadEHTMLDirective, NULL, RSRC_CONF, "Arguments: a valid absolute path to an ehtml file. If you change the ehtml file in time the server is running, you will have to restart the server for changes to take effect." ), ! AP_INIT_TAKE1("LoadEHTMLSessionDriver", (void*)LoadEHTMLSessionDriver, NULL, RSRC_CONF, "Arguments: a valid absolute path to a session driver file." ), ! AP_INIT_FLAG("EHTMLSessions", (void*)EHTMLSessionsDirective, NULL, OR_LIMIT, "< on | off > - 'on' enables sessions while 'off' disables them." ), ! AP_INIT_TAKE1("EHTMLSessionDuration", (void*)EHTMLSessionDurationDirective, NULL, OR_LIMIT, "Specify the number of minutes, default is 30 minutes." ), ! AP_INIT_TAKE12("EHTMLSessionType", (void*)EHTMLSessionTypeDirective, NULL, OR_LIMIT, "< type > [ arguments ] - the first parameter is mandatory, while the second one is needed only if the selected type of session management needs it." ), ! AP_INIT_FLAG("EHTMLCookieless", (void*)EHTMLCookielessDirective, NULL, OR_LIMIT, "< on | off > - 'on' disables cookies while 'off' enables them." ), ! AP_INIT_TAKE1("EHTMLSessionIdSize", (void*)EHTMLSessionIdSizeDirective, NULL, OR_LIMIT, "The number of bytes" ), { NULL } }; --- 384,427 ---- command_rec c_commands[] = { ! AP_INIT_TAKE1("LoadEHTML", (void*)LoadEHTMLDirective, NULL, RSRC_CONF, ! "Arguments: a valid absolute path to an ehtml file. " ! "If you change the ehtml file in time the server is running, " ! "you will have to restart the server for changes to take effect." ), ! ! AP_INIT_FLAG("EHTMLAllowOnDemand", (void*)EHTMLSetAllowOnDemand, NULL, ! RSRC_CONF, "Argument: on|off. If set to 'on', EHTML applications " ! "are loaded on demand."), ! ! AP_INIT_FLAG("EHTMLCacheAutoRefresh", (void*)EHTMLSetCacheAutoRefresh, ! NULL, RSRC_CONF, ! "Argument: on|off. If set to 'on', EHTML cached applications will " ! "be checked on each request. If the file is modified, it will be " ! "reloaded."), ! ! // Session directives ! AP_INIT_TAKE1("LoadEHTMLSessionDriver", (void*)LoadEHTMLSessionDriver, ! NULL, RSRC_CONF, ! "Arguments: a valid absolute path to a session driver file." ), ! ! AP_INIT_FLAG("EHTMLSessions", (void*)EHTMLSessionsDirective, NULL, ! OR_LIMIT, "< on | off > - 'on' enables sessions while 'off' " ! "disables them." ), ! ! AP_INIT_TAKE1("EHTMLSessionDuration", (void*)EHTMLSessionDurationDirective, ! NULL, OR_LIMIT, "Specify the number of minutes, default is 30 " ! "minutes." ), ! ! AP_INIT_TAKE12("EHTMLSessionType", (void*)EHTMLSessionTypeDirective, NULL, ! OR_LIMIT, "< type > [ arguments ] - the first parameter is " ! "mandatory, while the second one is needed only if the selected " ! "type of session management needs it." ), ! ! AP_INIT_FLAG("EHTMLCookieless", (void*)EHTMLCookielessDirective, NULL, ! OR_LIMIT, "< on | off > - 'on' disables cookies while 'off' " ! "enables them." ), ! ! AP_INIT_TAKE1("EHTMLSessionIdSize", (void*)EHTMLSessionIdSizeDirective, ! NULL, OR_LIMIT, "The number of bytes" ), ! { NULL } }; *************** *** 357,358 **** --- 437,439 ---- CRegisterHooks }; + Index: lib_cache.h =================================================================== RCS file: /cvsroot/mod-c/mod_c/src/lib_cache.h,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** lib_cache.h 23 Aug 2006 10:43:38 -0000 1.3 --- lib_cache.h 25 Aug 2006 13:27:41 -0000 1.4 *************** *** 25,28 **** --- 25,29 ---- extern "C" { + #include "mod_c.h" #endif *************** *** 44,49 **** * @param lib_filename * The name of the EHTML file to load. */ ! int PutEHTMLIntoCache( void * map, const char * lib_filename); /** --- 45,53 ---- * @param lib_filename * The name of the EHTML file to load. + * + * @param e_rec + * <rec>ehtml_rec*</code> structure describing ehtml handle. */ ! int PutEHTMLIntoCache( void * map, const char * lib_filename, ehtml_rec* e_rec); /** *************** *** 57,75 **** * @param lib_filename * The name of the EHTML file to lookup. */ ! void* GetEHTMLEntry( void * map, const char * lib_filename); /** ! * Removes a loaded EHTML file from the map (the cache). * ! * @param map ! * The map that was created with and returned by ! * <code>CreateEHTMLCache</code>. * ! * @param lib_filename ! * The name of the EHTML file to remove. */ ! void ReleaseEHTMLEntry( void * map, const char * lib_filename); #ifdef __cplusplus } --- 61,117 ---- * @param lib_filename * The name of the EHTML file to lookup. + * + * @param e_rec + * <rec>ehtml_rec*</code> structure describing ehtml handle. */ ! int GetEHTMLEntry( void * map, const char * lib_filename, ehtml_rec* e_rec); /** ! * Removes a cached EHTML entry. ! * Returns 0 if it was successfully erased. * ! * @param cache ! * The map that should have the entry. * ! * @param ehtml ! * filename that contains the application to unload. */ ! int ReleaseCachedEHTML(void* cache, const char* ehtml); ! ! /** ! * Loads the EHTML application in the file specified in <code>ehtml</code>. ! * Return <code>null</code>. ! * ! * @param ehtml ! * The filename containing the EHTML application. ! * ! * @param e_rec ! * The application handler. ! */ ! int LoadEHTMLFile(const char* ehtml, ehtml_rec* e_rec); ! ! /** ! * Loads and cache the EHTML application in the file specified ! * in <code>ehtml</code>. ! * Return <code>null</code>. ! * ! * @param cache ! * The EHTML application cache. ! * ! * @param ehtml ! * The filename containing the EHTML application. ! * ! * @param e_rec ! * The application handler. ! */ ! const char* LoadAndCacheEHTML(void* cache, const char* ehtml, ehtml_rec* e); + /** + * Closes the EHTML application handler. + * + * @param e_rec + * The handle to close. + */ + void ehtml_close(ehtml_rec* e_rec); #ifdef __cplusplus } |