Roxen.git / server / base_server / configuration.pike

version» Context lines:

Roxen.git/server/base_server/configuration.pike:1:   // A vitual server's main configuration   // Copyright © 1996 - 2000, Roxen IS. - constant cvs_version = "$Id: configuration.pike,v 1.428 2001/05/03 17:26:41 per Exp $"; + constant cvs_version = "$Id: configuration.pike,v 1.429 2001/05/07 02:48:33 per Exp $";   #include <module.h>   #include <module_constants.h>   #include <roxen.h>   #include <request_trace.h>   #include <timers.h>      #define CATCH(P,X) do{mixed e;if(e=catch{X;})report_error("While "+P+"\n"+describe_backtrace(e));}while(0)      // --- Locale defines ---   //<locale-token project="roxen_start"> LOC_S </locale-token>
Roxen.git/server/base_server/configuration.pike:25:   #else   #define THROTTLING_DEBUG(X)   #endif      #ifdef REQUEST_DEBUG   # define REQUEST_WERR(X) report_debug("CONFIG: "+X+"\n")   #else   # define REQUEST_WERR(X)   #endif    +  + #ifdef AVERAGE_PROFILING + class ProfStack + { +  array current_stack = ({}); +  +  void enter( string k, RequestID id ) +  { +  current_stack += ({ ({ k, gethrtime(), gethrvtime() }) }); +  } +  +  void leave( string k, RequestID id ) +  { +  int t0 = gethrtime(); +  int t1 = gethrvtime(); +  +  if( !sizeof(current_stack ) ) +  { +  report_error("Popping out of profiling stack\n"); +  return; +  } +  +  int i = sizeof( current_stack )-1; +  while( current_stack[ i ][0] != k && i >= 0 ) i--; +  +  if(i < 0 ) +  { +  report_error("Popping out of profiling stack, cannot find %O in %O\n", +  k, current_stack); +  return; +  } +  +  int tt = t0-current_stack[i][1]; +  int ttv = t1-current_stack[i][2]; +  +  if( i > 0 ) // Do not count child time in parent. +  { +  current_stack[i-1][1]+=tt+gethrtime()-t0; +  current_stack[i-1][2]+=ttv+gethrvtime()-t1; +  } +  current_stack = current_stack[..i-1]; +  add_prof_entry( id, k, tt, ttv ); +  } + } +  + class ProfInfo( string url ) + { +  mapping data = ([]); +  void add( string k, int h, int hrv ) +  { +  if( !data[k] ) +  data[k] = ({ h, hrv, 1 }); +  else +  { +  data[k][0]+=h; +  data[k][1]+=hrv; +  data[k][2]++; +  } +  } +  +  array summarize_table( ) +  { +  array table = ({}); +  int n, t, v; +  foreach( indices( data ), string k ) +  table += ({ ({ k, +  sprintf( "%d", (n=data[k][2]) ), +  sprintf("%5.2f",(t=data[k][0])/1000000.0), +  sprintf("%5.2f", (v=data[k][1])/1000000.0), +  sprintf("%8.2f", t/n/1000.0), +  sprintf("%8.2f",v/n/1000.0), }) }); +  sort( (array(float))column(table,2), table ); +  return reverse(table); +  } +  +  void dump( ) +  { +  write( "\n"+url+": \n" ); +  ADT.Table t = ADT.Table->table( summarize_table(), +  ({ "What", "Calls", +  "Time", "CPU", +  "t/call(ms)", "cpu/call(ms)" })); +  +  write( ADT.Table.ASCII.encode( t )+"\n" ); +  +  } + } +  + mapping profiling_info = ([]); +  + void debug_write_prof( ) + { +  foreach( sort( indices( profiling_info ) ), string p ) +  profiling_info[p]->dump(); + } +  + void add_prof_entry( RequestID id, string k, int hr, int hrv ) + { +  if( !profiling_info[id->not_query] ) +  profiling_info[id->not_query] = ProfInfo(id->not_query); +  profiling_info[id->not_query]->add( k, hr, hrv ); + } +  + void avg_prof_enter( string name, string type, RequestID id ) + { +  if( !id->misc->prof_stack ) +  id->misc->prof_stack = ProfStack(); +  id->misc->prof_stack->enter( name+":"+type,id ); + } + void avg_prof_leave( string name, string type, RequestID id ) + { +  if( !id->misc->prof_stack ) id->misc->prof_stack = ProfStack(); +  id->misc->prof_stack->leave( name+":"+type,id ); + } + #endif +  +    /* A configuration.. */   inherit Configuration;   inherit "basic_defvar";      // Trivial cache (actually, it's more or less identical to the 200+   // lines of C in HTTPLoop. But it does not have to bother with the   // fact that more than one thread can be active in it at once. Also,   // it does not have to delay free until all current connections using   // the cache entry is done...)   class DataCache
Roxen.git/server/base_server/configuration.pike:1163: Inside #if defined(MODULE_LEVEL_SECURITY)
   } else {    TRACE_LEAVE("");    TRACE_LEAVE("Request denied.");    TIMER_END(internal_magic);    return tmp2;    }   #endif    if(find_internal)    {    TRACE_ENTER("Calling find_internal()...", find_internal); +  PROF_ENTER("find_internal","location");    LOCK(find_internal);    fid=find_internal( rest, id );    UNLOCK();    TRACE_LEAVE(sprintf("find_internal has returned %O", fid)); -  +  PROF_LEAVE("find_internal","location");    if(fid)    {    if(mappingp(fid))    {    TRACE_LEAVE("");    TRACE_LEAVE(examine_return_mapping(fid));    TIMER_END(internal_magic);    return fid;    }    else
