summaryrefslogtreecommitdiffstats
path: root/unix/tclEpollNotfy.c
diff options
context:
space:
mode:
authorjan.nijtmans <nijtmans@users.sourceforge.net>2021-08-17 16:16:29 (GMT)
committerjan.nijtmans <nijtmans@users.sourceforge.net>2021-08-17 16:16:29 (GMT)
commit5f83d31eceac5d0a48f75293f02725a59168beaf (patch)
tree088ba5712739eee4f6fd1ff277de958420af7021 /unix/tclEpollNotfy.c
parent58502bda0b655dcb2b8e619c1cce4ba99f294aad (diff)
downloadtcl-5f83d31eceac5d0a48f75293f02725a59168beaf.zip
tcl-5f83d31eceac5d0a48f75293f02725a59168beaf.tar.gz
tcl-5f83d31eceac5d0a48f75293f02725a59168beaf.tar.bz2
tip#511 proposed implementation
Diffstat (limited to 'unix/tclEpollNotfy.c')
-rw-r--r--unix/tclEpollNotfy.c59
1 files changed, 59 insertions, 0 deletions
diff --git a/unix/tclEpollNotfy.c b/unix/tclEpollNotfy.c
index 4be1439..ce7d6b1 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. */
+{
+#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) 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)