? P
? unix/.gdb_history
? unix/libtcl8.4g.dylib
Index: generic/tclEvent.c
===================================================================
RCS file: /cvsroot/tcl/tcl/generic/tclEvent.c,v
retrieving revision 1.28.2.13
diff -r1.28.2.13 tclEvent.c
964,965c964
<     ThreadSpecificData *tsdPtr =
< 	    (ThreadSpecificData *)TclThreadDataKeyGet(&dataKey);
---
>     ThreadSpecificData *tsdPtr;
966a966
>     tsdPtr = (ThreadSpecificData *)TclThreadDataKeyGet(&dataKey);
997,998c997,998
< 	/*
< 	 * Blow away all thread local storage blocks.
---
>     /*
>      * Blow away all thread local storage blocks.
1005c1005
< 	 */
---
>      */
1007c1007
< 	TclFinalizeThreadData();
---
>     TclFinalizeThreadData();
Index: generic/tclIO.c
===================================================================
RCS file: /cvsroot/tcl/tcl/generic/tclIO.c,v
retrieving revision 1.61.2.18
diff -r1.61.2.18 tclIO.c
188c188
<  *	Releases all resources used by this subsystem on a per-process 
---
>  *	Releases all resources used by this subsystem on a per-thread
209a210,214
>     /*
>      * Walk all channel state structures known to this thread and
>      * close corresponding channels.
>      */
> 
236a242
> 
237a244
> 
246a254
> 
247a256
> 
276a286
> 
280a291
> 
283c294,296
<    }
---
>     }
> 
>     TclpFinalizeSockets();
Index: generic/tclInt.h
===================================================================
RCS file: /cvsroot/tcl/tcl/generic/tclInt.h,v
retrieving revision 1.118.2.21
diff -r1.118.2.21 tclInt.h
1744a1745
> EXTERN void		TclpFinalizeSockets _ANSI_ARGS_((void));
Index: mac/tclMacSock.c
===================================================================
RCS file: /cvsroot/tcl/tcl/mac/Attic/tclMacSock.c,v
retrieving revision 1.14
diff -r1.14 tclMacSock.c
162d161
< static void		SocketExitHandler _ANSI_ARGS_((ClientData clientData));
369a369
> 	tsdPtr = TCL_TSD_INIT(&dataKey);
372d371
< 	Tcl_CreateThreadExitHandler(SocketExitHandler, (ClientData) NULL);
379c378
<  * SocketExitHandler --
---
>  * TclpFinalizeSockets --
381,382c380
<  *	Callback invoked during exit clean up to deinitialize the
<  *	socket module.
---
>  *	Invoked during exit clean up to deinitialize the socket module.
388c386
<  *	None.
---
>  *	Removed event source.
393,395c391,392
< static void
< SocketExitHandler(
<     ClientData clientData)              /* Not used. */
---
> void
> TclpFinalizeSockets()
397c394,397
<     if (hasSockets) {
---
>     ThreadSpecificData *tsdPtr;
> 
>     tsdPtr = (ThreadSpecificData *)TclThreadDataKeyGet(&dataKey);
>     if (tsdPtr != NULL) {
399,400d398
< 	/* CleanUpExitProc();
< 	TclMacDeleteExitToShellPatch(CleanUpExitProc); */
Index: unix/tclUnixPipe.c
===================================================================
RCS file: /cvsroot/tcl/tcl/unix/tclUnixPipe.c,v
retrieving revision 1.23.2.5
diff -r1.23.2.5 tclUnixPipe.c
1261c1261,1262
<  * This procedure carries out no operation on Unix.
---
>  * Side effects:
>  * 	None.	
1268a1270
>     return;
Index: unix/tclUnixSock.c
===================================================================
RCS file: /cvsroot/tcl/tcl/unix/tclUnixSock.c,v
retrieving revision 1.6
diff -r1.6 tclUnixSock.c
150a151,172
> 
> /*
>  *----------------------------------------------------------------------
>  *
>  * TclpFinalizeSockets --
>  *
>  *	Performs per-thread socket subsystem finalization.
>  *
>  * Results:
>  *	None.
>  *
>  * Side effects:
>  *	None.
>  *
>  *----------------------------------------------------------------------
>  */
> 
> void
> TclpFinalizeSockets()
> {
>     return;
> }
Index: win/tclWinPipe.c
===================================================================
RCS file: /cvsroot/tcl/tcl/win/tclWinPipe.c,v
retrieving revision 1.33.2.15
diff -r1.33.2.15 tclWinPipe.c
192d191
< static void		PipeExitHandler(ClientData clientData);
274d272
< 	Tcl_CreateThreadExitHandler(PipeExitHandler, NULL);
281,304d278
<  * PipeExitHandler --
<  *
<  *	This function is called to cleanup the pipe module before
<  *	Tcl is unloaded.
<  *
<  * Results:
<  *	None.
<  *
<  * Side effects:
<  *	Removes the pipe event source.
<  *
<  *----------------------------------------------------------------------
<  */
< 
< static void
< PipeExitHandler(
<     ClientData clientData)	/* Old window proc */
< {
<     Tcl_DeleteEventSource(PipeSetupProc, PipeCheckProc, NULL);
< }
< 
< /*
<  *----------------------------------------------------------------------
<  *
307,308c281,282
<  *	This function is called to cleanup the process list before
<  *	Tcl is unloaded.
---
>  *	This function is called from Tcl_FinalizeThread to finalize the 
>  *	platform specific pipe subsystem.
314c288
<  *	Resets the process list.
---
>  *	Removes the pipe event source.
321,324c295,301
< {
<     Tcl_MutexLock(&pipeMutex);
<     initialized = 0;
<     Tcl_MutexUnlock(&pipeMutex);
---
> {    
>     ThreadSpecificData *tsdPtr;
> 
>     tsdPtr = (ThreadSpecificData *)TclThreadDataKeyGet(&dataKey);
>     if (tsdPtr != NULL) {
> 	Tcl_DeleteEventSource(PipeSetupProc, PipeCheckProc, NULL);
>     }
Index: win/tclWinSock.c
===================================================================
RCS file: /cvsroot/tcl/tcl/win/tclWinSock.c,v
retrieving revision 1.36.2.4
diff -r1.36.2.4 tclWinSock.c
252d251
< static Tcl_ExitProc	    SocketThreadExitHandler;
306c305
<  *	Assumes Mutex is held.
---
>  *	Assumes socketMutex is held.
494,497c493,494
< 	tsdPtr->hwnd = NULL;
< 
< 	tsdPtr->threadId = Tcl_GetCurrentThread();
< 	
---
> 	tsdPtr->hwnd       = NULL;
> 	tsdPtr->threadId   = Tcl_GetCurrentThread();
498a496,498
> 	if (tsdPtr->readyEvent == NULL) {
> 	    goto unloadLibrary;
> 	}
499a500,502
> 	if (tsdPtr->socketListLock == NULL) {
> 	    goto unloadLibrary;
> 	}
502,503d504
< 	SetThreadPriority(tsdPtr->socketThread, THREAD_PRIORITY_HIGHEST);
< 
507c508,509
< 	
---
> 
> 	SetThreadPriority(tsdPtr->socketThread, THREAD_PRIORITY_HIGHEST);
510,512c512,513
< 	 * Wait for the thread to signal that the window has
< 	 * been created and is ready to go.  Timeout after twenty
< 	 * seconds.
---
> 	 * Wait for the thread to signal when the window has
> 	 * been created and if it is ready to go.
514,518c515,516
< 	
< 	if (WaitForSingleObject(tsdPtr->readyEvent, 20000)
< 		== WAIT_TIMEOUT) {
< 	    goto unloadLibrary;
< 	}
---
> 
> 	WaitForSingleObject(tsdPtr->readyEvent, INFINITE);
521c519
< 	    goto unloadLibrary;
---
> 	    goto unloadLibrary; /* Trouble creating the window */
523c521
< 	
---
> 
525d522
< 	Tcl_CreateThreadExitHandler(SocketThreadExitHandler, NULL);
530,532c527
<     if (tsdPtr != NULL && tsdPtr->hwnd != NULL) {
< 	SocketThreadExitHandler(0);
<     }
---
>     TclpFinalizeSockets();
571c566
<  *	Callback invoked during exit clean up to delete the socket
---
>  *	Callback invoked during app exit clean up to delete the socket
594c589
< 	SocketThreadExitHandler(clientData);
---
> 	TclpFinalizeSockets();
608c603
<  * SocketThreadExitHandler --
---
>  * TclpFinalizeSockets --
610,611c605,608
<  *	Callback invoked during thread clean up to delete the socket
<  *	event source.
---
>  *	This function is called from Tcl_FinalizeThread to finalize
>  *	the platform specific socket subsystem.
>  *	Also, it may be called from within this module to cleanup
>  *	the state if unable to initialize the sockets subsystem.
617c614
<  *	Delete the event source.
---
>  *	Deletes the event source and destroys the socket thread.
622,625c619,620
<     /* ARGSUSED */
< static void
< SocketThreadExitHandler(clientData)
<     ClientData clientData;              /* Not used. */
---
> void
> TclpFinalizeSockets()
627,641c622
<     ThreadSpecificData *tsdPtr = 
< 	(ThreadSpecificData *)TclThreadDataKeyGet(&dataKey);
< 
<     if (tsdPtr != NULL && tsdPtr->socketThread != NULL) {
< 	DWORD exitCode;
< 
< 	GetExitCodeThread(tsdPtr->socketThread, &exitCode);
< 	if (exitCode == STILL_ACTIVE) {
< 	    PostMessage(tsdPtr->hwnd, SOCKET_TERMINATE, 0, 0);
< 	    /*
< 	     * Wait for the thread to close.  This ensures that we are
< 	     * completely cleaned up before we leave this function.
< 	     * If Tcl_Finalize was called from DllMain, the thread
< 	     * is in a paused state so we need to timeout and continue.
< 	     */
---
>     ThreadSpecificData *tsdPtr;
643c624,645
< 	    WaitForSingleObject(tsdPtr->socketThread, 100);
---
>     tsdPtr = (ThreadSpecificData *)TclThreadDataKeyGet(&dataKey);
>     if (tsdPtr != NULL) {
> 	if (tsdPtr->socketThread != NULL) {
> 	    if (tsdPtr->hwnd != NULL) {
> 		PostMessage(tsdPtr->hwnd, SOCKET_TERMINATE, 0, 0);
> 		/*
> 		 * Wait for the thread to exit. This ensures that we are
> 		 * completely cleaned up before we leave this function.
> 		 */
> 		WaitForSingleObject(tsdPtr->readyEvent, INFINITE);
> 		tsdPtr->hwnd = NULL;
> 	    }
> 	    CloseHandle(tsdPtr->socketThread);
> 	    tsdPtr->socketThread = NULL;
> 	}
> 	if (tsdPtr->readyEvent != NULL) {
> 	    CloseHandle(tsdPtr->readyEvent);
> 	    tsdPtr->readyEvent = NULL;
> 	}
> 	if (tsdPtr->socketListLock != NULL) {
> 	    CloseHandle(tsdPtr->socketListLock);
> 	    tsdPtr->socketListLock = NULL;
645,650d646
< 	CloseHandle(tsdPtr->socketThread);
< 	tsdPtr->socketThread = NULL;
< 	CloseHandle(tsdPtr->readyEvent);
< 	CloseHandle(tsdPtr->socketListLock);
< 
< 	Tcl_DeleteThreadExitHandler(SocketThreadExitHandler, NULL);
1036d1031
<     ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
2326a2322,2325
>     /*
>      * Create a dummy window receiving socket events.
>      */
> 
2331,2332c2330
<      * Signal the main thread that the window has been created
<      * and that the socket thread is ready to go.
---
>      * Signalize thread creator that we are done creating the window.
2334c2332
<     
---
> 
2336c2334,2338
<     
---
> 
>     /*
>      * If unable to create the window, exit this thread immediately.
>      */
> 
2338c2340
< 	return 1;
---
>         return 1;
2342a2345,2346
>      * This threads exits only when istructed to do so by the
>      * call to PostMessage(SOCKET_TERMINATE) in TclpFinalizeSockets().
2348a2353,2358
>     /*
>      * This releases waiters on thread exit in TclpFinalizeSockets()
>      */
> 
>     SetEvent(tsdPtr->readyEvent);
> 
2706c2716
<         SocketInfo **nextPtrPtr;
---
> 	SocketInfo **nextPtrPtr;
