From e8eb91c8acb09e341223b15de621f7ef1c8131f9 Mon Sep 17 00:00:00 2001 From: hobbs Date: Fri, 1 Aug 2008 18:22:27 +0000 Subject: * doc/Exit.3: do not call Tcl_Finalize implicitly * generic/tclEvent.c: on DLL_PROCESS_DETACH as it may lead * win/tclWin32Dll.c (DllMain): to issues and the user should be explicitly calling Tcl_Finalize before unloading regardless. Clarify the docs to note the explicit need in embedded use. --- ChangeLog | 8 ++++ doc/Exit.3 | 10 ++--- generic/tclEvent.c | 7 ++-- win/tclWin32Dll.c | 107 ++--------------------------------------------------- 4 files changed, 19 insertions(+), 113 deletions(-) diff --git a/ChangeLog b/ChangeLog index c8efe8e..617788e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +2008-08-01 Jeff Hobbs + + * doc/Exit.3: do not call Tcl_Finalize implicitly + * generic/tclEvent.c: on DLL_PROCESS_DETACH as it may lead + * win/tclWin32Dll.c (DllMain): to issues and the user should be + explicitly calling Tcl_Finalize before unloading regardless. + Clarify the docs to note the explicit need in embedded use. + 2008-08-01 Don Porter * generic/tclBasic.c: Revised timing of the CmdFrame stack management diff --git a/doc/Exit.3 b/doc/Exit.3 index 082802c..61fb222 100644 --- a/doc/Exit.3 +++ b/doc/Exit.3 @@ -4,7 +4,7 @@ '\" See the file "license.terms" for information on usage and redistribution '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES. '\" -'\" RCS: @(#) $Id: Exit.3,v 1.7 2008/06/29 22:28:24 dkf Exp $ +'\" RCS: @(#) $Id: Exit.3,v 1.8 2008/08/01 18:22:29 hobbs Exp $ '\" .so man.macros .TH Tcl_Exit 3 8.5 Tcl "Tcl Library Procedures" @@ -74,12 +74,8 @@ exit from the current process. It is useful for cleaning up when a process is finished using \fBTcl\fR but wishes to continue executing, and when \fBTcl\fR is used in a dynamically loaded extension that is about to be unloaded. -On some systems \fBTcl\fR is automatically notified when it is being -unloaded, and it calls \fBTcl_Finalize\fR internally; on these systems it -not necessary for the caller to explicitly call \fBTcl_Finalize\fR. -However, to ensure portability, your code should always invoke -\fBTcl_Finalize\fR when \fBTcl\fR is being unloaded, to ensure that the -code will work on all platforms. \fBTcl_Finalize\fR can be safely called +Your code should always invoke \fBTcl_Finalize\fR when \fBTcl\fR is being +unloaded, to ensure proper cleanup. \fBTcl_Finalize\fR can be safely called more than once. .PP \fBTcl_ExitThread\fR is used to terminate the current thread and invoke diff --git a/generic/tclEvent.c b/generic/tclEvent.c index 836d958..9e38f24 100644 --- a/generic/tclEvent.c +++ b/generic/tclEvent.c @@ -12,7 +12,7 @@ * See the file "license.terms" for information on usage and redistribution of * this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tclEvent.c,v 1.82 2008/06/13 05:45:10 mistachkin Exp $ + * RCS: @(#) $Id: tclEvent.c,v 1.83 2008/08/01 18:22:28 hobbs Exp $ */ #include "tclInt.h" @@ -914,8 +914,9 @@ TclInitSubsystems(void) * Tcl_Finalize -- * * Shut down Tcl. First calls registered exit handlers, then carefully - * shuts down various subsystems. Called by Tcl_Exit or when the Tcl - * shared library is being unloaded. + * shuts down various subsystems. Called by Tcl_Exit, or should be + * invoked by user before the Tcl shared library is being unloaded in + * an embedded context. * * Results: * None. diff --git a/win/tclWin32Dll.c b/win/tclWin32Dll.c index 6120c67..ac04198 100644 --- a/win/tclWin32Dll.c +++ b/win/tclWin32Dll.c @@ -10,7 +10,7 @@ * See the file "license.terms" for information on usage and redistribution of * this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tclWin32Dll.c,v 1.56 2008/07/13 09:03:41 msofer Exp $ + * RCS: @(#) $Id: tclWin32Dll.c,v 1.57 2008/08/01 18:22:29 hobbs Exp $ */ #include "tclWinInt.h" @@ -188,23 +188,12 @@ static TclWinProcs unicodeProcs = { TclWinProcs *tclWinProcs; static Tcl_Encoding tclWinTCharEncoding; -#ifdef HAVE_NO_SEH -/* - * Need to add noinline flag to DllMain declaration so that gcc -O3 does not - * inline asm code into DllEntryPoint and cause a compile time error because - * of redefined local labels. - */ - -BOOL APIENTRY DllMain(HINSTANCE hInst, DWORD reason, - LPVOID reserved) __attribute__ ((noinline)); -#else /* * The following declaration is for the VC++ DLL entry point. */ BOOL APIENTRY DllMain(HINSTANCE hInst, DWORD reason, LPVOID reserved); -#endif /* HAVE_NO_SEH */ /* * The following structure and linked list is to allow us to map between @@ -277,10 +266,7 @@ DllEntryPoint( * TRUE on sucess, FALSE on failure. * * Side effects: - * Establishes 32-to-16 bit thunk and initializes sockets library. This - * might call some sycronization functions, but MSDN documentation - * states: "Waiting on synchronization objects in DllMain can cause a - * deadlock." + * Initializes most rudimentary Windows bits. * *---------------------------------------------------------------------- */ @@ -291,101 +277,16 @@ DllMain( DWORD reason, /* Reason this function is being called. */ LPVOID reserved) /* Not used. */ { -#ifdef HAVE_NO_SEH - EXCEPTION_REGISTRATION registration; -#endif - switch (reason) { case DLL_PROCESS_ATTACH: DisableThreadLibraryCalls(hInst); TclWinInit(hInst); return TRUE; - case DLL_PROCESS_DETACH: /* - * Protect the call to Tcl_Finalize. The OS could be unloading us from - * an exception handler and the state of the stack might be unstable. + * DLL_PROCESS_DETACH is unnecessary as the user should call + * Tcl_Finalize explicitly before unloading Tcl. */ - -#ifdef HAVE_NO_SEH - __asm__ __volatile__ ( - - /* - * Construct an EXCEPTION_REGISTRATION to protect the call to - * Tcl_Finalize - */ - - "leal %[registration], %%edx" "\n\t" - "movl %%fs:0, %%eax" "\n\t" - "movl %%eax, 0x0(%%edx)" "\n\t" /* link */ - "leal 1f, %%eax" "\n\t" - "movl %%eax, 0x4(%%edx)" "\n\t" /* handler */ - "movl %%ebp, 0x8(%%edx)" "\n\t" /* ebp */ - "movl %%esp, 0xc(%%edx)" "\n\t" /* esp */ - "movl %[error], 0x10(%%edx)" "\n\t" /* status */ - - /* - * Link the EXCEPTION_REGISTRATION on the chain - */ - - "movl %%edx, %%fs:0" "\n\t" - - /* - * Call Tcl_Finalize - */ - - "call _Tcl_Finalize" "\n\t" - - /* - * Come here on a normal exit. Recover the EXCEPTION_REGISTRATION - * and store a TCL_OK status - */ - - "movl %%fs:0, %%edx" "\n\t" - "movl %[ok], %%eax" "\n\t" - "movl %%eax, 0x10(%%edx)" "\n\t" - "jmp 2f" "\n" - - /* - * Come here on an exception. Get the EXCEPTION_REGISTRATION that - * we previously put on the chain. - */ - - "1:" "\t" - "movl %%fs:0, %%edx" "\n\t" - "movl 0x8(%%edx), %%edx" "\n" - - - /* - * Come here however we exited. Restore context from the - * EXCEPTION_REGISTRATION in case the stack is unbalanced. - */ - - "2:" "\t" - "movl 0xc(%%edx), %%esp" "\n\t" - "movl 0x8(%%edx), %%ebp" "\n\t" - "movl 0x0(%%edx), %%eax" "\n\t" - "movl %%eax, %%fs:0" "\n\t" - - : - /* No outputs */ - : - [registration] "m" (registration), - [ok] "i" (TCL_OK), - [error] "i" (TCL_ERROR) - : - "%eax", "%ebx", "%ecx", "%edx", "%esi", "%edi", "memory" - ); - -#else /* HAVE_NO_SEH */ - __try { - Tcl_Finalize(); - } __except (EXCEPTION_EXECUTE_HANDLER) { - /* empty handler body. */ - } -#endif - - break; } return TRUE; -- cgit v0.12