TIP:            374
Title:          Stackless Vwait
Version:        $Revision: 1.4 $
Author:         Thomas Perschak <tombert@gmx.at>
Author:         Trevor Davel <twylite@crypt.co.za>
State:          Draft
Type:           Project
Vote:           Pending
Created:        13-Aug-2010
Post-History:   
Tcl-Version:    8.7

~ Abstract

This TIP proposes a way to have multiple procedures waiting for an event to happen, where the command that gets executed depends on the order of the
events.

~ Rationale

Suppose you have three (or even more) synchronous procedures each of them
waiting for the socket to be readable. This waiting is implemented with
'''vwait''' - it is not possible to call this procedure event-driven - the
socket is opened and closed inside the same procedure. The current
implementation of '''vwait''' would block the procedure which called
'''vwait''' first, till the last procedure has read all data.

The stackless '''vwait''' would allow to group all similar '''vwait''' calls, define them stackless as whoever-comes-first and so unblock the procedure which has first data to read.

Originally I thought this could be solved with coroutines but I'am not so sure any more. Anyhow I think that the problem - explained later below - could be solved with a stackless '''vwait''' in a very elegant way.  Currently the '''vwait''' command is last-in-first-out, on the basis of the stackless 8.6 core there could be an improvement to make the '''vwait''' command configurable as last-in-last-out or even completely stackless event driven.

~ Specification

This is only a first idea, but it could be similar to named-mutex definitions - so one as to define the group of the '''vwait''' waiting for and the three behaviour types: first-in-last-out, first-in-first-out, whoever-comes-first;

The following command creates a new vwait group with a specified stack behaviour:

| vwaitgroup myvwaitgroup whoever-comes-first

Finally comes the waiting for the '''vwait''' which is similar to the existing
one:

| vwaitnew<myvar>  myvwaitgroup

In addition I would allow a timeout value to be specified:

| vwaitnew<myvar>  myvwaitgroup<mytimeout>

~ Example

This is only a very reduced example, but should show the principle of the
problem:

| proc myproc1 {} {
|    open socket
|    fileevent socket {set myvar 1}
|    vwait myvar
|    read data
| }

Having more than one of these procedure above, the '''vwait''' would block
data reading depending on the '''vwait''' stack.

The new stackless '''vwait''' would look like the following example: On a
global level I would do the following:

| vwaitgroup sockreadgroup whoever-comes-first

Then the procedures:

| proc myproc1 {} {
|    open socket
|    fileevent socket {set myvar 1}
|    vwait myvar sockreadgroup
|    read data
| }

| proc myproc2 {} {
|    open socket
|    fileevent socket {set myvar 1}
|    vwait myvar sockreadgroup
|    read data
| }

| proc myproc3 {} {
|    open socket
|    fileevent socket {set myvar 1}
|    vwait myvar sockreadgroup
|    read data
| }

----

~ Comments

Twylite 2010/08/17: "coroutine-enabled event handling" (http://wiki.tcl.tk/21555) presents pure-Tcl implementations of coroutine-enabled '''vwait''' and '''gets''' that do what this TIP describes without attempting to implement a custom scheduler.

----

~ Copyright

This document has been placed in the public domain.
