1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
/*
* tclLoad.c --
*
* This file provides the generic portion (those that are the same on all
* platforms) of Tcl's dynamic loading facilities.
*
* Copyright (c) 1995-1997 Sun Microsystems, Inc.
*
* See the file "license.terms" for information on usage and redistribution of
* this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
* RCS: @(#) $Id: tclLoad.c,v 1.16 2007/02/20 23:24:03 nijtmans Exp $
*/
#include "tclInt.h"
/*
* The following structure describes a package that has been loaded either
* dynamically (with the "load" command) or statically (as indicated by a call
|
|
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
/*
* tclLoad.c --
*
* This file provides the generic portion (those that are the same on all
* platforms) of Tcl's dynamic loading facilities.
*
* Copyright (c) 1995-1997 Sun Microsystems, Inc.
*
* See the file "license.terms" for information on usage and redistribution of
* this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
* RCS: @(#) $Id: tclLoad.c,v 1.17 2008/05/30 22:54:29 dkf Exp $
*/
#include "tclInt.h"
/*
* The following structure describes a package that has been loaded either
* dynamically (with the "load" command) or statically (as indicated by a call
|
| ︙ | | | ︙ | |
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
|
/*
* Scan through the list of packages already loaded in the target
* interpreter. If the package we want is already loaded there, then
* there's nothing for us to do.
*/
if (pkgPtr != NULL) {
ipFirstPtr = (InterpPackage *) Tcl_GetAssocData(target,
"tclLoad", NULL);
for (ipPtr = ipFirstPtr; ipPtr != NULL; ipPtr = ipPtr->nextPtr) {
if (ipPtr->pkgPtr == pkgPtr) {
code = TCL_OK;
goto done;
}
}
}
|
<
|
|
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
|
/*
* Scan through the list of packages already loaded in the target
* interpreter. If the package we want is already loaded there, then
* there's nothing for us to do.
*/
if (pkgPtr != NULL) {
ipFirstPtr = Tcl_GetAssocData(target, "tclLoad", NULL);
for (ipPtr = ipFirstPtr; ipPtr != NULL; ipPtr = ipPtr->nextPtr) {
if (ipPtr->pkgPtr == pkgPtr) {
code = TCL_OK;
goto done;
}
}
}
|
| ︙ | | | ︙ | |
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
|
procPtrs[2] = &unloadProc;
procPtrs[3] = &safeUnloadProc;
Tcl_MutexLock(&packageMutex);
code = TclLoadFile(interp, objv[1], 4, symbols, procPtrs,
&loadHandle, &clientData, &unLoadProcPtr);
Tcl_MutexUnlock(&packageMutex);
loadHandle = (Tcl_LoadHandle) clientData;
if (code != TCL_OK) {
goto done;
}
if (*procPtrs[0] /* initProc */ == NULL) {
Tcl_AppendResult(interp, "couldn't find procedure ",
Tcl_DStringValue(&initName), NULL);
if (unLoadProcPtr != NULL) {
(*unLoadProcPtr)(loadHandle);
}
code = TCL_ERROR;
goto done;
}
/*
* Create a new record to describe this package.
*/
pkgPtr = (LoadedPackage *) ckalloc(sizeof(LoadedPackage));
pkgPtr->fileName = (char *) ckalloc((unsigned)
(strlen(fullFileName) + 1));
strcpy(pkgPtr->fileName, fullFileName);
pkgPtr->packageName = (char *) ckalloc((unsigned)
(Tcl_DStringLength(&pkgName) + 1));
strcpy(pkgPtr->packageName, Tcl_DStringValue(&pkgName));
pkgPtr->loadHandle = loadHandle;
pkgPtr->unLoadProcPtr = unLoadProcPtr;
pkgPtr->initProc = *procPtrs[0];
pkgPtr->safeInitProc = *procPtrs[1];
pkgPtr->unloadProc = (Tcl_PackageUnloadProc*) *procPtrs[2];
pkgPtr->safeUnloadProc = (Tcl_PackageUnloadProc*) *procPtrs[3];
pkgPtr->interpRefCount = 0;
pkgPtr->safeInterpRefCount = 0;
Tcl_MutexLock(&packageMutex);
pkgPtr->nextPtr = firstPackagePtr;
firstPackagePtr = pkgPtr;
Tcl_MutexUnlock(&packageMutex);
}
/*
* Invoke the package's initialization function (either the normal one or
* the safe one, depending on whether or not the interpreter is safe).
*/
if (Tcl_IsSafe(target)) {
if (pkgPtr->safeInitProc != NULL) {
code = (*pkgPtr->safeInitProc)(target);
} else {
Tcl_AppendResult(interp,
"can't use package in a safe interpreter: no ",
pkgPtr->packageName, "_SafeInit procedure", NULL);
code = TCL_ERROR;
goto done;
}
} else {
code = (*pkgPtr->initProc)(target);
}
/*
* Record the fact that the package has been loaded in the target
* interpreter.
*/
|
|
|
|
|
|
|
|
|
|
|
|
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
|
procPtrs[2] = &unloadProc;
procPtrs[3] = &safeUnloadProc;
Tcl_MutexLock(&packageMutex);
code = TclLoadFile(interp, objv[1], 4, symbols, procPtrs,
&loadHandle, &clientData, &unLoadProcPtr);
Tcl_MutexUnlock(&packageMutex);
loadHandle = clientData;
if (code != TCL_OK) {
goto done;
}
if (*procPtrs[0] /* initProc */ == NULL) {
Tcl_AppendResult(interp, "couldn't find procedure ",
Tcl_DStringValue(&initName), NULL);
if (unLoadProcPtr != NULL) {
unLoadProcPtr(loadHandle);
}
code = TCL_ERROR;
goto done;
}
/*
* Create a new record to describe this package.
*/
pkgPtr = (LoadedPackage *) ckalloc(sizeof(LoadedPackage));
pkgPtr->fileName =
ckalloc((unsigned) (strlen(fullFileName) + 1));
strcpy(pkgPtr->fileName, fullFileName);
pkgPtr->packageName =
ckalloc((unsigned) (Tcl_DStringLength(&pkgName) + 1));
strcpy(pkgPtr->packageName, Tcl_DStringValue(&pkgName));
pkgPtr->loadHandle = loadHandle;
pkgPtr->unLoadProcPtr = unLoadProcPtr;
pkgPtr->initProc = *procPtrs[0];
pkgPtr->safeInitProc = *procPtrs[1];
pkgPtr->unloadProc = (Tcl_PackageUnloadProc *) *procPtrs[2];
pkgPtr->safeUnloadProc = (Tcl_PackageUnloadProc *) *procPtrs[3];
pkgPtr->interpRefCount = 0;
pkgPtr->safeInterpRefCount = 0;
Tcl_MutexLock(&packageMutex);
pkgPtr->nextPtr = firstPackagePtr;
firstPackagePtr = pkgPtr;
Tcl_MutexUnlock(&packageMutex);
}
/*
* Invoke the package's initialization function (either the normal one or
* the safe one, depending on whether or not the interpreter is safe).
*/
if (Tcl_IsSafe(target)) {
if (pkgPtr->safeInitProc != NULL) {
code = pkgPtr->safeInitProc(target);
} else {
Tcl_AppendResult(interp,
"can't use package in a safe interpreter: no ",
pkgPtr->packageName, "_SafeInit procedure", NULL);
code = TCL_ERROR;
goto done;
}
} else {
code = pkgPtr->initProc(target);
}
/*
* Record the fact that the package has been loaded in the target
* interpreter.
*/
|
| ︙ | | | ︙ | |
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
|
Tcl_MutexUnlock(&packageMutex);
/*
* Refetch ipFirstPtr: loading the package may have introduced
* additional static packages at the head of the linked list!
*/
ipFirstPtr = (InterpPackage *) Tcl_GetAssocData(target,
"tclLoad", NULL);
ipPtr = (InterpPackage *) ckalloc(sizeof(InterpPackage));
ipPtr->pkgPtr = pkgPtr;
ipPtr->nextPtr = ipFirstPtr;
Tcl_SetAssocData(target, "tclLoad", LoadCleanupProc,
(ClientData) ipPtr);
} else {
TclTransferResult(target, code, interp);
}
done:
Tcl_DStringFree(&pkgName);
Tcl_DStringFree(&initName);
|
<
|
|
<
|
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
|
Tcl_MutexUnlock(&packageMutex);
/*
* Refetch ipFirstPtr: loading the package may have introduced
* additional static packages at the head of the linked list!
*/
ipFirstPtr = Tcl_GetAssocData(target, "tclLoad", NULL);
ipPtr = (InterpPackage *) ckalloc(sizeof(InterpPackage));
ipPtr->pkgPtr = pkgPtr;
ipPtr->nextPtr = ipFirstPtr;
Tcl_SetAssocData(target, "tclLoad", LoadCleanupProc, ipPtr);
} else {
TclTransferResult(target, code, interp);
}
done:
Tcl_DStringFree(&pkgName);
Tcl_DStringFree(&initName);
|
| ︙ | | | ︙ | |
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
|
/*
* Figure out which interpreter we're going to load the package into.
*/
target = interp;
if (objc - i == 3) {
char *slaveIntName;
slaveIntName = Tcl_GetString(objv[i+2]);
target = Tcl_GetSlave(interp, slaveIntName);
if (target == NULL) {
return TCL_ERROR;
}
}
/*
|
|
|
|
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
|
/*
* Figure out which interpreter we're going to load the package into.
*/
target = interp;
if (objc - i == 3) {
char *slaveIntName = Tcl_GetString(objv[i + 2]);
target = Tcl_GetSlave(interp, slaveIntName);
if (target == NULL) {
return TCL_ERROR;
}
}
/*
|
| ︙ | | | ︙ | |
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
|
* Scan through the list of packages already loaded in the target
* interpreter. If the package we want is already loaded there, then we
* should proceed with unloading.
*/
code = TCL_ERROR;
if (pkgPtr != NULL) {
ipFirstPtr = (InterpPackage *) Tcl_GetAssocData(target,
"tclLoad", NULL);
for (ipPtr = ipFirstPtr; ipPtr != NULL; ipPtr = ipPtr->nextPtr) {
if (ipPtr->pkgPtr == pkgPtr) {
code = TCL_OK;
break;
}
}
}
|
<
|
|
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
|
* Scan through the list of packages already loaded in the target
* interpreter. If the package we want is already loaded there, then we
* should proceed with unloading.
*/
code = TCL_ERROR;
if (pkgPtr != NULL) {
ipFirstPtr = Tcl_GetAssocData(target, "tclLoad", NULL);
for (ipPtr = ipFirstPtr; ipPtr != NULL; ipPtr = ipPtr->nextPtr) {
if (ipPtr->pkgPtr == pkgPtr) {
code = TCL_OK;
break;
}
}
}
|
| ︙ | | | ︙ | |
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
|
--trustedRefCount;
}
if (safeRefCount <= 0 && trustedRefCount <= 0) {
code = TCL_UNLOAD_DETACH_FROM_PROCESS;
}
}
code = (*unloadProc)(target, code);
if (code != TCL_OK) {
TclTransferResult(target, code, interp);
goto done;
}
/*
* The unload function executed fine. Examine the reference count to see
|
|
|
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
|
--trustedRefCount;
}
if (safeRefCount <= 0 && trustedRefCount <= 0) {
code = TCL_UNLOAD_DETACH_FROM_PROCESS;
}
}
code = unloadProc(target, code);
if (code != TCL_OK) {
TclTransferResult(target, code, interp);
goto done;
}
/*
* The unload function executed fine. Examine the reference count to see
|
| ︙ | | | ︙ | |
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
|
*/
if (pkgPtr->fileName[0] != '\0') {
Tcl_FSUnloadFileProc *unLoadProcPtr = pkgPtr->unLoadProcPtr;
if (unLoadProcPtr != NULL) {
Tcl_MutexLock(&packageMutex);
(*unLoadProcPtr)(pkgPtr->loadHandle);
/*
* Remove this library from the loaded library cache.
*/
defaultPtr = pkgPtr;
if (defaultPtr == firstPackagePtr) {
|
|
|
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
|
*/
if (pkgPtr->fileName[0] != '\0') {
Tcl_FSUnloadFileProc *unLoadProcPtr = pkgPtr->unLoadProcPtr;
if (unLoadProcPtr != NULL) {
Tcl_MutexLock(&packageMutex);
unLoadProcPtr(pkgPtr->loadHandle);
/*
* Remove this library from the loaded library cache.
*/
defaultPtr = pkgPtr;
if (defaultPtr == firstPackagePtr) {
|
| ︙ | | | ︙ | |
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
|
}
}
/*
* Remove this library from the interpreter's library cache.
*/
ipFirstPtr = (InterpPackage *) Tcl_GetAssocData(target,
"tclLoad", NULL);
ipPtr = ipFirstPtr;
if (ipPtr->pkgPtr == defaultPtr) {
ipFirstPtr = ipFirstPtr->nextPtr;
} else {
InterpPackage *ipPrevPtr;
for (ipPrevPtr = ipPtr; ipPtr != NULL;
ipPrevPtr = ipPtr, ipPtr = ipPtr->nextPtr) {
if (ipPtr->pkgPtr == pkgPtr) {
ipPrevPtr->nextPtr = ipPtr->nextPtr;
break;
}
}
}
Tcl_SetAssocData(target, "tclLoad", LoadCleanupProc,
(ClientData) ipFirstPtr);
ckfree(defaultPtr->fileName);
ckfree(defaultPtr->packageName);
ckfree((char *) defaultPtr);
ckfree((char *) ipPtr);
Tcl_MutexUnlock(&packageMutex);
} else {
Tcl_AppendResult(interp, "file \"", fullFileName,
|
<
|
|
|
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
|
}
}
/*
* Remove this library from the interpreter's library cache.
*/
ipFirstPtr = Tcl_GetAssocData(target, "tclLoad", NULL);
ipPtr = ipFirstPtr;
if (ipPtr->pkgPtr == defaultPtr) {
ipFirstPtr = ipFirstPtr->nextPtr;
} else {
InterpPackage *ipPrevPtr;
for (ipPrevPtr = ipPtr; ipPtr != NULL;
ipPrevPtr = ipPtr, ipPtr = ipPtr->nextPtr) {
if (ipPtr->pkgPtr == pkgPtr) {
ipPrevPtr->nextPtr = ipPtr->nextPtr;
break;
}
}
}
Tcl_SetAssocData(target, "tclLoad", LoadCleanupProc,
ipFirstPtr);
ckfree(defaultPtr->fileName);
ckfree(defaultPtr->packageName);
ckfree((char *) defaultPtr);
ckfree((char *) ipPtr);
Tcl_MutexUnlock(&packageMutex);
} else {
Tcl_AppendResult(interp, "file \"", fullFileName,
|
| ︙ | | | ︙ | |
951
952
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
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
|
Tcl_MutexUnlock(&packageMutex);
/*
* If the package is not yet recorded as being loaded statically, add it
* to the list now.
*/
if ( pkgPtr == NULL ) {
pkgPtr = (LoadedPackage *) ckalloc(sizeof(LoadedPackage));
pkgPtr->fileName = (char *) ckalloc((unsigned) 1);
pkgPtr->fileName[0] = 0;
pkgPtr->packageName = (char *)
ckalloc((unsigned) (strlen(pkgName) + 1));
strcpy(pkgPtr->packageName, pkgName);
pkgPtr->loadHandle = NULL;
pkgPtr->initProc = initProc;
pkgPtr->safeInitProc = safeInitProc;
Tcl_MutexLock(&packageMutex);
pkgPtr->nextPtr = firstPackagePtr;
firstPackagePtr = pkgPtr;
Tcl_MutexUnlock(&packageMutex);
}
if (interp != NULL) {
/*
* If we're loading the package into an interpreter, determine whether
* it's already loaded.
*/
ipFirstPtr = (InterpPackage *) Tcl_GetAssocData(interp,
"tclLoad", NULL);
for ( ipPtr = ipFirstPtr; ipPtr != NULL; ipPtr = ipPtr->nextPtr ) {
if ( ipPtr->pkgPtr == pkgPtr ) {
return;
}
}
/*
* Package isn't loade in the current interp yet. Mark it as now being
* loaded.
*/
ipPtr = (InterpPackage *) ckalloc(sizeof(InterpPackage));
ipPtr->pkgPtr = pkgPtr;
ipPtr->nextPtr = ipFirstPtr;
Tcl_SetAssocData(interp, "tclLoad", LoadCleanupProc,
(ClientData) ipPtr);
}
}
/*
*----------------------------------------------------------------------
*
* TclGetLoadedPackages --
|
|
|
<
|
<
|
|
|
|
<
|
946
947
948
949
950
951
952
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
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
|
Tcl_MutexUnlock(&packageMutex);
/*
* If the package is not yet recorded as being loaded statically, add it
* to the list now.
*/
if (pkgPtr == NULL) {
pkgPtr = (LoadedPackage *) ckalloc(sizeof(LoadedPackage));
pkgPtr->fileName = ckalloc((unsigned) 1);
pkgPtr->fileName[0] = 0;
pkgPtr->packageName = ckalloc((unsigned) (strlen(pkgName) + 1));
strcpy(pkgPtr->packageName, pkgName);
pkgPtr->loadHandle = NULL;
pkgPtr->initProc = initProc;
pkgPtr->safeInitProc = safeInitProc;
Tcl_MutexLock(&packageMutex);
pkgPtr->nextPtr = firstPackagePtr;
firstPackagePtr = pkgPtr;
Tcl_MutexUnlock(&packageMutex);
}
if (interp != NULL) {
/*
* If we're loading the package into an interpreter, determine whether
* it's already loaded.
*/
ipFirstPtr = Tcl_GetAssocData(interp, "tclLoad", NULL);
for (ipPtr = ipFirstPtr; ipPtr != NULL; ipPtr = ipPtr->nextPtr) {
if (ipPtr->pkgPtr == pkgPtr) {
return;
}
}
/*
* Package isn't loade in the current interp yet. Mark it as now being
* loaded.
*/
ipPtr = (InterpPackage *) ckalloc(sizeof(InterpPackage));
ipPtr->pkgPtr = pkgPtr;
ipPtr->nextPtr = ipFirstPtr;
Tcl_SetAssocData(interp, "tclLoad", LoadCleanupProc, ipPtr);
}
}
/*
*----------------------------------------------------------------------
*
* TclGetLoadedPackages --
|
| ︙ | | | ︙ | |
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
|
Tcl_Interp *interp, /* Interpreter in which to return information
* or error message. */
char *targetName) /* Name of target interpreter or NULL. If
* NULL, return info about all interps;
* otherwise, just return info about this
* interpreter. */
{
Tcl_Interp *target;
LoadedPackage *pkgPtr;
InterpPackage *ipPtr;
const char *prefix;
if (targetName == NULL) {
/*
|
>
|
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
|
Tcl_Interp *interp, /* Interpreter in which to return information
* or error message. */
char *targetName) /* Name of target interpreter or NULL. If
* NULL, return info about all interps;
* otherwise, just return info about this
* interpreter. */
{
/* TODO: Use Tcl_Obj APIs to generate this info for cleanliness. */
Tcl_Interp *target;
LoadedPackage *pkgPtr;
InterpPackage *ipPtr;
const char *prefix;
if (targetName == NULL) {
/*
|
| ︙ | | | ︙ | |
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
|
* interpreter.
*/
target = Tcl_GetSlave(interp, targetName);
if (target == NULL) {
return TCL_ERROR;
}
ipPtr = (InterpPackage *) Tcl_GetAssocData(target, "tclLoad", NULL);
prefix = "{";
for ( ; ipPtr != NULL; ipPtr = ipPtr->nextPtr) {
pkgPtr = ipPtr->pkgPtr;
Tcl_AppendResult(interp, prefix, NULL);
Tcl_AppendElement(interp, pkgPtr->fileName);
Tcl_AppendElement(interp, pkgPtr->packageName);
Tcl_AppendResult(interp, "}", NULL);
prefix = " {";
}
|
|
|
|
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
|
* interpreter.
*/
target = Tcl_GetSlave(interp, targetName);
if (target == NULL) {
return TCL_ERROR;
}
ipPtr = Tcl_GetAssocData(target, "tclLoad", NULL);
prefix = "{";
for (; ipPtr != NULL; ipPtr = ipPtr->nextPtr) {
pkgPtr = ipPtr->pkgPtr;
Tcl_AppendResult(interp, prefix, NULL);
Tcl_AppendElement(interp, pkgPtr->fileName);
Tcl_AppendElement(interp, pkgPtr->packageName);
Tcl_AppendResult(interp, "}", NULL);
prefix = " {";
}
|
| ︙ | | | ︙ | |
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
|
LoadCleanupProc(
ClientData clientData, /* Pointer to first InterpPackage structure
* for interp. */
Tcl_Interp *interp) /* Interpreter that is being deleted. */
{
InterpPackage *ipPtr, *nextPtr;
ipPtr = (InterpPackage *) clientData;
while (ipPtr != NULL) {
nextPtr = ipPtr->nextPtr;
ckfree((char *) ipPtr);
ipPtr = nextPtr;
}
}
|
|
|
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
|
LoadCleanupProc(
ClientData clientData, /* Pointer to first InterpPackage structure
* for interp. */
Tcl_Interp *interp) /* Interpreter that is being deleted. */
{
InterpPackage *ipPtr, *nextPtr;
ipPtr = clientData;
while (ipPtr != NULL) {
nextPtr = ipPtr->nextPtr;
ckfree((char *) ipPtr);
ipPtr = nextPtr;
}
}
|
| ︙ | | | ︙ | |
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
|
TclFinalizeLoad(void)
{
LoadedPackage *pkgPtr;
/*
* No synchronization here because there should just be one thread alive
* at this point. Logically, packageMutex should be grabbed at this point,
* but the Mutexes get finalized before the call to this routine. The
* only subsystem left alive at this point is the memory allocator.
*/
while (firstPackagePtr != NULL) {
pkgPtr = firstPackagePtr;
firstPackagePtr = pkgPtr->nextPtr;
#if defined(TCL_UNLOAD_DLLS) || defined(__WIN32__)
/*
* Some Unix dlls are poorly behaved - registering things like atexit
* calls that can't be unregistered. If you unload such dlls, you get
* a core on exit because it wants to call a function in the dll after
* it has been unloaded.
*/
if (pkgPtr->fileName[0] != '\0') {
Tcl_FSUnloadFileProc *unLoadProcPtr = pkgPtr->unLoadProcPtr;
if (unLoadProcPtr != NULL) {
(*unLoadProcPtr)(pkgPtr->loadHandle);
}
}
#endif
ckfree(pkgPtr->fileName);
ckfree(pkgPtr->packageName);
ckfree((char *) pkgPtr);
|
|
|
<
|
|
|
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
|
TclFinalizeLoad(void)
{
LoadedPackage *pkgPtr;
/*
* No synchronization here because there should just be one thread alive
* at this point. Logically, packageMutex should be grabbed at this point,
* but the Mutexes get finalized before the call to this routine. The only
* subsystem left alive at this point is the memory allocator.
*/
while (firstPackagePtr != NULL) {
pkgPtr = firstPackagePtr;
firstPackagePtr = pkgPtr->nextPtr;
#if defined(TCL_UNLOAD_DLLS) || defined(__WIN32__)
/*
* Some Unix dlls are poorly behaved - registering things like atexit
* calls that can't be unregistered. If you unload such dlls, you get
* a core on exit because it wants to call a function in the dll after
* it has been unloaded.
*/
if (pkgPtr->fileName[0] != '\0') {
if (pkgPtr->unLoadProcPtr != NULL) {
pkgPtr->unLoadProcPtr(pkgPtr->loadHandle);
}
}
#endif
ckfree(pkgPtr->fileName);
ckfree(pkgPtr->packageName);
ckfree((char *) pkgPtr);
|
| ︙ | | | ︙ | |