| ︙ | | | ︙ | |
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
|
*/
void
Tcl_DeleteExitHandler(
Tcl_ExitProc *proc, /* Function that was previously registered. */
void *clientData) /* Arbitrary value to pass to proc. */
{
ExitHandler *exitPtr, *prevPtr;
Tcl_MutexLock(&exitMutex);
for (prevPtr = NULL, exitPtr = firstExitPtr; exitPtr != NULL;
prevPtr = exitPtr, exitPtr = exitPtr->nextPtr) {
if ((exitPtr->proc == proc)
&& (exitPtr->clientData == clientData)) {
if (prevPtr == NULL) {
firstExitPtr = exitPtr->nextPtr;
} else {
prevPtr->nextPtr = exitPtr->nextPtr;
|
<
<
|
|
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
|
*/
void
Tcl_DeleteExitHandler(
Tcl_ExitProc *proc, /* Function that was previously registered. */
void *clientData) /* Arbitrary value to pass to proc. */
{
Tcl_MutexLock(&exitMutex);
for (ExitHandler *prevPtr = NULL, *exitPtr = firstExitPtr; exitPtr != NULL;
prevPtr = exitPtr, exitPtr = exitPtr->nextPtr) {
if ((exitPtr->proc == proc)
&& (exitPtr->clientData == clientData)) {
if (prevPtr == NULL) {
firstExitPtr = exitPtr->nextPtr;
} else {
prevPtr->nextPtr = exitPtr->nextPtr;
|
| ︙ | | | ︙ | |
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
|
*/
void
TclDeleteLateExitHandler(
Tcl_ExitProc *proc, /* Function that was previously registered. */
void *clientData) /* Arbitrary value to pass to proc. */
{
ExitHandler *exitPtr, *prevPtr;
Tcl_MutexLock(&exitMutex);
for (prevPtr = NULL, exitPtr = firstLateExitPtr; exitPtr != NULL;
prevPtr = exitPtr, exitPtr = exitPtr->nextPtr) {
if ((exitPtr->proc == proc)
&& (exitPtr->clientData == clientData)) {
if (prevPtr == NULL) {
firstLateExitPtr = exitPtr->nextPtr;
} else {
prevPtr->nextPtr = exitPtr->nextPtr;
|
<
<
|
|
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
|
*/
void
TclDeleteLateExitHandler(
Tcl_ExitProc *proc, /* Function that was previously registered. */
void *clientData) /* Arbitrary value to pass to proc. */
{
Tcl_MutexLock(&exitMutex);
for (ExitHandler *prevPtr = NULL, *exitPtr = firstLateExitPtr; exitPtr;
prevPtr = exitPtr, exitPtr = exitPtr->nextPtr) {
if ((exitPtr->proc == proc)
&& (exitPtr->clientData == clientData)) {
if (prevPtr == NULL) {
firstLateExitPtr = exitPtr->nextPtr;
} else {
prevPtr->nextPtr = exitPtr->nextPtr;
|
| ︙ | | | ︙ | |
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
|
*/
void
Tcl_CreateThreadExitHandler(
Tcl_ExitProc *proc, /* Function to invoke. */
void *clientData) /* Arbitrary value to pass to proc. */
{
ExitHandler *exitPtr;
ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
exitPtr = (ExitHandler*)Tcl_Alloc(sizeof(ExitHandler));
exitPtr->proc = proc;
exitPtr->clientData = clientData;
exitPtr->nextPtr = tsdPtr->firstExitPtr;
tsdPtr->firstExitPtr = exitPtr;
}
/*
|
<
|
|
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
|
*/
void
Tcl_CreateThreadExitHandler(
Tcl_ExitProc *proc, /* Function to invoke. */
void *clientData) /* Arbitrary value to pass to proc. */
{
ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
ExitHandler *exitPtr = (ExitHandler*) Tcl_Alloc(sizeof(ExitHandler));
exitPtr->proc = proc;
exitPtr->clientData = clientData;
exitPtr->nextPtr = tsdPtr->firstExitPtr;
tsdPtr->firstExitPtr = exitPtr;
}
/*
|
| ︙ | | | ︙ | |
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
|
*/
void
Tcl_DeleteThreadExitHandler(
Tcl_ExitProc *proc, /* Function that was previously registered. */
void *clientData) /* Arbitrary value to pass to proc. */
{
ExitHandler *exitPtr, *prevPtr;
ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
for (prevPtr = NULL, exitPtr = tsdPtr->firstExitPtr; exitPtr != NULL;
prevPtr = exitPtr, exitPtr = exitPtr->nextPtr) {
if ((exitPtr->proc == proc)
&& (exitPtr->clientData == clientData)) {
if (prevPtr == NULL) {
tsdPtr->firstExitPtr = exitPtr->nextPtr;
} else {
prevPtr->nextPtr = exitPtr->nextPtr;
|
<
|
|
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
|
*/
void
Tcl_DeleteThreadExitHandler(
Tcl_ExitProc *proc, /* Function that was previously registered. */
void *clientData) /* Arbitrary value to pass to proc. */
{
ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
for (ExitHandler *prevPtr = NULL, *exitPtr = tsdPtr->firstExitPtr; exitPtr;
prevPtr = exitPtr, exitPtr = exitPtr->nextPtr) {
if ((exitPtr->proc == proc)
&& (exitPtr->clientData == clientData)) {
if (prevPtr == NULL) {
tsdPtr->firstExitPtr = exitPtr->nextPtr;
} else {
prevPtr->nextPtr = exitPtr->nextPtr;
|
| ︙ | | | ︙ | |
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
|
* freed.
*
*----------------------------------------------------------------------
*/
static void
InvokeExitHandlers(void)
{
ExitHandler *exitPtr;
Tcl_MutexLock(&exitMutex);
inExit = 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;
|
<
<
|
>
|
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
|
* freed.
*
*----------------------------------------------------------------------
*/
static void
InvokeExitHandlers(void)
{
Tcl_MutexLock(&exitMutex);
inExit = 1;
for (ExitHandler *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;
|
| ︙ | | | ︙ | |
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
|
* returns, so critical is this dependency.
*
* If subsystems are not (yet) initialized, proper Tcl-finalization is
* impossible, so fallback to system exit, see bug-[f8a33ce3db5d8cc2].
*/
if (currentAppExitPtr) {
currentAppExitPtr(INT2PTR(status));
} else if (subsystemsInitialized) {
if (TclFullFinalizationRequested()) {
/*
* Thorough finalization for Valgrind et al.
*/
Tcl_Finalize();
} else {
/*
* Fast and deterministic exit (default behavior)
*/
InvokeExitHandlers();
/*
|
<
<
<
<
|
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
|
* returns, so critical is this dependency.
*
* If subsystems are not (yet) initialized, proper Tcl-finalization is
* impossible, so fallback to system exit, see bug-[f8a33ce3db5d8cc2].
*/
if (currentAppExitPtr) {
currentAppExitPtr(INT2PTR(status));
} else if (subsystemsInitialized) {
if (TclFullFinalizationRequested()) {
/*
* Thorough finalization for Valgrind et al.
*/
Tcl_Finalize();
} else {
/*
* Fast and deterministic exit (default behavior)
*/
InvokeExitHandlers();
/*
|
| ︙ | | | ︙ | |
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
|
*
*----------------------------------------------------------------------
*/
void
Tcl_Finalize(void)
{
ExitHandler *exitPtr;
/*
* Invoke exit handlers first.
*/
InvokeExitHandlers();
TclpInitLock();
|
<
<
|
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
|
*
*----------------------------------------------------------------------
*/
void
Tcl_Finalize(void)
{
/*
* Invoke exit handlers first.
*/
InvokeExitHandlers();
TclpInitLock();
|
| ︙ | | | ︙ | |
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
|
Tcl_FinalizeThread();
/*
* Now invoke late (process-wide) exit handlers.
*/
Tcl_MutexLock(&exitMutex);
for (exitPtr = firstLateExitPtr; exitPtr != NULL;
exitPtr = firstLateExitPtr) {
/*
* 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_DeleteLateExitHandler on itself.
*/
|
|
|
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
|
Tcl_FinalizeThread();
/*
* Now invoke late (process-wide) exit handlers.
*/
Tcl_MutexLock(&exitMutex);
for (ExitHandler *exitPtr = firstLateExitPtr; exitPtr != NULL;
exitPtr = firstLateExitPtr) {
/*
* 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_DeleteLateExitHandler on itself.
*/
|
| ︙ | | | ︙ | |
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
|
FinalizeThread(/* quick */ 0);
}
void
FinalizeThread(
int quick)
{
ExitHandler *exitPtr;
ThreadSpecificData *tsdPtr;
/*
* We use TclThreadDataKeyGet here, rather than Tcl_GetThreadData, because
* we don't want to initialize the data block if it hasn't been
* initialized already.
*/
tsdPtr = (ThreadSpecificData*)TclThreadDataKeyGet(&dataKey);
if (tsdPtr != NULL) {
tsdPtr->inExit = 1;
for (exitPtr = tsdPtr->firstExitPtr; exitPtr != NULL;
exitPtr = tsdPtr->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_DeleteThreadExitHandler on itself.
*/
|
<
<
<
>
|
|
|
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
|
FinalizeThread(/* quick */ 0);
}
void
FinalizeThread(
int quick)
{
/*
* We use TclThreadDataKeyGet here, rather than Tcl_GetThreadData, because
* we don't want to initialize the data block if it hasn't been
* initialized already.
*/
ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
TclThreadDataKeyGet(&dataKey);
if (tsdPtr != NULL) {
tsdPtr->inExit = 1;
for (ExitHandler *exitPtr = tsdPtr->firstExitPtr; exitPtr != NULL;
exitPtr = tsdPtr->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_DeleteThreadExitHandler on itself.
*/
|
| ︙ | | | ︙ | |