summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authordkf <donal.k.fellows@manchester.ac.uk>2021-03-21 13:07:15 (GMT)
committerdkf <donal.k.fellows@manchester.ac.uk>2021-03-21 13:07:15 (GMT)
commitc49b98fa6b7afdb6f63c4abca16d73c56990b715 (patch)
tree9574b65541cfeafbb15d115348443777af5de242
parent4e90ccc6db032c546939cdcdfa33fcecd7122dce (diff)
downloadtcl-c49b98fa6b7afdb6f63c4abca16d73c56990b715.zip
tcl-c49b98fa6b7afdb6f63c4abca16d73c56990b715.tar.gz
tcl-c49b98fa6b7afdb6f63c4abca16d73c56990b715.tar.bz2
Start of doing a clean up of the notifier code.
This originated as trying to stop macOS builds from doing silly warnings during a static build, but I noticed that there were common patterns that belong in generic code instead of being repeated in each of the platform-specific pieces.
-rw-r--r--generic/tclAlloc.c2
-rw-r--r--generic/tclInt.h26
-rw-r--r--generic/tclThreadJoin.c2
-rw-r--r--unix/tclEpollNotfy.c428
-rw-r--r--unix/tclKqueueNotfy.c20
-rw-r--r--unix/tclSelectNotfy.c16
-rw-r--r--unix/tclUnixEvent.c2
7 files changed, 278 insertions, 218 deletions
diff --git a/generic/tclAlloc.c b/generic/tclAlloc.c
index 2043248..03655b9 100644
--- a/generic/tclAlloc.c
+++ b/generic/tclAlloc.c
@@ -748,6 +748,8 @@ TclpRealloc(
}
#endif /* !USE_TCLALLOC */
+#else
+TCL_MAC_EMPTY_FILE(generic_tclAlloc_c)
#endif /* !TCL_THREADS */
/*
diff --git a/generic/tclInt.h b/generic/tclInt.h
index 1d192ff..4c3977a 100644
--- a/generic/tclInt.h
+++ b/generic/tclInt.h
@@ -5145,11 +5145,33 @@ typedef struct NRE_callback {
#endif
/*
+ * Special hack for macOS, where the static linker (technically the 'ar'
+ * command) hates empty object files, and accepts no flags to make it shut up.
+ *
+ * These symbols are otherwise completely useless.
+ *
+ * They can't be written to or written through. They can't be seen by any
+ * other code. They use a separate attribute (supported by all macOS
+ * compilers, which are derivatives of clang or gcc) to stop the compilation
+ * from moaning. They will be excluded during the final linking stage.
+ *
+ * Other platforms get nothing at all. That's good.
+ */
+
+#ifdef MAC_OSX_TCL
+#define TCL_MAC_EMPTY_FILE(name) \
+ static __attribute__((used)) const void *const TclUnusedFile_ ## name; \
+ static const void *const TclUnusedFile_ ## name = NULL;
+#else
+#define TCL_MAC_EMPTY_FILE(name)
+#endif /* MAC_OSX_TCL */
+
+/*
* Other externals.
*/
-MODULE_SCOPE size_t TclEnvEpoch; /* Epoch of the tcl environment
- * (if changed with tcl-env). */
+MODULE_SCOPE size_t TclEnvEpoch; /* Epoch of the tcl environment
+ * (if changed with tcl-env). */
#endif /* _TCLINT */
diff --git a/generic/tclThreadJoin.c b/generic/tclThreadJoin.c
index ba789d3..4d2aca5 100644
--- a/generic/tclThreadJoin.c
+++ b/generic/tclThreadJoin.c
@@ -305,6 +305,8 @@ TclSignalExitThread(
Tcl_MutexUnlock(&threadPtr->threadMutex);
}
+#else
+TCL_MAC_EMPTY_FILE(generic_tclThreadJoin_c)
#endif /* _WIN32 */
/*
diff --git a/unix/tclEpollNotfy.c b/unix/tclEpollNotfy.c
index 3a99e6d..5de6c90 100644
--- a/unix/tclEpollNotfy.c
+++ b/unix/tclEpollNotfy.c
@@ -119,6 +119,9 @@ static Tcl_ThreadDataKey dataKey;
* Forward declarations.
*/
+static void PlatformCreateFileHandler(int fd, int mask,
+ Tcl_FileProc *proc, ClientData clientData);
+static void PlatformDeleteFileHandler(int fd)
static void PlatformEventsControl(FileHandler *filePtr,
ThreadSpecificData *tsdPtr, int op, int isNew);
static void PlatformEventsFinalize(void);
@@ -126,6 +129,7 @@ static void PlatformEventsInit(void);
static int PlatformEventsTranslate(struct epoll_event *event);
static int PlatformEventsWait(struct epoll_event *events,
size_t numEvents, struct timeval *timePtr);
+static int PlatformWaitForEvent(const Tcl_Time *timePtr);
/*
* Incorporate the base notifier API.
@@ -144,8 +148,8 @@ 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.
*
*----------------------------------------------------------------------
*/
@@ -221,7 +225,7 @@ Tcl_FinalizeNotifier(
*----------------------------------------------------------------------
*/
-void
+static void
PlatformEventsControl(
FileHandler *filePtr,
ThreadSpecificData *tsdPtr,
@@ -240,7 +244,8 @@ PlatformEventsControl(
newEvent.events |= EPOLLOUT;
}
if (isNew) {
- newPedPtr = (struct PlatformEventData *)ckalloc(sizeof(struct PlatformEventData));
+ newPedPtr = (struct PlatformEventData *)
+ ckalloc(sizeof(struct PlatformEventData));
newPedPtr->filePtr = filePtr;
newPedPtr->tsdPtr = tsdPtr;
filePtr->pedPtr = newPedPtr;
@@ -249,7 +254,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.
*/
@@ -298,9 +303,8 @@ PlatformEventsControl(
*----------------------------------------------------------------------
*/
-void
-PlatformEventsFinalize(
- void)
+static void
+PlatformEventsFinalize(void)
{
ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
@@ -362,7 +366,7 @@ PlatformEventsFinalize(
*----------------------------------------------------------------------
*/
-void
+static void
PlatformEventsInit(void)
{
ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
@@ -393,7 +397,7 @@ PlatformEventsInit(void)
PlatformEventsControl(filePtr, tsdPtr, EPOLL_CTL_ADD, 1);
if (!tsdPtr->readyEvents) {
tsdPtr->maxReadyEvents = 512;
- tsdPtr->readyEvents = (struct epoll_event *)ckalloc(
+ tsdPtr->readyEvents = (struct epoll_event *) ckalloc(
tsdPtr->maxReadyEvents * sizeof(tsdPtr->readyEvents[0]));
}
LIST_INIT(&tsdPtr->firstReadyFileHandlerPtr);
@@ -416,7 +420,7 @@ PlatformEventsInit(void)
*----------------------------------------------------------------------
*/
-int
+static int
PlatformEventsTranslate(
struct epoll_event *eventPtr)
{
@@ -457,7 +461,7 @@ PlatformEventsTranslate(
*----------------------------------------------------------------------
*/
-int
+static int
PlatformEventsWait(
struct epoll_event *events,
size_t numEvents,
@@ -510,7 +514,7 @@ PlatformEventsWait(
/*
*----------------------------------------------------------------------
*
- * Tcl_CreateFileHandler --
+ * Tcl_CreateFileHandler, CreateFileHandler --
*
* This function registers a file handler with the epoll notifier of the
* thread of the caller.
@@ -540,40 +544,53 @@ Tcl_CreateFileHandler(
if (tclNotifierHooks.createFileHandlerProc) {
tclNotifierHooks.createFileHandlerProc(fd, mask, proc, clientData);
- return;
} else {
- ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
- FileHandler *filePtr;
+ PlatformCreateFileHandler(fd, mask, proc, clientData);
+ }
+}
- for (filePtr = tsdPtr->firstFileHandlerPtr; filePtr != NULL;
- filePtr = filePtr->nextPtr) {
- if (filePtr->fd == fd) {
- break;
- }
- }
- if (filePtr == NULL) {
- filePtr = (FileHandler *)ckalloc(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;
+static void
+PlatformCreateFileHandler(
+ int fd, /* Handle of stream to watch. */
+ int mask, /* OR'ed combination of TCL_READABLE,
+ * TCL_WRITABLE, and TCL_EXCEPTION: indicates
+ * conditions under which proc should be
+ * called. */
+ Tcl_FileProc *proc, /* Function to call for each selected
+ * event. */
+ ClientData clientData) /* Arbitrary data to pass to proc. */
+{
+ ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
+ FileHandler *filePtr;
- PlatformEventsControl(filePtr, tsdPtr,
- isNew ? EPOLL_CTL_ADD : EPOLL_CTL_MOD, isNew);
+ for (filePtr = tsdPtr->firstFileHandlerPtr; filePtr != NULL;
+ filePtr = filePtr->nextPtr) {
+ if (filePtr->fd == fd) {
+ break;
+ }
}
+ if (filePtr == NULL) {
+ filePtr = (FileHandler *) ckalloc(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;
+
+ PlatformEventsControl(filePtr, tsdPtr,
+ isNew ? EPOLL_CTL_ADD : EPOLL_CTL_MOD, isNew);
}
/*
*----------------------------------------------------------------------
*
- * Tcl_DeleteFileHandler --
+ * Tcl_DeleteFileHandler, PlatformDeleteFileHandler --
*
* Cancel a previously-arranged callback arrangement for a file on the
* epoll file descriptor of the thread of the caller.
@@ -597,51 +614,58 @@ Tcl_DeleteFileHandler(
{
if (tclNotifierHooks.deleteFileHandlerProc) {
tclNotifierHooks.deleteFileHandlerProc(fd);
- return;
} else {
- FileHandler *filePtr, *prevPtr;
- ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
+ PlatformDeleteFileHandler(fd);
+ }
+}
- /*
- * Find the entry for the given file (and return if there isn't one).
- */
+static void
+PlatformDeleteFileHandler(
+ int fd) /* Stream id for which to remove callback
+ * function. */
+{
+ FileHandler *filePtr, *prevPtr;
+ ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
- for (prevPtr = NULL, filePtr = tsdPtr->firstFileHandlerPtr; ;
- prevPtr = filePtr, filePtr = filePtr->nextPtr) {
- if (filePtr == NULL) {
- return;
- }
- if (filePtr->fd == fd) {
- break;
- }
+ /*
+ * 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;
+ }
+ }
- /*
- * Update the check masks for this file.
- */
+ /*
+ * Update the check masks for this file.
+ */
- PlatformEventsControl(filePtr, tsdPtr, EPOLL_CTL_DEL, 0);
- if (filePtr->pedPtr) {
- ckfree(filePtr->pedPtr);
- }
+ PlatformEventsControl(filePtr, tsdPtr, EPOLL_CTL_DEL, 0);
+ if (filePtr->pedPtr) {
+ ckfree(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;
- }
- ckfree(filePtr);
+ if (prevPtr == NULL) {
+ tsdPtr->firstFileHandlerPtr = filePtr->nextPtr;
+ } else {
+ prevPtr->nextPtr = filePtr->nextPtr;
}
+ ckfree(filePtr);
}
/*
*----------------------------------------------------------------------
*
- * Tcl_WaitForEvent --
+ * Tcl_WaitForEvent, PlatformWaitForEvent --
*
* 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
@@ -666,166 +690,170 @@ Tcl_WaitForEvent(
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.
- */
-
- struct timeval timeout, *timeoutPtr;
- int numFound, numEvent;
- struct PlatformEventData *pedPtr;
- ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
- int numQueued;
- ssize_t i;
+ return PlatformWaitForEvent(timePtr);
+ }
+}
- /*
- * 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.
- */
+static int
+PlatformWaitForEvent(
+ const Tcl_Time *timePtr) /* Maximum block time, or NULL. */
+{
+ 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;
- 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;
- }
+ /*
+ * 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) {
/*
- * 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().
+ * 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.
*/
- 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 (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 (filePtr->readyMask == 0) {
- FileHandlerEvent *fileEvPtr = (FileHandlerEvent *)
- ckalloc(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 *)
+ ckalloc(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.
+ */
- 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]);
+ 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]);
#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 *)
- ckalloc(sizeof(FileHandlerEvent));
+ if (filePtr->readyMask == 0) {
+ FileHandlerEvent *fileEvPtr = (FileHandlerEvent *)
+ ckalloc(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 */
/*
diff --git a/unix/tclKqueueNotfy.c b/unix/tclKqueueNotfy.c
index 2f1d8e6..fbd38dc 100644
--- a/unix/tclKqueueNotfy.c
+++ b/unix/tclKqueueNotfy.c
@@ -209,7 +209,7 @@ Tcl_FinalizeNotifier(
*----------------------------------------------------------------------
*/
-void
+static void
PlatformEventsControl(
FileHandler *filePtr,
ThreadSpecificData *tsdPtr,
@@ -222,7 +222,8 @@ PlatformEventsControl(
struct stat fdStat;
if (isNew) {
- newPedPtr = (struct PlatformEventData *)ckalloc(sizeof(struct PlatformEventData));
+ newPedPtr = (struct PlatformEventData *)
+ ckalloc(sizeof(struct PlatformEventData));
newPedPtr->filePtr = filePtr;
newPedPtr->tsdPtr = tsdPtr;
filePtr->pedPtr = newPedPtr;
@@ -324,9 +325,8 @@ PlatformEventsControl(
*----------------------------------------------------------------------
*/
-void
-PlatformEventsFinalize(
- void)
+static void
+PlatformEventsFinalize(void)
{
ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
@@ -380,7 +380,7 @@ PlatformEventsFinalize(
*----------------------------------------------------------------------
*/
-void
+static void
PlatformEventsInit(void)
{
ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
@@ -438,7 +438,7 @@ PlatformEventsInit(void)
*----------------------------------------------------------------------
*/
-int
+static int
PlatformEventsTranslate(
struct kevent *eventPtr)
{
@@ -459,7 +459,7 @@ PlatformEventsTranslate(
}
return mask;
}
-
+
/*
*----------------------------------------------------------------------
*
@@ -483,7 +483,7 @@ PlatformEventsTranslate(
*----------------------------------------------------------------------
*/
-int
+static int
PlatformEventsWait(
struct kevent *events,
size_t numEvents,
@@ -842,6 +842,8 @@ Tcl_WaitForEvent(
}
#endif /* NOTIFIER_KQUEUE && TCL_THREADS */
+#else
+TCL_MAC_EMPTY_FILE(unix_tclKqueueNotfy_c)
#endif /* !HAVE_COREFOUNDATION */
/*
diff --git a/unix/tclSelectNotfy.c b/unix/tclSelectNotfy.c
index 1d16114..e40997f 100644
--- a/unix/tclSelectNotfy.c
+++ b/unix/tclSelectNotfy.c
@@ -216,8 +216,8 @@ extern "C" {
typedef struct {
void *hwnd; /* Messaging window. */
unsigned int *message; /* Message payload. */
- size_t wParam; /* Event-specific "word" parameter. */
- size_t lParam; /* Event-specific "long" parameter. */
+ size_t wParam; /* Event-specific "word" parameter. */
+ size_t lParam; /* Event-specific "long" parameter. */
int time; /* Event timestamp. */
int x; /* Event location (where meaningful). */
int y;
@@ -244,8 +244,8 @@ extern void __stdcall CloseHandle(void *);
extern void *__stdcall CreateEventW(void *, unsigned char, unsigned char,
void *);
extern void *__stdcall CreateWindowExW(void *, const void *, const void *,
- unsigned int, int, int, int, int, void *, void *, void *,
- void *);
+ unsigned int, int, int, int, int, void *, void *,
+ void *, void *);
extern unsigned int __stdcall DefWindowProcW(void *, int, void *, void *);
extern unsigned char __stdcall DestroyWindow(void *);
extern int __stdcall DispatchMessageW(const MSG *);
@@ -504,7 +504,7 @@ Tcl_CreateFileHandler(
FD_CLR(fd, &tsdPtr->checkMasks.exception);
}
if (tsdPtr->numFdBits <= fd) {
- tsdPtr->numFdBits = fd+1;
+ tsdPtr->numFdBits = fd + 1;
}
}
}
@@ -573,11 +573,11 @@ Tcl_DeleteFileHandler(
if (fd+1 == tsdPtr->numFdBits) {
int numFdBits = 0;
- for (i = fd-1; i >= 0; i--) {
+ for (i = fd - 1; i >= 0; i--) {
if (FD_ISSET(i, &tsdPtr->checkMasks.readable)
|| FD_ISSET(i, &tsdPtr->checkMasks.writable)
|| FD_ISSET(i, &tsdPtr->checkMasks.exception)) {
- numFdBits = i+1;
+ numFdBits = i + 1;
break;
}
}
@@ -1113,6 +1113,8 @@ NotifierThreadProc(
#endif /* TCL_THREADS */
#endif /* (!NOTIFIER_EPOLL && !NOTIFIER_KQUEUE) || !TCL_THREADS */
+#else
+TCL_MAC_EMPTY_FILE(unix_tclSelectNotfy_c)
#endif /* !HAVE_COREFOUNDATION */
/*
diff --git a/unix/tclUnixEvent.c b/unix/tclUnixEvent.c
index aff7797..f7545db 100644
--- a/unix/tclUnixEvent.c
+++ b/unix/tclUnixEvent.c
@@ -85,6 +85,8 @@ Tcl_Sleep(
}
}
+#else
+TCL_MAC_EMPTY_FILE(unix_tclUnixEvent_c)
#endif /* HAVE_COREFOUNDATION */
/*
* Local Variables: