summaryrefslogtreecommitdiffstats
path: root/unix/tclEpollNotfy.c
diff options
context:
space:
mode:
authordkf <donal.k.fellows@manchester.ac.uk>2021-04-03 13:53:56 (GMT)
committerdkf <donal.k.fellows@manchester.ac.uk>2021-04-03 13:53:56 (GMT)
commit8b11f08b3cb7e5e92dd7812df02e8419e49be96d (patch)
tree87a42b23f924af5846a8c2999de5fd98db252a25 /unix/tclEpollNotfy.c
parent02855d5980f78e6e42b3a35274a26c978f9af694 (diff)
parent743881d3ce722dbba89ec98a6f5a9618e683bbf1 (diff)
downloadtcl-8b11f08b3cb7e5e92dd7812df02e8419e49be96d.zip
tcl-8b11f08b3cb7e5e92dd7812df02e8419e49be96d.tar.gz
tcl-8b11f08b3cb7e5e92dd7812df02e8419e49be96d.tar.bz2
Clean up the notifier code to not spread the hooks quite so widely
Diffstat (limited to 'unix/tclEpollNotfy.c')
-rw-r--r--unix/tclEpollNotfy.c461
1 files changed, 198 insertions, 263 deletions
diff --git a/unix/tclEpollNotfy.c b/unix/tclEpollNotfy.c
index 18abacd..a6a183b 100644
--- a/unix/tclEpollNotfy.c
+++ b/unix/tclEpollNotfy.c
@@ -97,7 +97,7 @@ typedef struct ThreadSpecificData {
* that are ready for I/O. */
pthread_mutex_t notifierMutex;
/* Mutex protecting notifier termination in
- * PlatformEventsFinalize. */
+ * TclpFinalizeNotifier. */
#ifdef HAVE_EVENTFD
int triggerEventFd; /* eventfd(2) used by other threads to wake
* up this thread for inter-thread IPC. */
@@ -121,14 +121,13 @@ static Tcl_ThreadDataKey dataKey;
static void PlatformEventsControl(FileHandler *filePtr,
ThreadSpecificData *tsdPtr, int op, int isNew);
-static void PlatformEventsFinalize(void);
static void PlatformEventsInit(void);
static int PlatformEventsTranslate(struct epoll_event *event);
static int PlatformEventsWait(struct epoll_event *events,
size_t numEvents, struct timeval *timePtr);
-
+
/*
- * Incorporate the base notifier API.
+ * Incorporate the base notifier implementation.
*/
#include "tclUnixNotfy.c"
@@ -136,7 +135,7 @@ static int PlatformEventsWait(struct epoll_event *events,
/*
*----------------------------------------------------------------------
*
- * Tcl_InitNotifier --
+ * TclpInitNotifier --
*
* Initializes the platform specific notifier state.
*
@@ -144,54 +143,21 @@ static int PlatformEventsWait(struct epoll_event *events,
* Returns a handle to the notifier state for this thread.
*
* Side effects:
- * If no initNotifierProc notifier hook exists, PlatformEventsInit
- * is called.
+ * If no initNotifierProc notifier hook exists, PlatformEventsInit is
+ * called.
*
*----------------------------------------------------------------------
*/
ClientData
-Tcl_InitNotifier(void)
+TclpInitNotifier(void)
{
- if (tclNotifierHooks.initNotifierProc) {
- return tclNotifierHooks.initNotifierProc();
- } else {
- ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
+ ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
- PlatformEventsInit();
- return tsdPtr;
- }
+ PlatformEventsInit();
+ return tsdPtr;
}
-/*
- *----------------------------------------------------------------------
- *
- * Tcl_FinalizeNotifier --
- *
- * This function is called to cleanup the notifier state before a thread
- * is terminated.
- *
- * Results:
- * None.
- *
- * Side effects:
- * If no finalizeNotifierProc notifier hook exists, PlatformEvents-
- * Finalize is called.
- *
- *----------------------------------------------------------------------
- */
-
-void
-Tcl_FinalizeNotifier(
- ClientData clientData)
-{
- if (tclNotifierHooks.finalizeNotifierProc) {
- tclNotifierHooks.finalizeNotifierProc(clientData);
- return;
- } else {
- PlatformEventsFinalize();
- }
-}
/*
*----------------------------------------------------------------------
@@ -221,7 +187,7 @@ Tcl_FinalizeNotifier(
*----------------------------------------------------------------------
*/
-void
+static void
PlatformEventsControl(
FileHandler *filePtr,
ThreadSpecificData *tsdPtr,
@@ -240,7 +206,8 @@ PlatformEventsControl(
newEvent.events |= EPOLLOUT;
}
if (isNew) {
- newPedPtr = (struct PlatformEventData *)Tcl_Alloc(sizeof(struct PlatformEventData));
+ newPedPtr = (struct PlatformEventData *)
+ Tcl_Alloc(sizeof(struct PlatformEventData));
newPedPtr->filePtr = filePtr;
newPedPtr->tsdPtr = tsdPtr;
filePtr->pedPtr = newPedPtr;
@@ -249,7 +216,7 @@ PlatformEventsControl(
/*
* N.B. As discussed in Tcl_WaitForEvent(), epoll(7) does not support
- * regular files (S_IFREG.) Therefore, filePtr is in these cases simply
+ * regular files (S_IFREG). Therefore, filePtr is in these cases simply
* added or deleted from the list of FileHandlers associated with regular
* files belonging to tsdPtr.
*/
@@ -277,7 +244,7 @@ PlatformEventsControl(
/*
*----------------------------------------------------------------------
*
- * PlatformEventsFinalize --
+ * TclpFinalizeNotifier --
*
* This function closes the eventfd and the epoll file descriptor and
* frees the epoll_event structs owned by the thread of the caller. The
@@ -299,8 +266,8 @@ PlatformEventsControl(
*/
void
-PlatformEventsFinalize(
- void)
+TclpFinalizeNotifier(
+ TCL_UNUSED(ClientData))
{
ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
@@ -362,7 +329,7 @@ PlatformEventsFinalize(
*----------------------------------------------------------------------
*/
-void
+static void
PlatformEventsInit(void)
{
ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
@@ -372,7 +339,7 @@ PlatformEventsInit(void)
if (errno) {
Tcl_Panic("Tcl_InitNotifier: %s", "could not create mutex");
}
- filePtr = (FileHandler *)Tcl_Alloc(sizeof(FileHandler));
+ filePtr = (FileHandler *) Tcl_Alloc(sizeof(FileHandler));
#ifdef HAVE_EVENTFD
tsdPtr->triggerEventFd = eventfd(0, EFD_CLOEXEC | EFD_NONBLOCK);
if (tsdPtr->triggerEventFd <= 0) {
@@ -393,7 +360,7 @@ PlatformEventsInit(void)
PlatformEventsControl(filePtr, tsdPtr, EPOLL_CTL_ADD, 1);
if (!tsdPtr->readyEvents) {
tsdPtr->maxReadyEvents = 512;
- tsdPtr->readyEvents = (struct epoll_event *)Tcl_Alloc(
+ tsdPtr->readyEvents = (struct epoll_event *) Tcl_Alloc(
tsdPtr->maxReadyEvents * sizeof(tsdPtr->readyEvents[0]));
}
LIST_INIT(&tsdPtr->firstReadyFileHandlerPtr);
@@ -416,7 +383,7 @@ PlatformEventsInit(void)
*----------------------------------------------------------------------
*/
-int
+static int
PlatformEventsTranslate(
struct epoll_event *eventPtr)
{
@@ -457,7 +424,7 @@ PlatformEventsTranslate(
*----------------------------------------------------------------------
*/
-int
+static int
PlatformEventsWait(
struct epoll_event *events,
size_t numEvents,
@@ -480,9 +447,9 @@ PlatformEventsWait(
} else if (!timePtr->tv_sec && !timePtr->tv_usec) {
timeout = 0;
} else {
- timeout = (int)timePtr->tv_sec * 1000;
+ timeout = (int) timePtr->tv_sec * 1000;
if (timePtr->tv_usec) {
- timeout += (int)timePtr->tv_usec / 1000;
+ timeout += (int) timePtr->tv_usec / 1000;
}
}
@@ -493,7 +460,7 @@ PlatformEventsWait(
*/
gettimeofday(&tv0, NULL);
- numFound = epoll_wait(tsdPtr->eventsFd, events, (int)numEvents, timeout);
+ numFound = epoll_wait(tsdPtr->eventsFd, events, (int) numEvents, timeout);
gettimeofday(&tv1, NULL);
if (timePtr && (timePtr->tv_sec && timePtr->tv_usec)) {
timersub(&tv1, &tv0, &tv_delta);
@@ -510,7 +477,7 @@ PlatformEventsWait(
/*
*----------------------------------------------------------------------
*
- * Tcl_CreateFileHandler --
+ * TclpCreateFileHandler --
*
* This function registers a file handler with the epoll notifier of the
* thread of the caller.
@@ -526,7 +493,7 @@ PlatformEventsWait(
*/
void
-Tcl_CreateFileHandler(
+TclpCreateFileHandler(
int fd, /* Handle of stream to watch. */
int mask, /* OR'ed combination of TCL_READABLE,
* TCL_WRITABLE, and TCL_EXCEPTION: indicates
@@ -536,44 +503,29 @@ Tcl_CreateFileHandler(
* event. */
ClientData clientData) /* Arbitrary data to pass to proc. */
{
- int isNew;
-
- if (tclNotifierHooks.createFileHandlerProc) {
- tclNotifierHooks.createFileHandlerProc(fd, mask, proc, clientData);
- return;
- } else {
- ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
- FileHandler *filePtr;
-
- for (filePtr = tsdPtr->firstFileHandlerPtr; filePtr != NULL;
- filePtr = filePtr->nextPtr) {
- if (filePtr->fd == fd) {
- break;
- }
- }
- if (filePtr == NULL) {
- filePtr = (FileHandler *)Tcl_Alloc(sizeof(FileHandler));
- filePtr->fd = fd;
- filePtr->readyMask = 0;
- filePtr->nextPtr = tsdPtr->firstFileHandlerPtr;
- tsdPtr->firstFileHandlerPtr = filePtr;
- isNew = 1;
- } else {
- isNew = 0;
- }
- filePtr->proc = proc;
- filePtr->clientData = clientData;
- filePtr->mask = mask;
+ ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
+ FileHandler *filePtr = LookUpFileHandler(tsdPtr, fd, NULL);
+ int isNew = (filePtr == NULL);
- PlatformEventsControl(filePtr, tsdPtr,
- isNew ? EPOLL_CTL_ADD : EPOLL_CTL_MOD, isNew);
+ if (isNew) {
+ filePtr = (FileHandler *) Tcl_Alloc(sizeof(FileHandler));
+ filePtr->fd = fd;
+ filePtr->readyMask = 0;
+ filePtr->nextPtr = tsdPtr->firstFileHandlerPtr;
+ tsdPtr->firstFileHandlerPtr = filePtr;
}
+ filePtr->proc = proc;
+ filePtr->clientData = clientData;
+ filePtr->mask = mask;
+
+ PlatformEventsControl(filePtr, tsdPtr,
+ isNew ? EPOLL_CTL_ADD : EPOLL_CTL_MOD, isNew);
}
/*
*----------------------------------------------------------------------
*
- * Tcl_DeleteFileHandler --
+ * TclpDeleteFileHandler --
*
* Cancel a previously-arranged callback arrangement for a file on the
* epoll file descriptor of the thread of the caller.
@@ -591,60 +543,50 @@ Tcl_CreateFileHandler(
*/
void
-Tcl_DeleteFileHandler(
+TclpDeleteFileHandler(
int fd) /* Stream id for which to remove callback
* function. */
{
- if (tclNotifierHooks.deleteFileHandlerProc) {
- tclNotifierHooks.deleteFileHandlerProc(fd);
- return;
- } else {
- FileHandler *filePtr, *prevPtr;
- ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
+ FileHandler *filePtr, *prevPtr;
+ ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
- /*
- * Find the entry for the given file (and return if there isn't one).
- */
+ /*
+ * Find the entry for the given file (and return if there isn't one).
+ */
- for (prevPtr = NULL, filePtr = tsdPtr->firstFileHandlerPtr; ;
- prevPtr = filePtr, filePtr = filePtr->nextPtr) {
- if (filePtr == NULL) {
- return;
- }
- if (filePtr->fd == fd) {
- break;
- }
- }
+ filePtr = LookUpFileHandler(tsdPtr, fd, &prevPtr);
+ if (filePtr == NULL) {
+ return;
+ }
- /*
- * Update the check masks for this file.
- */
+ /*
+ * Update the check masks for this file.
+ */
- PlatformEventsControl(filePtr, tsdPtr, EPOLL_CTL_DEL, 0);
- if (filePtr->pedPtr) {
- Tcl_Free(filePtr->pedPtr);
- }
+ PlatformEventsControl(filePtr, tsdPtr, EPOLL_CTL_DEL, 0);
+ if (filePtr->pedPtr) {
+ Tcl_Free(filePtr->pedPtr);
+ }
- /*
- * Clean up information in the callback record.
- */
+ /*
+ * Clean up information in the callback record.
+ */
- if (prevPtr == NULL) {
- tsdPtr->firstFileHandlerPtr = filePtr->nextPtr;
- } else {
- prevPtr->nextPtr = filePtr->nextPtr;
- }
- Tcl_Free(filePtr);
+ if (prevPtr == NULL) {
+ tsdPtr->firstFileHandlerPtr = filePtr->nextPtr;
+ } else {
+ prevPtr->nextPtr = filePtr->nextPtr;
}
+ Tcl_Free(filePtr);
}
/*
*----------------------------------------------------------------------
*
- * Tcl_WaitForEvent --
+ * TclpWaitForEvent --
*
* This function is called by Tcl_DoOneEvent to wait for new events on
- * the message queue. If the block time is 0, then Tcl_WaitForEvent just
+ * the message queue. If the block time is 0, then TclpWaitForEvent just
* polls without blocking.
*
* The waiting logic is implemented in PlatformEventsWait.
@@ -660,172 +602,165 @@ Tcl_DeleteFileHandler(
*/
int
-Tcl_WaitForEvent(
+TclpWaitForEvent(
const Tcl_Time *timePtr) /* Maximum block time, or NULL. */
{
- if (tclNotifierHooks.waitForEventProc) {
- return tclNotifierHooks.waitForEventProc(timePtr);
- } else {
- FileHandler *filePtr;
- int mask;
- Tcl_Time vTime;
- /*
- * Impl. notes: timeout & timeoutPtr are used if, and only if threads
- * are not enabled. They are the arguments for the regular epoll_wait()
- * used when the core is not thread-enabled.
- */
+ FileHandler *filePtr;
+ Tcl_Time vTime;
+ struct timeval timeout, *timeoutPtr;
+ /* Impl. notes: timeout & timeoutPtr are used
+ * if, and only if threads are not enabled.
+ * They are the arguments for the regular
+ * epoll_wait() used when the core is not
+ * thread-enabled. */
+ int mask, numFound, numEvent;
+ struct PlatformEventData *pedPtr;
+ ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
+ int numQueued;
+ ssize_t i;
- struct timeval timeout, *timeoutPtr;
- int numFound, numEvent;
- struct PlatformEventData *pedPtr;
- ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
- int numQueued;
- ssize_t i;
+ /*
+ * Set up the timeout structure. Note that if there are no events to check
+ * for, we return with a negative result rather than blocking forever.
+ */
+ if (timePtr != NULL) {
/*
- * Set up the timeout structure. Note that if there are no events to
- * check for, we return with a negative result rather than blocking
- * forever.
+ * TIP #233 (Virtualized Time). Is virtual time in effect? And do we
+ * actually have something to scale? If yes to both then we call the
+ * handler to do this scaling.
*/
- if (timePtr != NULL) {
- /*
- * TIP #233 (Virtualized Time). Is virtual time in effect? And do
- * we actually have something to scale? If yes to both then we
- * call the handler to do this scaling.
- */
-
- if (timePtr->sec != 0 || timePtr->usec != 0) {
- vTime = *timePtr;
- tclScaleTimeProcPtr(&vTime, tclTimeClientData);
- timePtr = &vTime;
- }
- timeout.tv_sec = timePtr->sec;
- timeout.tv_usec = timePtr->usec;
- timeoutPtr = &timeout;
- } else {
- timeoutPtr = NULL;
+ if (timePtr->sec != 0 || timePtr->usec != 0) {
+ vTime = *timePtr;
+ TclScaleTime(&vTime);
+ timePtr = &vTime;
}
+ timeout.tv_sec = timePtr->sec;
+ timeout.tv_usec = timePtr->usec;
+ timeoutPtr = &timeout;
+ } else {
+ timeoutPtr = NULL;
+ }
- /*
- * Walk the list of FileHandlers associated with regular files
- * (S_IFREG) belonging to tsdPtr, queue Tcl events for them, and
- * update their mask of events of interest.
- *
- * As epoll(7) does not support regular files, the behaviour of
- * {select,poll}(2) is simply simulated here: fds associated with
- * regular files are added to this list by PlatformEventsControl() and
- * processed here before calling (and possibly blocking) on
- * PlatformEventsWait().
- */
-
- numQueued = 0;
- LIST_FOREACH(filePtr, &tsdPtr->firstReadyFileHandlerPtr, readyNode) {
- mask = 0;
- if (filePtr->mask & TCL_READABLE) {
- mask |= TCL_READABLE;
- }
- if (filePtr->mask & TCL_WRITABLE) {
- mask |= TCL_WRITABLE;
- }
-
- /*
- * Don't bother to queue an event if the mask was previously
- * non-zero since an event must still be on the queue.
- */
-
- if (filePtr->readyMask == 0) {
- FileHandlerEvent *fileEvPtr = (FileHandlerEvent *)
- Tcl_Alloc(sizeof(FileHandlerEvent));
+ /*
+ * Walk the list of FileHandlers associated with regular files (S_IFREG)
+ * belonging to tsdPtr, queue Tcl events for them, and update their mask
+ * of events of interest.
+ *
+ * As epoll(7) does not support regular files, the behaviour of
+ * {select,poll}(2) is simply simulated here: fds associated with regular
+ * files are added to this list by PlatformEventsControl() and processed
+ * here before calling (and possibly blocking) on PlatformEventsWait().
+ */
- fileEvPtr->header.proc = FileHandlerEventProc;
- fileEvPtr->fd = filePtr->fd;
- Tcl_QueueEvent((Tcl_Event *) fileEvPtr, TCL_QUEUE_TAIL);
- numQueued++;
- }
- filePtr->readyMask = mask;
+ numQueued = 0;
+ LIST_FOREACH(filePtr, &tsdPtr->firstReadyFileHandlerPtr, readyNode) {
+ mask = 0;
+ if (filePtr->mask & TCL_READABLE) {
+ mask |= TCL_READABLE;
+ }
+ if (filePtr->mask & TCL_WRITABLE) {
+ mask |= TCL_WRITABLE;
}
/*
- * If any events were queued in the above loop, force
- * PlatformEventsWait() to poll as there already are events that need
- * to be processed at this point.
+ * Don't bother to queue an event if the mask was previously non-zero
+ * since an event must still be on the queue.
*/
- if (numQueued) {
- timeout.tv_sec = 0;
- timeout.tv_usec = 0;
- timeoutPtr = &timeout;
+ if (filePtr->readyMask == 0) {
+ FileHandlerEvent *fileEvPtr = (FileHandlerEvent *)
+ Tcl_Alloc(sizeof(FileHandlerEvent));
+
+ fileEvPtr->header.proc = FileHandlerEventProc;
+ fileEvPtr->fd = filePtr->fd;
+ Tcl_QueueEvent((Tcl_Event *) fileEvPtr, TCL_QUEUE_TAIL);
+ numQueued++;
}
+ filePtr->readyMask = mask;
+ }
- /*
- * Wait or poll for new events, queue Tcl events for the FileHandlers
- * corresponding to them, and update the FileHandlers' mask of events
- * of interest registered by the last call to Tcl_CreateFileHandler().
- *
- * Events for the eventfd(2)/trigger pipe are processed here in order
- * to facilitate inter-thread IPC. If another thread intends to wake
- * up this thread whilst it's blocking on PlatformEventsWait(), it
- * write(2)s to the eventfd(2)/trigger pipe (see Tcl_AlertNotifier(),)
- * which in turn will cause PlatformEventsWait() to return
- * immediately.
- */
+ /*
+ * If any events were queued in the above loop, force PlatformEventsWait()
+ * to poll as there already are events that need to be processed at this
+ * point.
+ */
+
+ if (numQueued) {
+ timeout.tv_sec = 0;
+ timeout.tv_usec = 0;
+ timeoutPtr = &timeout;
+ }
+
+ /*
+ * Wait or poll for new events, queue Tcl events for the FileHandlers
+ * corresponding to them, and update the FileHandlers' mask of events of
+ * interest registered by the last call to Tcl_CreateFileHandler().
+ *
+ * Events for the eventfd(2)/trigger pipe are processed here in order to
+ * facilitate inter-thread IPC. If another thread intends to wake up this
+ * thread whilst it's blocking on PlatformEventsWait(), it write(2)s to
+ * the eventfd(2)/trigger pipe (see Tcl_AlertNotifier(),) which in turn
+ * will cause PlatformEventsWait() to return immediately.
+ */
- numFound = PlatformEventsWait(tsdPtr->readyEvents,
- tsdPtr->maxReadyEvents, timeoutPtr);
- for (numEvent = 0; numEvent < numFound; numEvent++) {
- pedPtr = (struct PlatformEventData*)tsdPtr->readyEvents[numEvent].data.ptr;
- filePtr = pedPtr->filePtr;
- mask = PlatformEventsTranslate(&tsdPtr->readyEvents[numEvent]);
+ numFound = PlatformEventsWait(tsdPtr->readyEvents,
+ tsdPtr->maxReadyEvents, timeoutPtr);
+ for (numEvent = 0; numEvent < numFound; numEvent++) {
+ pedPtr = (struct PlatformEventData *)
+ tsdPtr->readyEvents[numEvent].data.ptr;
+ filePtr = pedPtr->filePtr;
+ mask = PlatformEventsTranslate(&tsdPtr->readyEvents[numEvent]);
#ifdef HAVE_EVENTFD
- if (filePtr->fd == tsdPtr->triggerEventFd) {
- uint64_t eventFdVal;
- i = read(tsdPtr->triggerEventFd, &eventFdVal,
- sizeof(eventFdVal));
- if ((i != sizeof(eventFdVal)) && (errno != EAGAIN)) {
- Tcl_Panic(
- "Tcl_WaitForEvent: read from %p->triggerEventFd: %s",
- (void *) tsdPtr, strerror(errno));
- }
- continue;
+ if (filePtr->fd == tsdPtr->triggerEventFd) {
+ uint64_t eventFdVal;
+
+ i = read(tsdPtr->triggerEventFd, &eventFdVal, sizeof(eventFdVal));
+ if ((i != sizeof(eventFdVal)) && (errno != EAGAIN)) {
+ Tcl_Panic("%s: read from %p->triggerEventFd: %s",
+ "Tcl_WaitForEvent", (void *) tsdPtr, strerror(errno));
}
+ continue;
+ }
#else /* !HAVE_EVENTFD */
- if (filePtr->fd == tsdPtr->triggerPipe[0]) {
- char triggerPipeVal;
- i = read(tsdPtr->triggerPipe[0], &triggerPipeVal,
- sizeof(triggerPipeVal));
- if ((i != sizeof(triggerPipeVal)) && (errno != EAGAIN)) {
- Tcl_Panic(
- "Tcl_WaitForEvent: read from %p->triggerPipe[0]: %s",
- (void *) tsdPtr, strerror(errno));
- }
- continue;
+ if (filePtr->fd == tsdPtr->triggerPipe[0]) {
+ char triggerPipeVal;
+
+ i = read(tsdPtr->triggerPipe[0], &triggerPipeVal,
+ sizeof(triggerPipeVal));
+ if ((i != sizeof(triggerPipeVal)) && (errno != EAGAIN)) {
+ Tcl_Panic("%s: read from %p->triggerPipe[0]: %s",
+ "Tcl_WaitForEvent", (void *) tsdPtr, strerror(errno));
}
+ continue;
+ }
#endif /* HAVE_EVENTFD */
- if (!mask) {
- continue;
- }
+ if (!mask) {
+ continue;
+ }
- /*
- * Don't bother to queue an event if the mask was previously
- * non-zero since an event must still be on the queue.
- */
+ /*
+ * Don't bother to queue an event if the mask was previously non-zero
+ * since an event must still be on the queue.
+ */
- if (filePtr->readyMask == 0) {
- FileHandlerEvent *fileEvPtr = (FileHandlerEvent *)
- Tcl_Alloc(sizeof(FileHandlerEvent));
+ if (filePtr->readyMask == 0) {
+ FileHandlerEvent *fileEvPtr = (FileHandlerEvent *)
+ Tcl_Alloc(sizeof(FileHandlerEvent));
- fileEvPtr->header.proc = FileHandlerEventProc;
- fileEvPtr->fd = filePtr->fd;
- Tcl_QueueEvent((Tcl_Event *) fileEvPtr, TCL_QUEUE_TAIL);
- }
- filePtr->readyMask = mask;
+ fileEvPtr->header.proc = FileHandlerEventProc;
+ fileEvPtr->fd = filePtr->fd;
+ Tcl_QueueEvent((Tcl_Event *) fileEvPtr, TCL_QUEUE_TAIL);
}
- return 0;
+ filePtr->readyMask = mask;
}
+ return 0;
}
#endif /* NOTIFIER_EPOLL && TCL_THREADS */
+#else
+TCL_MAC_EMPTY_FILE(unix_tclEpollNotfy_c)
#endif /* !HAVE_COREFOUNDATION */
/*