in src/mod_rivet_ng/worker_prefork_common.c [308:359]
void Rivet_ProcessorCleanup (void *data)
{
int i;
rivet_thread_private* private = (rivet_thread_private *) data;
ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, module_globals->server,
"Thread exiting after %d requests served (%d vhosts)",
private->req_cnt,module_globals->vhosts_count);
/* We are about to delete the interpreters and release the thread channel.
* Rivet channel is set as stdout channel of Tcl and as such is treated
* by Tcl_UnregisterChannel is a special way. When its refCount reaches 1
* the channel is released immediately by forcing the refCount to 0
* (see Tcl source code: generic/TclIO.c). Unregistering for each interpreter
* causes the process to segfault at least for certain Tcl versions.
* We unset the channel as stdout to avoid this
*/
Tcl_SetStdChannel(NULL,TCL_STDOUT);
/* there must be always a root interpreter in the slot 0 of private->interps,
* so we always need to run this cycle at least once
*/
i = 0;
do
{
RivetCache_Cleanup(private,private->ext->interps[i]);
if ((i > 0) && module_globals->separate_channels)
Rivet_ReleaseRivetChannel(private->ext->interps[i]->interp,private->channel);
Tcl_DeleteInterp(private->ext->interps[i]->interp);
/* Release interpreter scripts */
Rivet_ReleaseRunningScripts(private->ext->interps[i]->scripts);
/* Release scripts defined within <Directory...></Directory> conf blocks */
Rivet_ReleasePerDirScripts(private->ext->interps[i]);
/* if separate_virtual_interps == 0 we are running the same interpreter
* instance for each vhost, thus we can jump out of this loop after
* the first cycle as the only real intepreter object we have is stored
* in private->ext->interps[0]
*/
} while ((++i < module_globals->vhosts_count) && module_globals->separate_virtual_interps);
}