summaryrefslogtreecommitdiffstats
path: root/generic/tclIO.c
diff options
context:
space:
mode:
authorsebres <sebres@users.sourceforge.net>2017-07-10 08:55:58 (GMT)
committersebres <sebres@users.sourceforge.net>2017-07-10 08:55:58 (GMT)
commit1eda39625d8db0707bd1584697f58afde2494f12 (patch)
tree0c0a6501653effac571ccc8d0b7dec7b5106a5eb /generic/tclIO.c
parent0682a9d1c29428c039fde55c05a2d45eca36a1a1 (diff)
downloadtcl-1eda39625d8db0707bd1584697f58afde2494f12.zip
tcl-1eda39625d8db0707bd1584697f58afde2494f12.tar.gz
tcl-1eda39625d8db0707bd1584697f58afde2494f12.tar.bz2
Stability fix: queue epoch to guarantee avoid broken queue, service level to avoid reset block time by nested event-cycles (if Tcl_SetTimer does not create it), etc.
Fixed retarded events (using new retarded list, the involve of the retarded events occurs only after checking of all event sources now). Two opportunities to retard event: - lazy, using the same event-object: in the handler set event->proc to new (or the same) handler (fast, possible only if not entering new event-cycle in handler); - create the event with new position "TCL_QUEUE_RETARDED"; New inline functions TclpQueueEventClientData / TclpQueueEventEx to fast creating resp. queuing event with extra data.
Diffstat (limited to 'generic/tclIO.c')
-rw-r--r--generic/tclIO.c34
1 files changed, 20 insertions, 14 deletions
diff --git a/generic/tclIO.c b/generic/tclIO.c
index b761e1d..e2c4f32 100644
--- a/generic/tclIO.c
+++ b/generic/tclIO.c
@@ -8399,6 +8399,21 @@ Tcl_NotifyChannel(
tsdPtr->nestedHandlerPtr = nh.nestedHandlerPtr;
}
+static inline Tcl_Event *
+CreateChannelScheduledEvent(
+ Channel *chanPtr)
+{
+#ifdef SYNTHETIC_EVENT_TIME
+ Tcl_Time blckTime;
+
+ blckTime.sec = SYNTHETIC_EVENT_TIME / 1000000;
+ blckTime.usec = SYNTHETIC_EVENT_TIME % 1000000;
+ Tcl_SetMaxBlockTime(&blckTime);
+#endif
+ return TclpQueueEventClientData(ChannelScheduledProc, chanPtr,
+ TCL_QUEUE_RETARDED);
+}
+
/*
*----------------------------------------------------------------------
*
@@ -8492,12 +8507,7 @@ UpdateInterest(
mask &= ~TCL_EXCEPTION;
if (!statePtr->schedEvent) {
- Tcl_Event *evPtr = (Tcl_Event *)ckalloc(
- sizeof(Tcl_Event) + sizeof(Channel*));
- *(Channel**)(evPtr+1) = chanPtr;
- evPtr->proc = ChannelScheduledProc;
- statePtr->schedEvent = evPtr;
- Tcl_QueueEvent(evPtr, TCL_QUEUE_TAIL);
+ statePtr->schedEvent = CreateChannelScheduledEvent(chanPtr);
}
}
}
@@ -8544,13 +8554,13 @@ ChannelScheduledProc(
* before UpdateInterest gets called by Tcl_NotifyChannel.
*/
- statePtr->schedEvent->proc = ChannelScheduledProc; /* reattach to tail */
-
+ statePtr->schedEvent = CreateChannelScheduledEvent(chanPtr);
+
Tcl_Preserve(statePtr);
Tcl_NotifyChannel((Tcl_Channel) chanPtr, TCL_READABLE);
Tcl_Release(statePtr);
- return 1;
+ return 1; /* next cycle */
}
statePtr->schedEvent = NULL; /* event done. */
@@ -9179,11 +9189,7 @@ TclCopyChannel(
*/
if ((nonBlocking == CHANNEL_NONBLOCKING) && (toRead == 0)) {
- Tcl_Event *evPtr = (Tcl_Event *)ckalloc(
- sizeof(Tcl_Event) + sizeof(ClientData*));
- *(ClientData*)(evPtr+1) = csPtr;
- evPtr->proc = ZeroTransferEventProc;
- Tcl_QueueEvent(evPtr, TCL_QUEUE_TAIL);
+ TclpQueueEventClientData(ZeroTransferEventProc, csPtr, TCL_QUEUE_TAIL);
return 0;
}