Author: Christian Werner <[email protected]>
State: Final
Type: Project
Tcl-Version: 8.7
Vote: Done
Created: 07-Oct-2016
Keywords: Tcl, event loop
Tcl-Branch: tip-455
Vote-Summary: Accepted 4/0/2
Votes-For: BG, JN, KW, SL
Votes-Against: none
Votes-Present: KBK, MC
Abstract
This TIP generalizes the vwait command to allow waiting on zero, one, or more variable changes, on zero or more file events, to time-limit the wait, and to control which kinds of events to await by partially exposing the underlying API, namely Tcl_DoOneEvent().
Rationale
One remarkable property of Tcl is the ability to add traces, i.e. the execution of callback functions, on certain operations affecting variables. The vwait command combines the variable trace facility with a/the event loop, i.e. a/the program main loop awaiting and processing various types of events generated by I/O channels, time, and internal activities of the running Tcl program.
The current implementation of vwait allows opening an unconstrained event loop which is terminated by writing or unsetting exactly one global variable given as argument to vwait.
This proposal extends vwait to terminate its event loop on the occurrence of
Zero or more variable modifications.
Readability/writability of zero or more file channels (usually sockets).
An optional timeout specified as milliseconds as in the after command.
Additional flags to vwait control which types of events are to be dealt with in its event loop, i.e. the underlying Tcl_DoOneEvent() API.
When more than one kind of active input (both, variables and file channels) are involved in an instance of vwait, another flag controls whether any one of the inputs or all inputs must have been activated in order to terminate the event loop. This allows for scenarios where vwait can be used as a kind of "barrier" getting broken if all required conditions are fulfilled, i.e. axe, saw, spade, fire accelerant, water, in order to demolish, burn down, extinct the glow, and finally bury the trellis-work fence.
However, in contrast to the illustrious demolition job, the order of occurrence of events breaking that "barrier" is indeterminate.
If vwait is constrained by a timeout and the time limit is reached, its event loop terminates early and vwait indicates that timeout by a negative integer result. Otherwise, the return value is the remaining number of milliseconds (positive integer which can be zero) of the timeout constraint. This property combined with [302] provides for the implementation of (soft real-time) control loops.
An extended result list can be obtained from vwait by another flag which gives detailed information on the cause of the termination of the event loop.
Proposal
The vwait command shall have the following signature:
vwait var-name - Well-known previously-implemented behaviour.
vwait options ?var-names? - All available enhanced features. More than one variable name may be given, in which case the wait will terminate when any of the variables are written to unless the -all option below is given.
where options are:
--: indicates the end of options
-all: all (except timeout) conditions must be met
-extended: result is a list (see below)
-nofileevents: don't consider file events
-noidleevents: don't consider idle events
-notimerevents: don't consider timer events
-nowindowevents: don't consider window system events
-readable channel: channel becomes readable
-timeout ms: timeout in milliseconds
-variable var-name: var-name is written or unset
-writable channel: channel becomes writable
The return value of vwait is the empty string except when the -timeout and/or -extended options are in effect (see above).
The normal result format when -timeout is given is the number of milliseconds remaining in the wait. Otherwise it's an empty string.
The extended result format is a list having an even number of elements. Odd elements take the values readable, timeleft, variable, and writable, i.e. they qualify the event. Even elements are the corresponding variable and channel names or the remaining number of milliseconds. The list is ordered by the occurrences of the event(s), with the exception of timeleft, which always comes last.
Where the combination of options doesn't make sense or even conflicts, an appropriate error message is thrown, e.g., -timeout and -notimerevents can't be specified at the same time.
If all event types except idle events are excluded, the event loop (Tcl_DoOneEvent) is constrained by TCL_DONT_WAIT.
Interesting analogies to the update command can be inferred: vwait -- is equivalent to update, vwait -nofileevents -notimerevents -nowindoevents is equivalent to update idletasks.
Copyright
This document has been placed in the public domain. In legislations where this concept does not exist the CC0 license applies.