Artifact
c917148257ac8c7e63c161e41784fee7f8445825:
Attachment "TclEvent_c.txt" to
ticket [1589794fff]
added by
celine_thales
2007-01-22 16:21:03.
void
Tcl_Finalize()
{
ExitHandler *exitPtr;
ThreadSpecificData *tsdPtr;
TclpInitLock();
if (subsystemsInitialized != 0) {
subsystemsInitialized = 0;
tsdPtr = TCL_TSD_INIT(&dataKey);
/*
* Invoke exit handlers first.
*/
Tcl_MutexLock(&exitMutex);
inFinalize = 1;
for (exitPtr = firstExitPtr; exitPtr != NULL; exitPtr = firstExitPtr) {
/*
* Be careful to remove the handler from the list before
* invoking its callback. This protects us against
* double-freeing if the callback should call
* Tcl_DeleteExitHandler on itself.
*/
firstExitPtr = exitPtr->nextPtr;
Tcl_MutexUnlock(&exitMutex);
(*exitPtr->proc)(exitPtr->clientData);
ckfree((char *) exitPtr);
Tcl_MutexLock(&exitMutex);
}
firstExitPtr = NULL;
Tcl_MutexUnlock(&exitMutex);
/*
* Clean up after the current thread now, after exit handlers.
* In particular, the testexithandler command sets up something
* that writes to standard output, which gets closed.
* Note that there is no thread-local storage after this call.
*/
Tcl_FinalizeThread();
/*
* Now finalize the Tcl execution environment. Note that this
* must be done after the exit handlers, because there are
* order dependencies.
*/
TclFinalizeCompExecEnv();
TclFinalizeEnvironment();
TclFinalizeEncodingSubsystem();
if (tclExecutableName != NULL) {
ckfree(tclExecutableName);
tclExecutableName = NULL;
}
if (tclNativeExecutableName != NULL) {
ckfree(tclNativeExecutableName);
tclNativeExecutableName = NULL;
}
if (tclDefaultEncodingDir != NULL) {
ckfree(tclDefaultEncodingDir);
tclDefaultEncodingDir = NULL;
}
Tcl_SetPanicProc(NULL);
// Added to avoid memeory leak
TclFinalizeThreadData();
/*
* Free synchronization objects. There really should only be one
* thread alive at this moment.
*/
TclFinalizeSynchronization();
/*
* We defer unloading of packages until very late
* to avoid memory access issues. Both exit callbacks and
* synchronization variables may be stored in packages.
*/
TclFinalizeLoad();
/*
* There shouldn't be any malloc'ed memory after this.
*/
TclFinalizeMemorySubsystem();
inFinalize = 0;
}
TclpInitUnlock();
}