Roxen.git/server/base_server/configuration.pike:1219:       // Well, this just _might_ be somewhat over-optimized, since it is    // quite unreadable, but, you cannot win them all..    if(!fid)    {   #ifdef URL_MODULES    // Map URL-modules    TIMER_START(url_modules);    foreach(url_module_cache||url_modules(), funp)    { +  PROF_ENTER(Roxen.get_owning_module(funp)->module_name,"url module");    LOCK(funp);    TRACE_ENTER("URL module", funp);    tmp=funp( id, file );    UNLOCK(); -  +  PROF_LEAVE(Roxen.get_owning_module(funp)->module_name,"url module");       if(mappingp(tmp))    {    TRACE_LEAVE("");    TRACE_LEAVE("Returning data");    TIMER_END(url_modules);    return tmp;    }    if(objectp( tmp ))    {
Roxen.git/server/base_server/configuration.pike:1278: Inside #if defined(MODULE_LEVEL_SECURITY)
   {    TRACE_LEAVE("Permission to access module denied.");    continue;    } else {    TRACE_LEAVE("");    TRACE_LEAVE("Request denied.");    TIMER_END(location_modules);    return tmp2;    }   #endif +  PROF_ENTER(Roxen.get_owning_module(tmp[1])->module_name,"location module");    TRACE_ENTER("Calling find_file()...", 0);    LOCK(tmp[1]);    fid=tmp[1]( file[ strlen(loc) .. ] + id->extra_extension, id);    UNLOCK();    TRACE_LEAVE(""); -  +  PROF_LEAVE(Roxen.get_owning_module(tmp[1])->module_name,"location module");    if(fid)    {    id->virtfile = loc;       if(mappingp(fid))    {    TRACE_LEAVE("");    TRACE_LEAVE(examine_return_mapping(fid));    TIMER_END(location_modules);    return fid;
Roxen.git/server/base_server/configuration.pike:1352:    if(fid == -1)    {    if(no_magic)    {    TRACE_LEAVE("No magic requested. Returning -1.");    return -1;    }    TIMER_START(directory_module);    if(dir_module)    { +  PROF_ENTER(dir_module->module_name,"directory module");    LOCK(dir_module);    TRACE_ENTER("Directory module", dir_module);    fid = dir_module->parse_directory(id);    UNLOCK(); -  +  PROF_LEAVE(dir_module->module_name,"directory module");    }    else    {    TRACE_LEAVE("No directory module. Returning 'no such file'");    return 0;    }    TIMER_END(directory_module);    if(mappingp(fid))    {    TRACE_LEAVE("Returning data");
Roxen.git/server/base_server/configuration.pike:1393: Inside #if defined(MODULE_LEVEL_SECURITY)
   continue;    }    else    {    TRACE_LEAVE("");    TRACE_LEAVE("Permission denied");    TIMER_END(extension_module);    return tmp;    }   #endif +  PROF_ENTER(Roxen.get_owning_module(funp)->module_name,"ext module");    LOCK(funp);    tmp=funp(fid, loc, id);    UNLOCK(); -  +  PROF_LEAVE(Roxen.get_owning_module(funp)->module_name,"ext module");    if(tmp)    {    if(!objectp(tmp))    {    TRACE_LEAVE("");    TRACE_LEAVE("Returning data");    TIMER_END(extension_module);    return tmp;    }    if(fid && tmp != fid)
Roxen.git/server/base_server/configuration.pike:1504:    res = low_get_file(id, no_magic);    TIMER_END(get_file);       // finally map all filter type modules.    // Filter modules are like TYPE_LAST modules, but they get called    // for _all_ files.    TIMER_START(filter_modules);    foreach(filter_module_cache||filter_modules(), tmp)    {    TRACE_ENTER("Filter module", tmp); +  PROF_ENTER(Roxen.get_owning_module(tmp)->module_name,"filter");    if(res2=tmp(res,id))    {    if(res && res->file && (res2->file != res->file))    destruct(res->file);    TRACE_LEAVE("Rewrote result.");    res=res2;    } else    TRACE_LEAVE(""); -  +  PROF_LEAVE(Roxen.get_owning_module(tmp)->module_name,"filter");    }    TIMER_END(filter_modules);       id->misc->internal_get = orig_internal_get;    return res;   }      array(string) find_dir(string file, RequestID id, void|int(0..1) verbose)   {    array dir;