TIP 455: Extensions to [vwait]: Variable Sets and Scripted Access to Tcl_DoOneEvent

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


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 on which kinds of events is to be waited by partially exposing the underlying API, namely Tcl_DoOneEvent().


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 the (a) event loop, i.e., the (a) program main loop waiting 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 to open 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 occurence of

  1. zero or more variable modifications

  2. readability/writability of zero or more file channels (usually sockets)

  3. 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) is involved in an instance of vwait, another flag controls if 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 occurence of events breaking that "barrier" is indeterminate.

If the 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] allows to implement (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.


The vwait command shall have the following signature:

vwait var-name - well known and 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 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 shall be 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 with even number of elements. Odd elements take the values readable, timeleft, variable, and writable, i.e. 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 shall be 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) shall be constrained by TCL_DONT_WAIT.

Interesting analogies to the update command can be infered: vwait -- is equivalent to update, vwait -nofileevents -notimerevents -nowindoevents is equivalent to update idletasks.


This document has been placed in the public domain. In legislations where this concept does not exist the CC0 license applies.