summaryrefslogtreecommitdiffstats
path: root/unix/tclEpollNotfy.c
diff options
context:
space:
mode:
authorjan.nijtmans <nijtmans@users.sourceforge.net>2021-08-20 12:48:30 (GMT)
committerjan.nijtmans <nijtmans@users.sourceforge.net>2021-08-20 12:48:30 (GMT)
commit01fbecbaaf77dd7e80ed055550874cf8b4a04c00 (patch)
tree521a362b471330df6d50b874790c4de4dc45b291 /unix/tclEpollNotfy.c
parentb7d695159389d80f23edaff43638646ab40c2adc (diff)
parent94b338844e5af1659858a5446714c65fcbaecf54 (diff)
downloadtcl-01fbecbaaf77dd7e80ed055550874cf8b4a04c00.zip
tcl-01fbecbaaf77dd7e80ed055550874cf8b4a04c00.tar.gz
tcl-01fbecbaaf77dd7e80ed055550874cf8b4a04c00.tar.bz2
Merge 8.7
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 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)