Diff
Not logged in

Differences From Artifact [7f4081eec8]:

To Artifact [bb5228652a]:


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.
	     */