Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Separate library unloading routine from [unload] command processing. |
---|---|
Downloads: | Tarball | ZIP archive | SQL archive |
Timelines: | family | ancestors | descendants | both | pyk-tclUnload |
Files: | files | file ages | folders |
SHA3-256: |
723d1eb93779e81bfd2dcb23cbd87782 |
User & Date: | pooryorick 2021-05-15 07:55:55.923 |
References
2021-05-15
| ||
22:30 | • Ticket [28027d8bb7] Per-interp Loaded library structures not cleaned up on interp exit. status still Open with 4 other changes artifact: 2b81c100ce user: pooryorick | |
Context
2021-05-15
| ||
10:10 | merge core-8-branch check-in: aa66f1cc04 user: pooryorick tags: pyk-tclUnload | |
07:55 | Separate library unloading routine from [unload] command processing. check-in: 723d1eb937 user: pooryorick tags: pyk-tclUnload | |
2021-05-14
| ||
13:54 | Respect TIP #587 in dde test-cases. check-in: 45fa0ff557 user: jan.nijtmans tags: core-8-branch | |
Changes
Changes to generic/tclLoad.c.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | /* * tclLoad.c -- * * This file provides the generic portion (those that are the same on all * platforms) of Tcl's dynamic loading facilities. * * Copyright © 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. */ #include "tclInt.h" /* * The following structure describes a library that has been loaded either * dynamically (with the "load" command) or statically (as indicated by a call * to Tcl_StaticLibrary). All such libraries are linked together into a * single list for the process. Library are never unloaded, until the * application exits, when TclFinalizeLoad is called, and these structures are | > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | /* * tclLoad.c -- * * This file provides the generic portion (those that are the same on all * platforms) of Tcl's dynamic loading facilities. * * Copyright © 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. */ #include "tclInt.h" /* * The following structure describes a library that has been loaded either * dynamically (with the "load" command) or statically (as indicated by a call * to Tcl_StaticLibrary). All such libraries are linked together into a * single list for the process. Library are never unloaded, until the * application exits, when TclFinalizeLoad is called, and these structures are |
︙ | ︙ | |||
89 90 91 92 93 94 95 | * for end of list. */ } InterpLibrary; /* * Prototypes for functions that are private to this file: */ | | | > > > > | 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 | * for end of list. */ } InterpLibrary; /* * Prototypes for functions that are private to this file: */ static void LoadCleanupProc(ClientData clientData, Tcl_Interp *interp); static int UnloadLibrary(Tcl_Interp *interp, Tcl_Interp *target, LoadedLibrary *library, int keepLibrary, const char *fullFileName); /* *---------------------------------------------------------------------- * * Tcl_LoadObjCmd -- * * This function is invoked to process the "load" Tcl command. See the |
︙ | ︙ | |||
545 546 547 548 549 550 551 | Tcl_Interp *interp, /* Current interpreter. */ int objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* Argument objects. */ { Tcl_Interp *target; /* Which interpreter to unload from. */ LoadedLibrary *libraryPtr, *defaultPtr; Tcl_DString pfx, tmp; | < < | 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 | Tcl_Interp *interp, /* Current interpreter. */ int objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* Argument objects. */ { Tcl_Interp *target; /* Which interpreter to unload from. */ LoadedLibrary *libraryPtr, *defaultPtr; Tcl_DString pfx, tmp; InterpLibrary *ipFirstPtr, *ipPtr; int i, index, code, complain = 1, keepLibrary = 0; const char *fullFileName = ""; const char *prefix; static const char *const options[] = { "-nocomplain", "-keeplibrary", "--", NULL }; enum unloadOptionsEnum { UNLOAD_NOCOMPLAIN, UNLOAD_KEEPLIB, UNLOAD_LAST |
︙ | ︙ | |||
737 738 739 740 741 742 743 744 745 746 747 748 749 750 | fullFileName)); Tcl_SetErrorCode(interp, "TCL", "OPERATION", "UNLOAD", "NEVERLOADED", NULL); code = TCL_ERROR; goto done; } /* * Ensure that the DLL can be unloaded. If it is a trusted interpreter, * libraryPtr->unloadProc must not be NULL for the DLL to be unloadable. If * the interpreter is a safe one, libraryPtr->safeUnloadProc must be non-NULL. */ if (Tcl_IsSafe(target)) { | > > > > > > > > > > > > > > > > > > > > > > > > > > > | 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 | fullFileName)); Tcl_SetErrorCode(interp, "TCL", "OPERATION", "UNLOAD", "NEVERLOADED", NULL); code = TCL_ERROR; goto done; } code = UnloadLibrary(interp, target, libraryPtr, keepLibrary, fullFileName); done: Tcl_DStringFree(&pfx); Tcl_DStringFree(&tmp); if (!complain && (code != TCL_OK)) { code = TCL_OK; Tcl_ResetResult(interp); } return code; } static int UnloadLibrary( Tcl_Interp *interp, Tcl_Interp *target, LoadedLibrary *libraryPtr, int keepLibrary, const char *fullFileName ) { int code; InterpLibrary *ipFirstPtr, *ipPtr; LoadedLibrary *defaultPtr; int trustedRefCount, safeRefCount; Tcl_LibraryUnloadProc *unloadProc; /* * Ensure that the DLL can be unloaded. If it is a trusted interpreter, * libraryPtr->unloadProc must not be NULL for the DLL to be unloadable. If * the interpreter is a safe one, libraryPtr->safeUnloadProc must be non-NULL. */ if (Tcl_IsSafe(target)) { |
︙ | ︙ | |||
766 767 768 769 770 771 772 773 774 775 776 777 778 779 | Tcl_SetErrorCode(interp, "TCL", "OPERATION", "UNLOAD", "CANNOT", NULL); code = TCL_ERROR; goto done; } unloadProc = libraryPtr->unloadProc; } /* * We are ready to unload the library. First, evaluate the unload * function. If this fails, we cannot proceed with unload. Also, we must * specify the proper flag to pass to the unload callback. * TCL_UNLOAD_DETACH_FROM_INTERPRETER is defined when the callback should * only remove itself from the interpreter; the library will be unloaded | > > > | 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 | Tcl_SetErrorCode(interp, "TCL", "OPERATION", "UNLOAD", "CANNOT", NULL); code = TCL_ERROR; goto done; } unloadProc = libraryPtr->unloadProc; } /* * We are ready to unload the library. First, evaluate the unload * function. If this fails, we cannot proceed with unload. Also, we must * specify the proper flag to pass to the unload callback. * TCL_UNLOAD_DETACH_FROM_INTERPRETER is defined when the callback should * only remove itself from the interpreter; the library will be unloaded |
︙ | ︙ | |||
885 886 887 888 889 890 891 | ipPrevPtr = ipPtr, ipPtr = ipPtr->nextPtr) { if (ipPtr->libraryPtr == defaultPtr) { ipPrevPtr->nextPtr = ipPtr->nextPtr; break; } } } | | < < < < < < < | 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 | ipPrevPtr = ipPtr, ipPtr = ipPtr->nextPtr) { if (ipPtr->libraryPtr == defaultPtr) { ipPrevPtr->nextPtr = ipPtr->nextPtr; break; } } } Tcl_SetAssocData(target, "tclLoad", LoadCleanupProc, ipFirstPtr); ckfree(defaultPtr->fileName); ckfree(defaultPtr->prefix); ckfree(defaultPtr); ckfree(ipPtr); Tcl_MutexUnlock(&libraryMutex); } else { code = TCL_ERROR; } } #else Tcl_SetObjResult(interp, Tcl_ObjPrintf( "file \"%s\" cannot be unloaded: unloading disabled", fullFileName)); Tcl_SetErrorCode(interp, "TCL", "OPERATION", "UNLOAD", "DISABLED", NULL); code = TCL_ERROR; #endif } done: return code; } /* *---------------------------------------------------------------------- * * Tcl_StaticLibrary -- |
︙ | ︙ |