diff options
Diffstat (limited to 'unix/tclUnixNotfy.c')
| -rw-r--r-- | unix/tclUnixNotfy.c | 78 |
1 files changed, 67 insertions, 11 deletions
diff --git a/unix/tclUnixNotfy.c b/unix/tclUnixNotfy.c index 9f9301f..a8dbebe 100644 --- a/unix/tclUnixNotfy.c +++ b/unix/tclUnixNotfy.c @@ -1,5 +1,7 @@ +#define AT_FORK_INIT_VALUE 0 +#define RESET_ATFORK_MUTEX 1 /* - * tclUnixNotfy.c -- + * tclUnixNotify.c -- * * This file contains the implementation of the select()-based * Unix-specific notifier, which is the lowest-level part of the Tcl @@ -39,7 +41,7 @@ typedef struct FileHandler { * handlers are ready to fire. */ -typedef struct { +typedef struct FileHandlerEvent { Tcl_Event header; /* Information that is standard for all * events. */ int fd; /* File descriptor that is ready. Used to find @@ -54,7 +56,7 @@ typedef struct { * writable, and exception conditions. */ -typedef struct { +typedef struct SelectMasks { fd_set readable; fd_set writable; fd_set exception; @@ -150,8 +152,8 @@ static int triggerPipe = -1; * The notifierMutex locks access to all of the global notifier state. */ -pthread_mutex_t notifierInitMutex = PTHREAD_MUTEX_INITIALIZER; -pthread_mutex_t notifierMutex = PTHREAD_MUTEX_INITIALIZER; +static pthread_mutex_t notifierInitMutex = PTHREAD_MUTEX_INITIALIZER; +static pthread_mutex_t notifierMutex = PTHREAD_MUTEX_INITIALIZER; /* * The following static indicates if the notifier thread is running. * @@ -195,7 +197,9 @@ static Tcl_ThreadId notifierThread; #ifdef TCL_THREADS static void NotifierThreadProc(ClientData clientData); #if defined(HAVE_PTHREAD_ATFORK) -static int atForkInit = 0; +static int atForkInit = AT_FORK_INIT_VALUE; +static void AtForkPrepare(void); +static void AtForkParent(void); static void AtForkChild(void); #endif /* HAVE_PTHREAD_ATFORK */ #endif /* TCL_THREADS */ @@ -252,7 +256,7 @@ extern unsigned char __stdcall TranslateMessage(const MSG *); * Threaded-cygwin specific constants and functions in this file: */ -static const WCHAR className[] = L"TclNotifier"; +static const WCHAR NotfyClassName[] = L"TclNotifier"; static DWORD __stdcall NotifierProc(void *hwnd, unsigned int message, void *wParam, void *lParam); #endif /* TCL_THREADS && __CYGWIN__ */ @@ -341,7 +345,7 @@ Tcl_InitNotifier(void) class.hInstance = TclWinGetTclInstance(); class.hbrBackground = NULL; class.lpszMenuName = NULL; - class.lpszClassName = className; + class.lpszClassName = NotfyClassName; class.lpfnWndProc = NotifierProc; class.hIcon = NULL; class.hCursor = NULL; @@ -366,7 +370,7 @@ Tcl_InitNotifier(void) */ if (!atForkInit) { - int result = pthread_atfork(NULL, NULL, AtForkChild); + int result = pthread_atfork(AtForkPrepare, AtForkParent, AtForkChild); if (result) { Tcl_Panic("Tcl_InitNotifier: pthread_atfork failed"); @@ -1347,6 +1351,54 @@ NotifierThreadProc( /* *---------------------------------------------------------------------- * + * AtForkPrepare -- + * + * Lock the notifier in preparation for a fork. + * + * Results: + * None. + * + * Side effects: + * None. + * + *---------------------------------------------------------------------- + */ + +static void +AtForkPrepare(void) +{ +#if RESET_ATFORK_MUTEX == 0 + pthread_mutex_lock(¬ifierInitMutex); +#endif +} + +/* + *---------------------------------------------------------------------- + * + * AtForkParent -- + * + * Unlock the notifier in the parent after a fork. + * + * Results: + * None. + * + * Side effects: + * None. + * + *---------------------------------------------------------------------- + */ + +static void +AtForkParent(void) +{ +#if RESET_ATFORK_MUTEX == 0 + pthread_mutex_unlock(¬ifierInitMutex); +#endif +} + +/* + *---------------------------------------------------------------------- + * * AtForkChild -- * * Unlock and reinstall the notifier in the child after a fork. @@ -1366,8 +1418,12 @@ AtForkChild(void) if (notifierThreadRunning == 1) { pthread_cond_destroy(¬ifierCV); } +#if RESET_ATFORK_MUTEX == 0 + pthread_mutex_unlock(¬ifierInitMutex); +#else pthread_mutex_init(¬ifierInitMutex, NULL); pthread_mutex_init(¬ifierMutex, NULL); +#endif pthread_cond_init(¬ifierCV, NULL); /* @@ -1399,8 +1455,8 @@ AtForkChild(void) */ #ifdef __CYGWIN__ DestroyWindow(tsdPtr->hwnd); - tsdPtr->hwnd = CreateWindowExW(NULL, className, - className, 0, 0, 0, 0, 0, NULL, NULL, + tsdPtr->hwnd = CreateWindowExW(NULL, NotfyClassName, + NotfyClassName, 0, 0, 0, 0, 0, NULL, NULL, TclWinGetTclInstance(), NULL); ResetEvent(tsdPtr->event); #else |
