diff options
author | jan.nijtmans <nijtmans@users.sourceforge.net> | 2021-08-20 12:48:30 (GMT) |
---|---|---|
committer | jan.nijtmans <nijtmans@users.sourceforge.net> | 2021-08-20 12:48:30 (GMT) |
commit | 01fbecbaaf77dd7e80ed055550874cf8b4a04c00 (patch) | |
tree | 521a362b471330df6d50b874790c4de4dc45b291 /unix/tclEpollNotfy.c | |
parent | b7d695159389d80f23edaff43638646ab40c2adc (diff) | |
parent | 94b338844e5af1659858a5446714c65fcbaecf54 (diff) | |
download | tcl-01fbecbaaf77dd7e80ed055550874cf8b4a04c00.zip tcl-01fbecbaaf77dd7e80ed055550874cf8b4a04c00.tar.gz tcl-01fbecbaaf77dd7e80ed055550874cf8b4a04c00.tar.bz2 |
Merge 8.7
Diffstat (limited to 'unix/tclEpollNotfy.c')
-rw-r--r-- | unix/tclEpollNotfy.c | 59 |
1 files changed, 59 insertions, 0 deletions
diff --git a/unix/tclEpollNotfy.c b/unix/tclEpollNotfy.c index 588c1b5..5b40dd7 100644 --- a/unix/tclEpollNotfy.c +++ b/unix/tclEpollNotfy.c @@ -111,6 +111,7 @@ typedef struct ThreadSpecificData { /* Pointer to at most maxReadyEvents events * returned by epoll_wait(2). */ size_t maxReadyEvents; /* Count of epoll_events in readyEvents. */ + int asyncPending; /* True when signal triggered thread. */ } ThreadSpecificData; static Tcl_ThreadDataKey dataKey; @@ -478,6 +479,10 @@ PlatformEventsWait( timePtr->tv_usec = 0; } } + if (tsdPtr->asyncPending) { + tsdPtr->asyncPending = 0; + TclAsyncMarkFromNotifier(); + } return numFound; } @@ -765,6 +770,60 @@ TclpWaitForEvent( return 0; } +/* + *---------------------------------------------------------------------- + * + * TclAsyncNotifier -- + * + * This procedure sets the async mark of an async handler to a + * given value, if it is called from the target thread. + * + * Result: + * True, when the handler will be marked, false otherwise. + * + * Side effects: + * The signal may be resent to the target thread. + * + *---------------------------------------------------------------------- + */ + +int +TclAsyncNotifier( + int sigNumber, /* Signal number. */ + Tcl_ThreadId threadId, /* Target thread. */ + ClientData clientData, /* Notifier data. */ + int *flagPtr, /* Flag to mark. */ + int value) /* Value of mark. */ +{ +#if 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) threadId)) { + ThreadSpecificData *tsdPtr = (ThreadSpecificData *) clientData; + + *flagPtr = value; + if (tsdPtr != NULL && !tsdPtr->asyncPending) { + tsdPtr->asyncPending = 1; + TclpAlertNotifier(tsdPtr); + return 1; + } + return 0; + } + + /* + * Re-send the signal to the proper target thread. + */ + + pthread_kill((pthread_t) threadId, sigNumber); +#endif + return 0; +} + #endif /* NOTIFIER_EPOLL && TCL_THREADS */ #else TCL_MAC_EMPTY_FILE(unix_tclEpollNotfy_c) |