Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | improve POSIX signal handling without blocking signals on all threads, only the notifier thread is special, and the design should be able to support a similar approach for epoll/kqueue notifiers. |
---|---|
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
40790af1e8e4ec9f41a90d04f966db95 |
User & Date: | chw 2018-06-13 22:04:35 |
Context
2018-06-15
| ||
07:41 | in tkvnc use poll(2) if available check-in: 948056bf95 user: chw tags: trunk | |
2018-06-13
| ||
22:04 | improve POSIX signal handling without blocking signals on all threads, only the notifier thread is special, and the design should be able to support a similar approach for epoll/kqueue notifiers. check-in: 40790af1e8 user: chw tags: trunk | |
11:06 | update tclws to version 2.6.0 check-in: c3a47e6bef user: chw tags: trunk | |
Changes
Changes to jni/tcl/doc/Async.3.
1 2 3 4 5 6 7 8 9 10 11 | '\" '\" Copyright (c) 1989-1993 The Regents of the University of California. '\" Copyright (c) 1994-1996 Sun Microsystems, Inc. '\" '\" See the file "license.terms" for information on usage and redistribution '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES. '\" .TH Tcl_AsyncCreate 3 7.0 Tcl "Tcl Library Procedures" .so man.macros .BS .SH NAME | | > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 | '\" '\" Copyright (c) 1989-1993 The Regents of the University of California. '\" Copyright (c) 1994-1996 Sun Microsystems, Inc. '\" '\" See the file "license.terms" for information on usage and redistribution '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES. '\" .TH Tcl_AsyncCreate 3 7.0 Tcl "Tcl Library Procedures" .so man.macros .BS .SH NAME Tcl_AsyncCreate, Tcl_AsyncMark, Tcl_AsyncMarkFromSignal, Tcl_AsyncInvoke, Tcl_AsyncDelete, Tcl_AsyncReady \- handle asynchronous events .SH SYNOPSIS .nf \fB#include <tcl.h>\fR .sp Tcl_AsyncHandler \fBTcl_AsyncCreate\fR(\fIproc, clientData\fR) .sp \fBTcl_AsyncMark\fR(\fIasync\fR) .sp \fBTcl_AsyncMarkFromSignal\fR(\fIasync, sigNumber\fR) .sp int \fBTcl_AsyncInvoke\fR(\fIinterp, code\fR) .sp \fBTcl_AsyncDelete\fR(\fIasync\fR) .sp int \fBTcl_AsyncReady\fR() .SH ARGUMENTS .AS Tcl_AsyncHandler clientData .AP Tcl_AsyncProc *proc in Procedure to invoke to handle an asynchronous event. .AP ClientData clientData in One-word value to pass to \fIproc\fR. .AP Tcl_AsyncHandler async in Token for asynchronous event handler. .AP int sigNumber in POSIX signal number, when used in a signal context. .AP Tcl_Interp *interp in Tcl interpreter in which command was being evaluated when handler was invoked, or NULL if handler was invoked when there was no interpreter active. .AP int code in Completion code from command that just completed in \fIinterp\fR, or 0 if \fIinterp\fR is NULL. |
︙ | ︙ | |||
56 57 58 59 60 61 62 | allocation could have been in progress when the event occurred. The only safe approach is to set a flag indicating that the event occurred, then handle the event later when the world has returned to a clean state, such as after the current Tcl command completes. .PP \fBTcl_AsyncCreate\fR, \fBTcl_AsyncDelete\fR, and \fBTcl_AsyncReady\fR are thread sensitive. They access and/or set a thread-specific data | | | | > | | | | > | | | | | 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 | allocation could have been in progress when the event occurred. The only safe approach is to set a flag indicating that the event occurred, then handle the event later when the world has returned to a clean state, such as after the current Tcl command completes. .PP \fBTcl_AsyncCreate\fR, \fBTcl_AsyncDelete\fR, and \fBTcl_AsyncReady\fR are thread sensitive. They access and/or set a thread-specific data structure in the event of a core built with \fI\-\-enable\-threads\fR. The token created by \fBTcl_AsyncCreate\fR contains the needed thread information it was called from so that calling \fBTcl_AsyncMarkFromSignal\fR or \fBTcl_AsyncMark\fR with this token will only yield the origin thread into the asynchronous handler. .PP \fBTcl_AsyncCreate\fR creates an asynchronous handler and returns a token for it. The asynchronous handler must be created before any occurrences of the asynchronous event that it is intended to handle (it is not safe to create a handler at the time of an event). When an asynchronous event occurs the code that detects the event (such as a POSIX signal handler) should call \fBTcl_AsyncMarkFromSignal\fR with the token for the handler and the POSIX signal number. For non-signal contexts, \fBTcl_AsyncMark\fR serves the same purpose. \fBTcl_AsyncMarkFromSignal\fR and \fBTcl_AsyncMark\fR will mark the handler as ready to execute, but will not invoke the handler immediately. Tcl will call the \fIproc\fR associated with the handler later, when the world is in a safe state, and \fIproc\fR can then carry out the actions associated with the asynchronous event. \fIProc\fR should have arguments and result that match the type \fBTcl_AsyncProc\fR: .PP .CS typedef int \fBTcl_AsyncProc\fR( ClientData \fIclientData\fR, Tcl_Interp *\fIinterp\fR, |
︙ | ︙ |
Changes to jni/tcl/generic/tcl.decls.
︙ | ︙ | |||
2318 2319 2320 2321 2322 2323 2324 2325 2326 2327 2328 2329 2330 2331 | } # TIP #400 declare 630 { void Tcl_ZlibStreamSetCompressionDictionary(Tcl_ZlibStream zhandle, Tcl_Obj *compressionDictionaryObj) } # ----- BASELINE -- FOR -- 8.6.0 ----- # ############################################################################## # Define the platform specific public Tcl interface. These functions are only # available on the designated platform. | > > > > | 2318 2319 2320 2321 2322 2323 2324 2325 2326 2327 2328 2329 2330 2331 2332 2333 2334 2335 | } # TIP #400 declare 630 { void Tcl_ZlibStreamSetCompressionDictionary(Tcl_ZlibStream zhandle, Tcl_Obj *compressionDictionaryObj) } declare 631 { void Tcl_AsyncMarkFromSignal(Tcl_AsyncHandler async, int sigNumber) } # ----- BASELINE -- FOR -- 8.6.0 ----- # ############################################################################## # Define the platform specific public Tcl interface. These functions are only # available on the designated platform. |
︙ | ︙ |
Changes to jni/tcl/generic/tclAsync.c.
︙ | ︙ | |||
188 189 190 191 192 193 194 | void Tcl_AsyncMark( Tcl_AsyncHandler async) /* Token for handler. */ { AsyncHandler *token = (AsyncHandler *) async; | < < < > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 | void Tcl_AsyncMark( Tcl_AsyncHandler async) /* Token for handler. */ { AsyncHandler *token = (AsyncHandler *) async; Tcl_MutexLock(&asyncMutex); token->ready = 1; if (!token->originTsd->asyncActive) { token->originTsd->asyncReady = 1; Tcl_ThreadAlert(token->originThrdId); } Tcl_MutexUnlock(&asyncMutex); } /* *---------------------------------------------------------------------- * * Tcl_AsyncMarkFromSignal -- * * This procedure is similar to Tcl_AsyncMark but must be used * in POSIX signal contexts. In addition to Tcl_AsyncMark the * signal number is passed. * * Results: * None. * * Side effects: * The handler gets marked for invocation later. * *---------------------------------------------------------------------- */ void Tcl_AsyncMarkFromSignal( Tcl_AsyncHandler async, /* Token for handler. */ int sigNumber) /* Signal number. */ { #ifdef TCL_THREADS AsyncHandler *token = (AsyncHandler *) async; TclAsyncNotifier(sigNumber, token->originThrdId, &token->ready, -1); #else Tcl_AsyncMark(async); #endif } /* *---------------------------------------------------------------------- * * TclAsyncMarkFromNotifier -- * * This procedure is called from the notifier thread and |
︙ | ︙ |
Changes to jni/tcl/generic/tclDecls.h.
︙ | ︙ | |||
1812 1813 1814 1815 1816 1817 1818 1819 1820 1821 1822 1823 1824 1825 | /* 629 */ EXTERN int Tcl_FSUnloadFile(Tcl_Interp *interp, Tcl_LoadHandle handlePtr); /* 630 */ EXTERN void Tcl_ZlibStreamSetCompressionDictionary( Tcl_ZlibStream zhandle, Tcl_Obj *compressionDictionaryObj); typedef struct { const struct TclPlatStubs *tclPlatStubs; const struct TclIntStubs *tclIntStubs; const struct TclIntPlatStubs *tclIntPlatStubs; } TclStubHooks; | > > > | 1812 1813 1814 1815 1816 1817 1818 1819 1820 1821 1822 1823 1824 1825 1826 1827 1828 | /* 629 */ EXTERN int Tcl_FSUnloadFile(Tcl_Interp *interp, Tcl_LoadHandle handlePtr); /* 630 */ EXTERN void Tcl_ZlibStreamSetCompressionDictionary( Tcl_ZlibStream zhandle, Tcl_Obj *compressionDictionaryObj); /* 631 */ EXTERN void Tcl_AsyncMarkFromSignal( Tcl_AsyncHandler async, int sigNumber); typedef struct { const struct TclPlatStubs *tclPlatStubs; const struct TclIntStubs *tclIntStubs; const struct TclIntPlatStubs *tclIntPlatStubs; } TclStubHooks; |
︙ | ︙ | |||
2478 2479 2480 2481 2482 2483 2484 2485 2486 2487 2488 2489 2490 2491 | int (*tcl_CloseEx) (Tcl_Interp *interp, Tcl_Channel chan, int flags); /* 624 */ int (*tcl_NRExprObj) (Tcl_Interp *interp, Tcl_Obj *objPtr, Tcl_Obj *resultPtr); /* 625 */ int (*tcl_NRSubstObj) (Tcl_Interp *interp, Tcl_Obj *objPtr, int flags); /* 626 */ int (*tcl_LoadFile) (Tcl_Interp *interp, Tcl_Obj *pathPtr, const char *const symv[], int flags, void *procPtrs, Tcl_LoadHandle *handlePtr); /* 627 */ void * (*tcl_FindSymbol) (Tcl_Interp *interp, Tcl_LoadHandle handle, const char *symbol); /* 628 */ int (*tcl_FSUnloadFile) (Tcl_Interp *interp, Tcl_LoadHandle handlePtr); /* 629 */ void (*tcl_ZlibStreamSetCompressionDictionary) (Tcl_ZlibStream zhandle, Tcl_Obj *compressionDictionaryObj); /* 630 */ } TclStubs; extern const TclStubs *tclStubsPtr; #ifdef __cplusplus } #endif | > | 2481 2482 2483 2484 2485 2486 2487 2488 2489 2490 2491 2492 2493 2494 2495 | int (*tcl_CloseEx) (Tcl_Interp *interp, Tcl_Channel chan, int flags); /* 624 */ int (*tcl_NRExprObj) (Tcl_Interp *interp, Tcl_Obj *objPtr, Tcl_Obj *resultPtr); /* 625 */ int (*tcl_NRSubstObj) (Tcl_Interp *interp, Tcl_Obj *objPtr, int flags); /* 626 */ int (*tcl_LoadFile) (Tcl_Interp *interp, Tcl_Obj *pathPtr, const char *const symv[], int flags, void *procPtrs, Tcl_LoadHandle *handlePtr); /* 627 */ void * (*tcl_FindSymbol) (Tcl_Interp *interp, Tcl_LoadHandle handle, const char *symbol); /* 628 */ int (*tcl_FSUnloadFile) (Tcl_Interp *interp, Tcl_LoadHandle handlePtr); /* 629 */ void (*tcl_ZlibStreamSetCompressionDictionary) (Tcl_ZlibStream zhandle, Tcl_Obj *compressionDictionaryObj); /* 630 */ void (*tcl_AsyncMarkFromSignal) (Tcl_AsyncHandler async, int sigNumber); /* 631 */ } TclStubs; extern const TclStubs *tclStubsPtr; #ifdef __cplusplus } #endif |
︙ | ︙ | |||
3770 3771 3772 3773 3774 3775 3776 3777 3778 3779 3780 3781 3782 3783 | (tclStubsPtr->tcl_LoadFile) /* 627 */ #define Tcl_FindSymbol \ (tclStubsPtr->tcl_FindSymbol) /* 628 */ #define Tcl_FSUnloadFile \ (tclStubsPtr->tcl_FSUnloadFile) /* 629 */ #define Tcl_ZlibStreamSetCompressionDictionary \ (tclStubsPtr->tcl_ZlibStreamSetCompressionDictionary) /* 630 */ #endif /* defined(USE_TCL_STUBS) */ /* !END!: Do not edit above this line. */ #if defined(USE_TCL_STUBS) # undef Tcl_CreateInterp | > > | 3774 3775 3776 3777 3778 3779 3780 3781 3782 3783 3784 3785 3786 3787 3788 3789 | (tclStubsPtr->tcl_LoadFile) /* 627 */ #define Tcl_FindSymbol \ (tclStubsPtr->tcl_FindSymbol) /* 628 */ #define Tcl_FSUnloadFile \ (tclStubsPtr->tcl_FSUnloadFile) /* 629 */ #define Tcl_ZlibStreamSetCompressionDictionary \ (tclStubsPtr->tcl_ZlibStreamSetCompressionDictionary) /* 630 */ #define Tcl_AsyncMarkFromSignal \ (tclStubsPtr->tcl_AsyncMarkFromSignal) /* 631 */ #endif /* defined(USE_TCL_STUBS) */ /* !END!: Do not edit above this line. */ #if defined(USE_TCL_STUBS) # undef Tcl_CreateInterp |
︙ | ︙ |
Changes to jni/tcl/generic/tclInt.decls.
︙ | ︙ | |||
1283 1284 1285 1286 1287 1288 1289 | declare 30 {win unix} { int TclUnixOpenTemporaryFile(Tcl_Obj *dirObj, Tcl_Obj *basenameObj, Tcl_Obj *extensionObj, Tcl_Obj *resultingNameObj) } # TIP#302 ??? declare 31 {win unix macosx} { int TclpGetMonotonicTime(Tcl_Time *timePtr) | < < < | 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 | declare 30 {win unix} { int TclUnixOpenTemporaryFile(Tcl_Obj *dirObj, Tcl_Obj *basenameObj, Tcl_Obj *extensionObj, Tcl_Obj *resultingNameObj) } # TIP#302 ??? declare 31 {win unix macosx} { int TclpGetMonotonicTime(Tcl_Time *timePtr) } # Local Variables: # mode: tcl # End: |
Changes to jni/tcl/generic/tclInt.h.
︙ | ︙ | |||
2864 2865 2866 2867 2868 2869 2870 | MODULE_SCOPE void TclArgumentBCEnter(Tcl_Interp *interp, Tcl_Obj *objv[], int objc, void *codePtr, CmdFrame *cfPtr, int cmd, int pc); MODULE_SCOPE void TclArgumentBCRelease(Tcl_Interp *interp, CmdFrame *cfPtr); MODULE_SCOPE void TclArgumentGet(Tcl_Interp *interp, Tcl_Obj *obj, CmdFrame **cfPtrPtr, int *wordPtr); | > | | 2864 2865 2866 2867 2868 2869 2870 2871 2872 2873 2874 2875 2876 2877 2878 2879 | MODULE_SCOPE void TclArgumentBCEnter(Tcl_Interp *interp, Tcl_Obj *objv[], int objc, void *codePtr, CmdFrame *cfPtr, int cmd, int pc); MODULE_SCOPE void TclArgumentBCRelease(Tcl_Interp *interp, CmdFrame *cfPtr); MODULE_SCOPE void TclArgumentGet(Tcl_Interp *interp, Tcl_Obj *obj, CmdFrame **cfPtrPtr, int *wordPtr); MODULE_SCOPE void TclAsyncNotifier(int sigNumber, Tcl_ThreadId threadId, int *flagPtr, int value); MODULE_SCOPE void TclAsyncMarkFromNotifier(void); MODULE_SCOPE double TclBignumToDouble(const mp_int *bignum); MODULE_SCOPE int TclByteArrayMatch(const unsigned char *string, int strLen, const unsigned char *pattern, int ptnLen, int flags); MODULE_SCOPE double TclCeil(const mp_int *a); MODULE_SCOPE void TclChannelPreserve(Tcl_Channel chan); |
︙ | ︙ |
Changes to jni/tcl/generic/tclIntPlatDecls.h.
︙ | ︙ | |||
94 95 96 97 98 99 100 | EXTERN int TclWinCPUID(unsigned int index, unsigned int *regs); /* 30 */ EXTERN int TclUnixOpenTemporaryFile(Tcl_Obj *dirObj, Tcl_Obj *basenameObj, Tcl_Obj *extensionObj, Tcl_Obj *resultingNameObj); /* 31 */ EXTERN int TclpGetMonotonicTime(Tcl_Time *timePtr); | < < | 94 95 96 97 98 99 100 101 102 103 104 105 106 107 | EXTERN int TclWinCPUID(unsigned int index, unsigned int *regs); /* 30 */ EXTERN int TclUnixOpenTemporaryFile(Tcl_Obj *dirObj, Tcl_Obj *basenameObj, Tcl_Obj *extensionObj, Tcl_Obj *resultingNameObj); /* 31 */ EXTERN int TclpGetMonotonicTime(Tcl_Time *timePtr); #endif /* UNIX */ #if defined(_WIN32) || defined(__CYGWIN__) /* WIN */ /* 0 */ EXTERN void TclWinConvertError(DWORD errCode); /* 1 */ EXTERN void TclWinConvertWSAError(DWORD errCode); /* 2 */ |
︙ | ︙ | |||
173 174 175 176 177 178 179 | EXTERN int TclWinCPUID(unsigned int index, unsigned int *regs); /* 30 */ EXTERN int TclUnixOpenTemporaryFile(Tcl_Obj *dirObj, Tcl_Obj *basenameObj, Tcl_Obj *extensionObj, Tcl_Obj *resultingNameObj); /* 31 */ EXTERN int TclpGetMonotonicTime(Tcl_Time *timePtr); | < < | 171 172 173 174 175 176 177 178 179 180 181 182 183 184 | EXTERN int TclWinCPUID(unsigned int index, unsigned int *regs); /* 30 */ EXTERN int TclUnixOpenTemporaryFile(Tcl_Obj *dirObj, Tcl_Obj *basenameObj, Tcl_Obj *extensionObj, Tcl_Obj *resultingNameObj); /* 31 */ EXTERN int TclpGetMonotonicTime(Tcl_Time *timePtr); #endif /* WIN */ #ifdef MAC_OSX_TCL /* MACOSX */ /* 0 */ EXTERN void TclGetAndDetachPids(Tcl_Interp *interp, Tcl_Channel chan); /* 1 */ EXTERN int TclpCloseFile(TclFile file); |
︙ | ︙ | |||
249 250 251 252 253 254 255 | EXTERN int TclWinCPUID(unsigned int index, unsigned int *regs); /* 30 */ EXTERN int TclUnixOpenTemporaryFile(Tcl_Obj *dirObj, Tcl_Obj *basenameObj, Tcl_Obj *extensionObj, Tcl_Obj *resultingNameObj); /* 31 */ EXTERN int TclpGetMonotonicTime(Tcl_Time *timePtr); | < < | 245 246 247 248 249 250 251 252 253 254 255 256 257 258 | EXTERN int TclWinCPUID(unsigned int index, unsigned int *regs); /* 30 */ EXTERN int TclUnixOpenTemporaryFile(Tcl_Obj *dirObj, Tcl_Obj *basenameObj, Tcl_Obj *extensionObj, Tcl_Obj *resultingNameObj); /* 31 */ EXTERN int TclpGetMonotonicTime(Tcl_Time *timePtr); #endif /* MACOSX */ typedef struct TclIntPlatStubs { int magic; void *hooks; #if !defined(_WIN32) && !defined(__CYGWIN__) && !defined(MAC_OSX_TCL) /* UNIX */ |
︙ | ︙ | |||
290 291 292 293 294 295 296 | void (*reserved25)(void); void (*reserved26)(void); void (*reserved27)(void); void (*reserved28)(void); int (*tclWinCPUID) (unsigned int index, unsigned int *regs); /* 29 */ int (*tclUnixOpenTemporaryFile) (Tcl_Obj *dirObj, Tcl_Obj *basenameObj, Tcl_Obj *extensionObj, Tcl_Obj *resultingNameObj); /* 30 */ int (*tclpGetMonotonicTime) (Tcl_Time *timePtr); /* 31 */ | < | 284 285 286 287 288 289 290 291 292 293 294 295 296 297 | void (*reserved25)(void); void (*reserved26)(void); void (*reserved27)(void); void (*reserved28)(void); int (*tclWinCPUID) (unsigned int index, unsigned int *regs); /* 29 */ int (*tclUnixOpenTemporaryFile) (Tcl_Obj *dirObj, Tcl_Obj *basenameObj, Tcl_Obj *extensionObj, Tcl_Obj *resultingNameObj); /* 30 */ int (*tclpGetMonotonicTime) (Tcl_Time *timePtr); /* 31 */ #endif /* UNIX */ #if defined(_WIN32) || defined(__CYGWIN__) /* WIN */ void (*tclWinConvertError) (DWORD errCode); /* 0 */ void (*tclWinConvertWSAError) (DWORD errCode); /* 1 */ struct servent * (*tclWinGetServByName) (const char *nm, const char *proto); /* 2 */ int (*tclWinGetSockOpt) (SOCKET s, int level, int optname, char *optval, int *optlen); /* 3 */ HINSTANCE (*tclWinGetTclInstance) (void); /* 4 */ |
︙ | ︙ | |||
325 326 327 328 329 330 331 | void (*reserved25)(void); void (*tclWinSetInterfaces) (int wide); /* 26 */ void (*tclWinFlushDirtyChannels) (void); /* 27 */ void (*tclWinResetInterfaces) (void); /* 28 */ int (*tclWinCPUID) (unsigned int index, unsigned int *regs); /* 29 */ int (*tclUnixOpenTemporaryFile) (Tcl_Obj *dirObj, Tcl_Obj *basenameObj, Tcl_Obj *extensionObj, Tcl_Obj *resultingNameObj); /* 30 */ int (*tclpGetMonotonicTime) (Tcl_Time *timePtr); /* 31 */ | < | 318 319 320 321 322 323 324 325 326 327 328 329 330 331 | void (*reserved25)(void); void (*tclWinSetInterfaces) (int wide); /* 26 */ void (*tclWinFlushDirtyChannels) (void); /* 27 */ void (*tclWinResetInterfaces) (void); /* 28 */ int (*tclWinCPUID) (unsigned int index, unsigned int *regs); /* 29 */ int (*tclUnixOpenTemporaryFile) (Tcl_Obj *dirObj, Tcl_Obj *basenameObj, Tcl_Obj *extensionObj, Tcl_Obj *resultingNameObj); /* 30 */ int (*tclpGetMonotonicTime) (Tcl_Time *timePtr); /* 31 */ #endif /* WIN */ #ifdef MAC_OSX_TCL /* MACOSX */ void (*tclGetAndDetachPids) (Tcl_Interp *interp, Tcl_Channel chan); /* 0 */ int (*tclpCloseFile) (TclFile file); /* 1 */ Tcl_Channel (*tclpCreateCommandChannel) (TclFile readFile, TclFile writeFile, TclFile errorFile, int numPids, Tcl_Pid *pidPtr); /* 2 */ int (*tclpCreatePipe) (TclFile *readPipe, TclFile *writePipe); /* 3 */ int (*tclpCreateProcess) (Tcl_Interp *interp, int argc, const char **argv, TclFile inputFile, TclFile outputFile, TclFile errorFile, Tcl_Pid *pidPtr); /* 4 */ |
︙ | ︙ | |||
360 361 362 363 364 365 366 | void (*reserved25)(void); void (*reserved26)(void); void (*reserved27)(void); void (*reserved28)(void); int (*tclWinCPUID) (unsigned int index, unsigned int *regs); /* 29 */ int (*tclUnixOpenTemporaryFile) (Tcl_Obj *dirObj, Tcl_Obj *basenameObj, Tcl_Obj *extensionObj, Tcl_Obj *resultingNameObj); /* 30 */ int (*tclpGetMonotonicTime) (Tcl_Time *timePtr); /* 31 */ | < | 352 353 354 355 356 357 358 359 360 361 362 363 364 365 | void (*reserved25)(void); void (*reserved26)(void); void (*reserved27)(void); void (*reserved28)(void); int (*tclWinCPUID) (unsigned int index, unsigned int *regs); /* 29 */ int (*tclUnixOpenTemporaryFile) (Tcl_Obj *dirObj, Tcl_Obj *basenameObj, Tcl_Obj *extensionObj, Tcl_Obj *resultingNameObj); /* 30 */ int (*tclpGetMonotonicTime) (Tcl_Time *timePtr); /* 31 */ #endif /* MACOSX */ } TclIntPlatStubs; extern const TclIntPlatStubs *tclIntPlatStubsPtr; #ifdef __cplusplus } |
︙ | ︙ | |||
424 425 426 427 428 429 430 | /* Slot 28 is reserved */ #define TclWinCPUID \ (tclIntPlatStubsPtr->tclWinCPUID) /* 29 */ #define TclUnixOpenTemporaryFile \ (tclIntPlatStubsPtr->tclUnixOpenTemporaryFile) /* 30 */ #define TclpGetMonotonicTime \ (tclIntPlatStubsPtr->tclpGetMonotonicTime) /* 31 */ | < < | 415 416 417 418 419 420 421 422 423 424 425 426 427 428 | /* Slot 28 is reserved */ #define TclWinCPUID \ (tclIntPlatStubsPtr->tclWinCPUID) /* 29 */ #define TclUnixOpenTemporaryFile \ (tclIntPlatStubsPtr->tclUnixOpenTemporaryFile) /* 30 */ #define TclpGetMonotonicTime \ (tclIntPlatStubsPtr->tclpGetMonotonicTime) /* 31 */ #endif /* UNIX */ #if defined(_WIN32) || defined(__CYGWIN__) /* WIN */ #define TclWinConvertError \ (tclIntPlatStubsPtr->tclWinConvertError) /* 0 */ #define TclWinConvertWSAError \ (tclIntPlatStubsPtr->tclWinConvertWSAError) /* 1 */ #define TclWinGetServByName \ |
︙ | ︙ | |||
490 491 492 493 494 495 496 | (tclIntPlatStubsPtr->tclWinResetInterfaces) /* 28 */ #define TclWinCPUID \ (tclIntPlatStubsPtr->tclWinCPUID) /* 29 */ #define TclUnixOpenTemporaryFile \ (tclIntPlatStubsPtr->tclUnixOpenTemporaryFile) /* 30 */ #define TclpGetMonotonicTime \ (tclIntPlatStubsPtr->tclpGetMonotonicTime) /* 31 */ | < < | 479 480 481 482 483 484 485 486 487 488 489 490 491 492 | (tclIntPlatStubsPtr->tclWinResetInterfaces) /* 28 */ #define TclWinCPUID \ (tclIntPlatStubsPtr->tclWinCPUID) /* 29 */ #define TclUnixOpenTemporaryFile \ (tclIntPlatStubsPtr->tclUnixOpenTemporaryFile) /* 30 */ #define TclpGetMonotonicTime \ (tclIntPlatStubsPtr->tclpGetMonotonicTime) /* 31 */ #endif /* WIN */ #ifdef MAC_OSX_TCL /* MACOSX */ #define TclGetAndDetachPids \ (tclIntPlatStubsPtr->tclGetAndDetachPids) /* 0 */ #define TclpCloseFile \ (tclIntPlatStubsPtr->tclpCloseFile) /* 1 */ #define TclpCreateCommandChannel \ |
︙ | ︙ | |||
546 547 548 549 550 551 552 | /* Slot 28 is reserved */ #define TclWinCPUID \ (tclIntPlatStubsPtr->tclWinCPUID) /* 29 */ #define TclUnixOpenTemporaryFile \ (tclIntPlatStubsPtr->tclUnixOpenTemporaryFile) /* 30 */ #define TclpGetMonotonicTime \ (tclIntPlatStubsPtr->tclpGetMonotonicTime) /* 31 */ | < < | 533 534 535 536 537 538 539 540 541 542 543 544 545 546 | /* Slot 28 is reserved */ #define TclWinCPUID \ (tclIntPlatStubsPtr->tclWinCPUID) /* 29 */ #define TclUnixOpenTemporaryFile \ (tclIntPlatStubsPtr->tclUnixOpenTemporaryFile) /* 30 */ #define TclpGetMonotonicTime \ (tclIntPlatStubsPtr->tclpGetMonotonicTime) /* 31 */ #endif /* MACOSX */ #endif /* defined(USE_TCL_STUBS) */ /* !END!: Do not edit above this line. */ #undef TCL_STORAGE_CLASS |
︙ | ︙ |
Changes to jni/tcl/generic/tclNotify.c.
︙ | ︙ | |||
136 137 138 139 140 141 142 | tsdPtr->clientData = Tcl_InitNotifier(); tsdPtr->initialized = 1; tsdPtr->nextPtr = firstNotifierPtr; firstNotifierPtr = tsdPtr; } Tcl_MutexUnlock(&listLock); | | | | 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 | tsdPtr->clientData = Tcl_InitNotifier(); tsdPtr->initialized = 1; tsdPtr->nextPtr = firstNotifierPtr; firstNotifierPtr = tsdPtr; } Tcl_MutexUnlock(&listLock); #ifndef _WIN32 /* * Kick off notifier thread if it is not running already. * Needed to early handle signals proper. */ Tcl_SetServiceMode(TCL_SERVICE_ALL); #endif } /* *---------------------------------------------------------------------- |
︙ | ︙ |
Changes to jni/tcl/generic/tclStubInit.c.
︙ | ︙ | |||
595 596 597 598 599 600 601 | 0, /* 25 */ 0, /* 26 */ 0, /* 27 */ 0, /* 28 */ TclWinCPUID, /* 29 */ TclUnixOpenTemporaryFile, /* 30 */ TclpGetMonotonicTime, /* 31 */ | < | 595 596 597 598 599 600 601 602 603 604 605 606 607 608 | 0, /* 25 */ 0, /* 26 */ 0, /* 27 */ 0, /* 28 */ TclWinCPUID, /* 29 */ TclUnixOpenTemporaryFile, /* 30 */ TclpGetMonotonicTime, /* 31 */ #endif /* UNIX */ #if defined(_WIN32) || defined(__CYGWIN__) /* WIN */ TclWinConvertError, /* 0 */ TclWinConvertWSAError, /* 1 */ TclWinGetServByName, /* 2 */ TclWinGetSockOpt, /* 3 */ TclWinGetTclInstance, /* 4 */ |
︙ | ︙ | |||
630 631 632 633 634 635 636 | 0, /* 25 */ TclWinSetInterfaces, /* 26 */ TclWinFlushDirtyChannels, /* 27 */ TclWinResetInterfaces, /* 28 */ TclWinCPUID, /* 29 */ TclUnixOpenTemporaryFile, /* 30 */ TclpGetMonotonicTime, /* 31 */ | < | 629 630 631 632 633 634 635 636 637 638 639 640 641 642 | 0, /* 25 */ TclWinSetInterfaces, /* 26 */ TclWinFlushDirtyChannels, /* 27 */ TclWinResetInterfaces, /* 28 */ TclWinCPUID, /* 29 */ TclUnixOpenTemporaryFile, /* 30 */ TclpGetMonotonicTime, /* 31 */ #endif /* WIN */ #ifdef MAC_OSX_TCL /* MACOSX */ TclGetAndDetachPids, /* 0 */ TclpCloseFile, /* 1 */ TclpCreateCommandChannel, /* 2 */ TclpCreatePipe, /* 3 */ TclpCreateProcess, /* 4 */ |
︙ | ︙ | |||
665 666 667 668 669 670 671 | 0, /* 25 */ 0, /* 26 */ 0, /* 27 */ 0, /* 28 */ TclWinCPUID, /* 29 */ TclUnixOpenTemporaryFile, /* 30 */ TclpGetMonotonicTime, /* 31 */ | < | 663 664 665 666 667 668 669 670 671 672 673 674 675 676 | 0, /* 25 */ 0, /* 26 */ 0, /* 27 */ 0, /* 28 */ TclWinCPUID, /* 29 */ TclUnixOpenTemporaryFile, /* 30 */ TclpGetMonotonicTime, /* 31 */ #endif /* MACOSX */ }; static const TclPlatStubs tclPlatStubs = { TCL_STUB_MAGIC, 0, #if defined(_WIN32) || defined(__CYGWIN__) /* WIN */ |
︙ | ︙ | |||
1418 1419 1420 1421 1422 1423 1424 1425 1426 1427 | Tcl_CloseEx, /* 624 */ Tcl_NRExprObj, /* 625 */ Tcl_NRSubstObj, /* 626 */ Tcl_LoadFile, /* 627 */ Tcl_FindSymbol, /* 628 */ Tcl_FSUnloadFile, /* 629 */ Tcl_ZlibStreamSetCompressionDictionary, /* 630 */ }; /* !END!: Do not edit above this line. */ | > | 1415 1416 1417 1418 1419 1420 1421 1422 1423 1424 1425 | Tcl_CloseEx, /* 624 */ Tcl_NRExprObj, /* 625 */ Tcl_NRSubstObj, /* 626 */ Tcl_LoadFile, /* 627 */ Tcl_FindSymbol, /* 628 */ Tcl_FSUnloadFile, /* 629 */ Tcl_ZlibStreamSetCompressionDictionary, /* 630 */ Tcl_AsyncMarkFromSignal, /* 631 */ }; /* !END!: Do not edit above this line. */ |
Changes to jni/tcl/macosx/tclMacOSXNotify.c.
︙ | ︙ | |||
361 362 363 364 365 366 367 | /* * Signal mask information for notifier thread. */ static sigset_t notifierSigMask; static sigset_t allSigMask; | < < < < < < < < < < < < < < < < | 361 362 363 364 365 366 367 368 369 370 371 372 373 374 | /* * Signal mask information for notifier thread. */ static sigset_t notifierSigMask; static sigset_t allSigMask; /* * This is the thread ID of the notifier thread that does select. Only valid * when notifierThreadRunning is non-zero. * * You must hold the notifierInitLock before accessing this variable. */ |
︙ | ︙ | |||
677 678 679 680 681 682 683 | Tcl_Panic("StartNotifierThread: notifier not initialized"); } if (!notifierThreadRunning) { int result; pthread_attr_t attr; /* | < | < | < | < > > > > > > > | 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 | Tcl_Panic("StartNotifierThread: notifier not initialized"); } if (!notifierThreadRunning) { int result; pthread_attr_t attr; /* * Arrange for the notifier thread to start with all * signals blocked. In its mainloop it unblocks the * signals at safe points. */ sigfillset(&allSigMask); pthread_sigmask(SIG_BLOCK, &allSigMask, ¬ifierSigMask); pthread_attr_init(&attr); pthread_attr_setscope(&attr, PTHREAD_SCOPE_SYSTEM); pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE); pthread_attr_setstacksize(&attr, 60 * 1024); result = pthread_create(¬ifierThread, &attr, (void * (*)(void *))NotifierThreadProc, NULL); pthread_attr_destroy(&attr); if (result) { Tcl_Panic("StartNotifierThread: unable to start notifier thread"); } notifierThreadRunning = 1; /* * Restore original signal mask. */ pthread_sigmask(SIG_SETMASK, ¬ifierSigMask, NULL); } UNLOCK_NOTIFIER_INIT; } /* *---------------------------------------------------------------------- |
︙ | ︙ | |||
769 770 771 772 773 774 775 | if (result) { Tcl_Panic("Tcl_FinalizeNotifier: unable to join notifier " "thread"); } notifierThreadRunning = 0; | < < < < < < | 756 757 758 759 760 761 762 763 764 765 766 767 768 769 | if (result) { Tcl_Panic("Tcl_FinalizeNotifier: unable to join notifier " "thread"); } notifierThreadRunning = 0; /* * If async marks are outstanding, perform actions now. */ if (asyncPending) { asyncPending = 0; TclAsyncMarkFromNotifier(); } |
︙ | ︙ | |||
1784 1785 1786 1787 1788 1789 1790 | } return result; } /* *---------------------------------------------------------------------- * | | | | | > > < | > | | | > > > > > < | 1765 1766 1767 1768 1769 1770 1771 1772 1773 1774 1775 1776 1777 1778 1779 1780 1781 1782 1783 1784 1785 1786 1787 1788 1789 1790 1791 1792 1793 1794 1795 1796 1797 1798 1799 1800 1801 1802 1803 1804 1805 1806 1807 1808 1809 1810 1811 1812 1813 1814 1815 1816 1817 1818 1819 1820 1821 1822 1823 | } return result; } /* *---------------------------------------------------------------------- * * TclAsyncNotifier -- * * This procedure sets the async mark of an async handler to a * given value, if it is called from the notifier thread. * * Result: * None. * * Side effetcs: * The trigger pipe is written when called from the notifier * thread. * *---------------------------------------------------------------------- */ void TclAsyncNotifier( int sigNumber, /* Signal number. */ Tcl_ThreadId threadId, /* Target thread. */ int *flagPtr, /* Flag to mark. */ int value) /* Value of mark. */ { #ifdef TCL_THREADS /* * WARNING: * This code most likely runs in a signal handler. Thus, * only few async-signal-safe system calls are allowed, * e.g. pthread_self(), sem_post(), write(). */ if (pthread_equal(pthread_self(), (pthread_t) notifierThread)) { if (notifierThreadRunning) { *flagPtr = value; asyncPending = 1; write(triggerPipe, "S", 1); } return; } /* * Re-send the signal to the notifier thread. */ pthread_kill((pthread_t) notifierThread, sigNumber); #endif } /* *---------------------------------------------------------------------- * * NotifierThreadProc -- * |
︙ | ︙ | |||
1858 1859 1860 1861 1862 1863 1864 | ClientData clientData) /* Not used. */ { ThreadSpecificData *tsdPtr; fd_set readableMask, writableMask, exceptionalMask; int i, ret, numFdBits = 0, polling; struct timeval poll = {0., 0.}, *timePtr; char buf[2]; | < < | 1845 1846 1847 1848 1849 1850 1851 1852 1853 1854 1855 1856 1857 1858 | ClientData clientData) /* Not used. */ { ThreadSpecificData *tsdPtr; fd_set readableMask, writableMask, exceptionalMask; int i, ret, numFdBits = 0, polling; struct timeval poll = {0., 0.}, *timePtr; char buf[2]; /* * Look for file events and report them to interested threads. */ while (1) { FD_ZERO(&readableMask); |
︙ | ︙ | |||
1910 1911 1912 1913 1914 1915 1916 | */ if (receivePipe >= numFdBits) { numFdBits = receivePipe + 1; } FD_SET(receivePipe, &readableMask); | < | < < < < < < < < < < | < < | < < < < | < < < < < | < < < > > > > > > > > > | 1895 1896 1897 1898 1899 1900 1901 1902 1903 1904 1905 1906 1907 1908 1909 1910 1911 1912 1913 1914 1915 1916 1917 1918 1919 1920 1921 1922 1923 1924 1925 1926 1927 | */ if (receivePipe >= numFdBits) { numFdBits = receivePipe + 1; } FD_SET(receivePipe, &readableMask); /* * Signals are unblocked only during select(). */ pthread_sigmask(SIG_SETMASK, ¬ifierSigMask, NULL); ret = select(numFdBits, &readableMask, &writableMask, &exceptionalMask, timePtr); pthread_sigmask(SIG_BLOCK, &allSigMask, NULL); if (ret == -1) { /* * In case a signal was caught during select(), * perform work on async handlers now. */ if (errno == EINTR && asyncPending) { asyncPending = 0; TclAsyncMarkFromNotifier(); } /* * Try again immediately on an error. */ continue; } /* |
︙ | ︙ | |||
2014 2015 2016 2017 2018 2019 2020 | CFRunLoopWakeUp(tsdPtr->runLoop); } } } UNLOCK_NOTIFIER; | < < < < < < < < < < < < < < < < | 1983 1984 1985 1986 1987 1988 1989 1990 1991 1992 1993 1994 1995 1996 | CFRunLoopWakeUp(tsdPtr->runLoop); } } } UNLOCK_NOTIFIER; /* * Consume the next byte from the notifier pipe if the pipe was * readable. Note that there may be multiple bytes pending, but to * avoid a race condition we only read one at a time. */ if (FD_ISSET(receivePipe, &readableMask)) { |
︙ | ︙ | |||
2136 2137 2138 2139 2140 2141 2142 | { ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey); UNLOCK_NOTIFIER_TSD; UNLOCK_NOTIFIER; UNLOCK_NOTIFIER_INIT; | < < < < < < < < < < | 2089 2090 2091 2092 2093 2094 2095 2096 2097 2098 2099 2100 2101 2102 2103 2104 2105 2106 2107 2108 2109 2110 2111 2112 2113 2114 2115 2116 2117 2118 2119 2120 2121 | { ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey); UNLOCK_NOTIFIER_TSD; UNLOCK_NOTIFIER; UNLOCK_NOTIFIER_INIT; asyncPending = 0; if (tsdPtr->runLoop) { tsdPtr->runLoop = NULL; if (!noCFafterFork) { CFRunLoopSourceInvalidate(tsdPtr->runLoopSource); CFRelease(tsdPtr->runLoopSource); if (tsdPtr->runLoopTimer) { CFRunLoopTimerInvalidate(tsdPtr->runLoopTimer); CFRelease(tsdPtr->runLoopTimer); } } tsdPtr->runLoopSource = NULL; tsdPtr->runLoopTimer = NULL; } if (notifierCount > 0) { notifierCount = 1; notifierThreadRunning = 0; /* * Assume that the return value of Tcl_InitNotifier in the child will * be identical to the one stored as clientData in tclNotify.c's * ThreadSpecificData by the parent's TclInitNotifier, so discard the * return value here. This assumption may require the fork() to be * executed in the main thread of the parent, otherwise * Tcl_AlertNotifier may break in the child. |
︙ | ︙ | |||
2192 2193 2194 2195 2196 2197 2198 | const void *runLoopMode) { Tcl_Panic("TclMacOSXNotifierAddRunLoopMode: " "Tcl not built with CoreFoundation support"); } #endif /* HAVE_COREFOUNDATION */ | < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < | 2135 2136 2137 2138 2139 2140 2141 2142 2143 2144 2145 2146 2147 2148 2149 | const void *runLoopMode) { Tcl_Panic("TclMacOSXNotifierAddRunLoopMode: " "Tcl not built with CoreFoundation support"); } #endif /* HAVE_COREFOUNDATION */ /* * Local Variables: * mode: c * c-basic-offset: 4 * fill-column: 78 * End: */ |
Changes to jni/tcl/unix/tclUnixNotfy.c.
︙ | ︙ | |||
165 166 167 168 169 170 171 | static int notifierThreadRunning = 0; /* * The following static flag indicates that async handlers are pending. */ | < < | 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 | static int notifierThreadRunning = 0; /* * The following static flag indicates that async handlers are pending. */ static int asyncPending = 0; /* * The notifier thread signals the notifierCV when it has finished * initializing the triggerPipe and right before the notifier thread * terminates. This condition is used to deal with the signal mask, too. */ |
︙ | ︙ | |||
199 200 201 202 203 204 205 | static Tcl_ThreadId notifierThread; /* * Signal mask information for notifier thread. */ | < < < < < < < < < < < < < < < < < | 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 | static Tcl_ThreadId notifierThread; /* * Signal mask information for notifier thread. */ static sigset_t notifierSigMask; static sigset_t allSigMask; #endif /* TCL_THREADS */ /* * Static routines defined in this file. */ |
︙ | ︙ | |||
312 313 314 315 316 317 318 | */ static void StartNotifierThread(const char *proc) { if (!notifierThreadRunning) { pthread_mutex_lock(¬ifierInitMutex); if (!notifierThreadRunning) { | | < | < | < | < > | > > > > > > | 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 | */ static void StartNotifierThread(const char *proc) { if (!notifierThreadRunning) { pthread_mutex_lock(¬ifierInitMutex); if (!notifierThreadRunning) { /* * Arrange for the notifier thread to start with all * signals blocked. In its mainloop it unblocks the * signals at safe points. */ sigfillset(&allSigMask); pthread_sigmask(SIG_BLOCK, &allSigMask, ¬ifierSigMask); pthread_mutex_lock(¬ifierMutex); if (TclpThreadCreate(¬ifierThread, NotifierThreadProc, NULL, TCL_THREAD_STACK_DEFAULT, TCL_THREAD_JOINABLE) != TCL_OK) { Tcl_Panic("%s: unable to start notifier thread", proc); } /* * Wait for the notifier pipe to be created. */ while (triggerPipe < 0) { pthread_cond_wait(¬ifierCV, ¬ifierMutex); } pthread_mutex_unlock(¬ifierMutex); notifierThreadRunning = 1; /* * Restore original signal mask. */ pthread_sigmask(SIG_SETMASK, ¬ifierSigMask, NULL); } pthread_mutex_unlock(¬ifierInitMutex); } } #endif /* TCL_THREADS */ /* |
︙ | ︙ | |||
506 507 508 509 510 511 512 | if (result) { Tcl_Panic("Tcl_FinalizeNotifier: unable to join notifier " "thread"); } notifierThreadRunning = 0; | < < < < < < < < | 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 | if (result) { Tcl_Panic("Tcl_FinalizeNotifier: unable to join notifier " "thread"); } notifierThreadRunning = 0; /* * If async marks are outstanding, perform actions now. */ if (asyncPending) { asyncPending = 0; TclAsyncMarkFromNotifier(); } } } } /* * Clean up any synchronization objects in the thread local storage. */ |
︙ | ︙ | |||
1209 1210 1211 1212 1213 1214 1215 | return 0; } } /* *---------------------------------------------------------------------- * | | | | | > > | < | > | | | > > > > > < | 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 | return 0; } } /* *---------------------------------------------------------------------- * * TclAsyncNotifier -- * * This procedure sets the async mark of an async handler to a * given value, if it is called from the notifier thread. * * Result: * None. * * Side effetcs: * The trigger pipe is written when called from the notifier * thread. * *---------------------------------------------------------------------- */ void TclAsyncNotifier( int sigNumber, /* Signal number. */ Tcl_ThreadId threadId, /* Target thread. */ int *flagPtr, /* Flag to mark. */ int value) /* Value of mark. */ { #ifdef TCL_THREADS /* * WARNING: * This code most likely runs in a signal handler. Thus, * only few async-signal-safe system calls are allowed, * e.g. pthread_self(), sem_post(), write(). */ if (pthread_equal(pthread_self(), (pthread_t) notifierThread)) { if (notifierThreadRunning) { *flagPtr = value; asyncPending = 1; write(triggerPipe, "S", 1); } return; } /* * Re-send the signal to the notifier thread. */ pthread_kill((pthread_t) notifierThread, sigNumber); #endif } #ifdef TCL_THREADS /* *---------------------------------------------------------------------- * * NotifierThreadProc -- |
︙ | ︙ | |||
1288 1289 1290 1291 1292 1293 1294 | fd_set writableMask; fd_set exceptionMask; int fds[2]; int i, numFdBits = 0, receivePipe, ret; long found; struct timeval poll = {0., 0.}, *timePtr; char buf[2]; | < < < < | 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 | fd_set writableMask; fd_set exceptionMask; int fds[2]; int i, numFdBits = 0, receivePipe, ret; long found; struct timeval poll = {0., 0.}, *timePtr; char buf[2]; if (pipe(fds) != 0) { Tcl_Panic("NotifierThreadProc: %s", "could not create trigger pipe"); } receivePipe = fds[0]; |
︙ | ︙ | |||
1383 1384 1385 1386 1387 1388 1389 | */ if (receivePipe >= numFdBits) { numFdBits = receivePipe + 1; } FD_SET(receivePipe, &readableMask); | < < | | < | | | < < | > | | | < > > < < | < < < < < | < < < < | < < | < < < < | 1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 1389 1390 1391 1392 1393 | */ if (receivePipe >= numFdBits) { numFdBits = receivePipe + 1; } FD_SET(receivePipe, &readableMask); /* * Signals are unblocked only during select(). */ pthread_sigmask(SIG_SETMASK, ¬ifierSigMask, NULL); ret = select(numFdBits, &readableMask, &writableMask, &exceptionMask, timePtr); pthread_sigmask(SIG_BLOCK, &allSigMask, NULL); if (ret == -1) { /* * In case a signal was caught during select(), * perform work on async handlers now. */ if (errno == EINTR && asyncPending) { asyncPending = 0; TclAsyncMarkFromNotifier(); } /* * Try again immediately on select() error. */ continue; } /* |
︙ | ︙ | |||
1484 1485 1486 1487 1488 1489 1490 | PostMessageW(tsdPtr->hwnd, 1024, 0, 0); #else /* __CYGWIN__ */ pthread_cond_broadcast(&tsdPtr->waitCV); #endif /* __CYGWIN__ */ } } | < < < < < < < < < < < < < < < > | | | | < < | 1442 1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 1453 1454 1455 1456 1457 1458 1459 1460 1461 1462 1463 1464 1465 1466 1467 1468 1469 1470 1471 1472 1473 1474 1475 1476 1477 1478 1479 1480 | PostMessageW(tsdPtr->hwnd, 1024, 0, 0); #else /* __CYGWIN__ */ pthread_cond_broadcast(&tsdPtr->waitCV); #endif /* __CYGWIN__ */ } } pthread_mutex_unlock(¬ifierMutex); /* * Consume the next byte from the notifier pipe if the pipe was * readable. Note that there may be multiple bytes pending, but to * avoid a race condition we only read one at a time. */ if (FD_ISSET(receivePipe, &readableMask)) { i = read(receivePipe, buf, 1); if ((i == 0) || ((i == 1) && (buf[0] == 'q'))) { /* * Someone closed the write end of the pipe or sent us a Quit * message [Bug: 4139] and then closed the write end of the * pipe so we need to shut down the notifier thread. */ break; } } if (asyncPending) { asyncPending = 0; TclAsyncMarkFromNotifier(); } } /* * Clean up the read end of the pipe and signal any threads waiting on * termination of the notifier thread. */ |
︙ | ︙ | |||
1570 1571 1572 1573 1574 1575 1576 | if (notifierThreadRunning == 1) { pthread_cond_destroy(¬ifierCV); } pthread_mutex_init(¬ifierInitMutex, NULL); pthread_mutex_init(¬ifierMutex, NULL); pthread_cond_init(¬ifierCV, NULL); | < < < | 1512 1513 1514 1515 1516 1517 1518 1519 1520 1521 1522 1523 1524 1525 1526 | if (notifierThreadRunning == 1) { pthread_cond_destroy(¬ifierCV); } pthread_mutex_init(¬ifierInitMutex, NULL); pthread_mutex_init(¬ifierMutex, NULL); pthread_cond_init(¬ifierCV, NULL); asyncPending = 0; /* * notifierThreadRunning == 1: thread is running, (there might be data in notifier lists) * atForkInit == 0: InitNotifier was never called * notifierCount != 0: unbalanced InitNotifier() / FinalizeNotifier calls * waitingListPtr != 0: there are threads currently waiting for events. */ |
︙ | ︙ | |||
1645 1646 1647 1648 1649 1650 1651 | } Tcl_InitNotifier(); } #endif /* HAVE_PTHREAD_ATFORK */ #endif /* TCL_THREADS */ | < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < | 1584 1585 1586 1587 1588 1589 1590 1591 1592 1593 1594 1595 1596 1597 1598 1599 1600 | } Tcl_InitNotifier(); } #endif /* HAVE_PTHREAD_ATFORK */ #endif /* TCL_THREADS */ #endif /* !HAVE_COREFOUNDATION */ /* * Local Variables: * mode: c * c-basic-offset: 4 * fill-column: 78 * End: */ |
jni/tcl/win/tclWinFile.c became a regular file.
︙ | ︙ |
Changes to jni/tcl/win/tclWinNotify.c.
︙ | ︙ | |||
365 366 367 368 369 370 371 | } } } /* *---------------------------------------------------------------------- * | | | | | > > < | 365 366 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 | } } } /* *---------------------------------------------------------------------- * * TclAsyncNotifier -- * * This procedure is a no-op on Windows. * * Result: * None. * * Side effetcs: * None. *---------------------------------------------------------------------- */ void TclAsyncNotifier( int sigNumber, /* Signal number. */ Tcl_ThreadId threadId, /* Target thread. */ int *flagPtr, /* Flag to mark. */ int value) /* Value of mark. */ { } /* *---------------------------------------------------------------------- * * NotifierProc -- * |
︙ | ︙ | |||
626 627 628 629 630 631 632 | tclScaleTimeProcPtr(&vdelay, tclTimeClientData); sleepTime = vdelay.sec * 1000 + vdelay.usec / 1000; if (sleepTime == INFINITE) { --sleepTime; } } } | < < < < < < < < < < < < < < < < < < < < < < < < < | 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 | tclScaleTimeProcPtr(&vdelay, tclTimeClientData); sleepTime = vdelay.sec * 1000 + vdelay.usec / 1000; if (sleepTime == INFINITE) { --sleepTime; } } } /* * Local Variables: * mode: c * c-basic-offset: 4 * fill-column: 78 * End: */ |
Changes to jni/tclx/generic/tclXsignal.c.
︙ | ︙ | |||
222 223 224 225 226 227 228 229 230 231 232 233 234 235 | static TclX_AppSignalErrorHandler appSigErrorHandler = NULL; static ClientData appSigErrorClientData = NULL; /* * Counters of signals that have occured but have not been processed. */ static unsigned signalsReceived[MAXSIG]; /* * Table of commands to evaluate when a signal occurs. If the command is * NULL and the signal is received, an error is returned. */ static char *signalTrapCmds[MAXSIG]; | > > | 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 | static TclX_AppSignalErrorHandler appSigErrorHandler = NULL; static ClientData appSigErrorClientData = NULL; /* * Counters of signals that have occured but have not been processed. */ static unsigned signalsReceived[MAXSIG]; static char signalsPending[MAXSIG]; static char signalsBlocked[MAXSIG]; /* * Table of commands to evaluate when a signal occurs. If the command is * NULL and the signal is received, an error is returned. */ static char *signalTrapCmds[MAXSIG]; |
︙ | ︙ | |||
463 464 465 466 467 468 469 | *----------------------------------------------------------------------------- */ static int BlockSignals (Tcl_Interp *interp, int action, unsigned char signals[]) { #ifndef NO_SIGACTION int signalNum; | < < < | > > | | < < < < | 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 | *----------------------------------------------------------------------------- */ static int BlockSignals (Tcl_Interp *interp, int action, unsigned char signals[]) { #ifndef NO_SIGACTION int signalNum; for (signalNum = 0; signalNum < MAXSIG; signalNum++) { if (signals [signalNum]) { signalsBlocked [signalNum] = (action == SIG_BLOCK); if (action == SIG_UNBLOCK && signalsPending [signalNum]) kill (getpid (), signalNum); } } return TCL_OK; #else TclX_AppendObjResult (interp, "Posix signals are not available on this system, ", "can not block signals"); |
︙ | ︙ | |||
503 504 505 506 507 508 509 | * boolean object. *----------------------------------------------------------------------------- */ static Tcl_Obj * SignalBlocked (int signalNum) { #ifndef NO_SIGACTION | < < < < < | | 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 | * boolean object. *----------------------------------------------------------------------------- */ static Tcl_Obj * SignalBlocked (int signalNum) { #ifndef NO_SIGACTION return Tcl_NewBooleanObj (signalsBlocked [signalNum] != 0); #else return Tcl_NewBooleanObj (FALSE); #endif } /*----------------------------------------------------------------------------- * SigNameToNum -- |
︙ | ︙ | |||
613 614 615 616 617 618 619 620 621 | { if (asyncHandler == NULL) return; /* * Record the count of the number of this type of signal that has occured * and tell all the interpreters to call the async handler when safe. */ signalsReceived [signalNum]++; | > > > > > > | | 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 | { if (asyncHandler == NULL) return; /* * Record the count of the number of this type of signal that has occured * and tell all the interpreters to call the async handler when safe. */ if (signalsBlocked [signalNum]) { signalsPending [signalNum] = 1; return; } signalsPending [signalNum] = 0; signalsReceived [signalNum]++; Tcl_AsyncMarkFromSignal (asyncHandler, signalNum); #ifdef NO_SIGACTION /* * For old-style Unix signals, the signal must be explictly re-enabled. * Not done for SIGCHLD, as we would continue to the signal until the * wait is done. This is fixed by Posix signals and is not necessary under * BSD, but it done this way for consistency. |
︙ | ︙ | |||
1618 1619 1620 1621 1622 1623 1624 1625 1626 1627 1628 1629 1630 1631 | if (numInterps == 0) { interpTableSize = 4; interpTable = (Tcl_Interp **) ckalloc (sizeof (Tcl_Interp *) * interpTableSize); for (idx = 0; idx < MAXSIG; idx++) { signalsReceived [idx] = 0; signalTrapCmds [idx] = NULL; } asyncHandler = Tcl_AsyncCreate (ProcessSignals, (ClientData) NULL); /* * Get address of "unknown signal" message. */ unknownSignalIdMsg = Tcl_SignalId (20000); | > > | 1616 1617 1618 1619 1620 1621 1622 1623 1624 1625 1626 1627 1628 1629 1630 1631 | if (numInterps == 0) { interpTableSize = 4; interpTable = (Tcl_Interp **) ckalloc (sizeof (Tcl_Interp *) * interpTableSize); for (idx = 0; idx < MAXSIG; idx++) { signalsReceived [idx] = 0; signalsBlocked [idx] = 0; signalsPending [idx] = 0; signalTrapCmds [idx] = NULL; } asyncHandler = Tcl_AsyncCreate (ProcessSignals, (ClientData) NULL); /* * Get address of "unknown signal" message. */ unknownSignalIdMsg = Tcl_SignalId (20000); |
︙ | ︙ |