From 0724ad11901b1b93fd79ec948eb4997cbbee73c3 Mon Sep 17 00:00:00 2001 From: andreas_kupries Date: Fri, 17 Mar 2006 17:24:10 +0000 Subject: * doc/chan.n: Updated with documentation for the commands 'chan create' and 'chan postevent' (TIP #219). * doc/refchan.n: New file. Documentation of the command handler API for reflected channels (TIP #219). --- ChangeLog | 8 ++ doc/chan.n | 105 ++++++++++++++++++++-- doc/refchan.n | 278 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 385 insertions(+), 6 deletions(-) create mode 100644 doc/refchan.n diff --git a/ChangeLog b/ChangeLog index c74fe12..71d493b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +2006-03-17 Andreas Kupries + + * doc/chan.n: Updated with documentation for the commands 'chan + create' and 'chan postevent' (TIP #219). + + * doc/refchan.n: New file. Documentation of the command handler + API for reflected channels (TIP #219). + 2006-03-17 Joe Mistachkin * unix/tclUnixPort.h: Include pthread.h prior to pthread_np.h diff --git a/doc/chan.n b/doc/chan.n index 21484f6..73d9c09 100644 --- a/doc/chan.n +++ b/doc/chan.n @@ -4,7 +4,7 @@ '\" See the file "license.terms" for information on usage and redistribution '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES. '\" -'\" RCS: @(#) $Id: chan.n,v 1.2 2005/06/10 15:22:43 dkf Exp $ +'\" RCS: @(#) $Id: chan.n,v 1.3 2006/03/17 17:24:10 andreas_kupries Exp $ .so man.macros .TH chan n 8.5 Tcl "Tcl Built-In Commands" .BS @@ -14,7 +14,6 @@ chan \- Read, write and manipulate channels .SH SYNOPSIS \fBchan \fIoption\fR ?\fIarg arg ...\fR? .BE - .SH DESCRIPTION .PP This command provides several operations for reading from, writing to @@ -41,7 +40,7 @@ deletes all existing file-events registered on the channel. .RS .PP As part of closing the channel, all buffered output is flushed to the -channel's outpuot device, any buffered input is discarded, the +channel's output device, any buffered input is discarded, the underlying operating system resource is closed and \fIchannelId\fR becomes unavailable for future use. .PP @@ -320,6 +319,67 @@ to the output encoding. The behaviour of the system for bytes which are not valid UTF-8 characters is undefined in this case. .RE .TP +\fBchan create \fImode cmdPrefix\fR +. +This subcommand creates a new script level channel using the command +prefix \fIcmdPrefix\fR as its handler. Any such channel is called a +\fBreflected\fR channel. The specified command prefix, \fBcmdPrefix\fR, +must be a non-empty list, and should provide the API described in the +\fBreflectedchan\fR manual page. The handle of the new channel is +returned as the result of the \fBchan create\fR command, and the +channel is open. Use either \fBclose\fR or \fBchan close\fR to remove +the channel. +.RS +The argument \fImode\fR specifies if the new channel is opened for +reading, writing, or both. It has to be a list containing any of the +strings "\fBread\fR" or "\fBwrite\fR". The list must have at least one +element, as a channel you can neither write to nor read from makes no +sense. The handler command for the new channel must support the chosen +mode, or an error is thrown. +.PP +The command prefix is executed in the global namespace, at the top of +call stack, following the appending of arguments as described in the +\fBreflectedchan\fR manual page. Command resolution happens at the +time of the call. Renaming the command, or destroying it means that +the next call of a handler method may fail, causing the channel +command invoking the handler to fail as well. Depending on the +subcommand being invoked, the error message may not be able to explain +the reason for that failure. +.PP +Every channel created with this subcommand knows which interpreter it +was created in, and only ever executes its handler command in that +interpreter, even if the channel was shared with and/or was moved into +a different interpreter. Each reflected channel also knows the thread +it was created in, and executes its handler command only in that +thread, even if the channel was moved into a different thread. To this +end all invokations of the handler are forwarded to the original +thread by posting special events to it. This means that the original +thread (i.e. the thread that executed the \fBchan create\fR command) +must have an active event loop, i.e. it must be able to process such +events. Otherwise the thread sending them will \fIblock +indefinitely\fR. Deadlock may occur. +.PP +Note that this permits the creation of a channel whose two endpoints +live in two different threads, providing a stream-oriented bridge +between these threads. In other words, we can provide a way for +regular stream communication between threads instead of having to send +commands. +.PP +When a thread or interpreter is deleted, all channels created with +this subcommand and using this thread/interpreter as their computing +base are deleted as well, in all interpreters they have been shared +with or moved into, and in whatever thread they have been transfered +to. While this pulls the rug out under the other thread(s) and/or +interpreter(s), this cannot be avoided. Trying to use such a channel +will cause the generation of a regular error about unknown channel +handles. +.PP +This subcommand is \fBsafe\fR and made accessible to safe +interpreters. While it arranges for the execution of arbitrary Tcl +code the system also makes sure that the code is always executed +within the safe interpreter. +.RE +.TP \fBchan eof \fIchannelId\fR . Test whether the last input operation on the channel called @@ -433,6 +493,41 @@ Produces a list of all channel names. If \fIpattern\fR is specified, only those channel names that match it (according to the rules of \fBstring match\fR) will be returned. .TP +\fBchan postevent \fIchannel eventspec\fR +. +This subcommand is used by command handlers specified with \fBchan +create\fR. It notifies the channel represented by the handle +\fIchannel\fR that the event(s) listed in the \fIeventspec\fR have +occurred. The argument has to be a list containing any of the strings +"\fBread\fR" and "\fBwrite\fR". The list must contain at least one +element as it does not make sense to invoke the command if there are +no events to post. +.RS +Note that this subcommand can only be used with channel handles that +were created/opened by \fBchan create\fR. All other channels will +cause this subcommand to report an error. +.PP +As only the Tcl level of a channel, i.e. its command handler, should +post events to it we also restrict the usage of this command to the +interpreter that created the channel. In other words, posting events +to a reflected channel from an interpreter that does not contain it's +implementation is not allowed. Attempting to post an event from any +other interpreter will cause this subcommand to report an error. +.PP +Another restriction is that it is not possible to post events that the +I/O core has not registered an interest in. Trying to do so will cause +the method to throw an error. See the command handler method +\fBwatch\fR described in \fBreflectedchan\fR, the document specifying +the API of command handlers for reflected channels. +.PP +This command is \fBsafe\fR and made accessible to safe interpreters. +It can trigger the execution of \fBchan event\fR handlers, whether in the +current interpreter or in other interpreters or other threads, even +where the event is posted from a safe interpreter and listened for by +a trusted interpreter. \fBChan event\fR handlers are \fIalways\fR +executed in the interpreter that set them up. +.RE +.TP \fBchan puts\fR ?\fB\-nonewline\fR? ?\fIchannelId\fR? \fIstring\fR . Writes \fIstring\fR to the channel named \fIchannelId\fR followed by a @@ -578,11 +673,9 @@ Sets the byte length of the underlying data stream for the channel named \fIchannelId\fR to be \fIlength\fR (or to the current byte offset within the underlying data stream if \fIlength\fR is omitted). The channel is flushed before truncation. - .SH "SEE ALSO" close(n), eof(n), fblocked(n), fconfigure(n), fcopy(n), file(n), fileevent(n), flush(n), gets(n), open(n), puts(n), read(n), seek(n), -socket(n), tell(n) - +socket(n), tell(n), reflectedchan(n) .SH KEYWORDS channel, input, output, events, offset diff --git a/doc/refchan.n b/doc/refchan.n new file mode 100644 index 0000000..a35ec53 --- /dev/null +++ b/doc/refchan.n @@ -0,0 +1,278 @@ +'\" +'\" Copyright (c) 2006 Andreas Kupries +'\" +'\" See the file "license.terms" for information on usage and redistribution +'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES. +'\" +'\" RCS: @(#) $Id: refchan.n,v 1.1 2006/03/17 17:24:10 andreas_kupries Exp $ +.so man.macros +.TH reflectedchan n 8.5 Tcl "Tcl Built-In Commands" +.BS +'\" Note: do not modify the .SH NAME line immediately below! +.SH NAME +reflectedchan \- Command handler API of reflected channels, version 1 +.SH SYNOPSIS +\fBcmdPrefix \fIoption\fR ?\fIarg arg ...\fR? +.BE +.SH DESCRIPTION +.PP +The Tcl-level handler for a reflected channel has to be a command with +subcommands (termed an \fIensemble\fR, as it is a command such as that +created by \fBnamespace ensemble create\fR, though the implementation +of handlers for reflected channel \fIis not\fR tied to \fBnamespace +ensemble\fRs in any way). Note that \fIcmdPrefix\fR is whatever was +specified in the call to \fBchan create\fR, and may consist of +multiple arguments; this will be expanded to multiple words in place +of the prefix. +.PP +Of all the possible subcommands, the handler \fImust\fR support +\fBinitialize\fR, \fBfinalize\fR, and \fBwatch\fR. Support for the +other subcommands is optional. +.SS "MANDATORY SUBCOMMANDS" +.TP +\fIcmdPrefix \fBinitialize \fIchannel mode\fR +. +An invokation of this subcommand will be the first call the +\fIcmdPrefix\fR will receive for the specified new \fBchannel\fR. It +is the responsibility of this subcommand to set up any internal data +structures required to keep track of the channel and its state. +.RS +.PP +The return value of the method has to be a list containing the names +of all subcommands supported by the \fIcmdPrefix\fR. This also tells +the Tcl core which version of the API for reflected channels is used by +this command handler. +.PP +Any error thrown by the method will abort the creation of the channel +and no channel will be created. The thrown error will appear as error +thrown by \fBchan create\fR. Any exception other than an \fBerror\fR +(e.g. \fBbreak\fR, etc.) is treated as (and converted to) an error. +.PP +\fBNote:\fR If the creation of the channel was aborted due to failures +here, then the \fBfinalize\fR subcommand will not be called. +.PP +The \fImode\fR argument tells the handler whether the channel was +opened for reading, writing, or both. It is a list containing any of +the strings "\fBread\fR" or "\fBwrite\fR". The list will always +contain at least one element. +.PP +The subcommand must throw an error if the chosen mode is not +supported by the \fIcmdPrefix\fR. +.RE +.TP +\fIcmdPrefix \fBfinalize \fIchannel\fR +. +An invokation of this subcommand will be the last call the +\fIcmdPrefix\fR will receive for the specified \fIchannel\fR. It will +be generated just before the destruction of the data structures of the +channel held by the Tcl core. The command handler \fImust not\fR +access the \fIchannel\fR anymore in no way. Upon this subcommand being +called, any internal resources allocated to this channel must be +cleaned up. +.RS +.PP +The return value of this subcommand is ignored. +.PP +If the subcommand throws an error the command which caused its +invocation (usually \fBclose\fR) will appear to have thrown this +error. Any exception beyond \fIerror\fR (e.g. \fIbreak\fR, etc.) is +treated as (and converted to) an error. +.PP +This subcommand is not invoked if the creation of the channel was +aborted during \fBinitialize\fR (See above). +.RE +.TP +\fIcmdPrefix \fBwatch \fIchannel eventspec\fR +. +This subcommand notifies the \fIcmdPrefix\fR that the specified +\fIchannel\fR is interested in the events listed in the +\fIeventspec\fR. This argument is a list containing any of "\fBread\fR" +and "\fBwrite\fR". The list may be empty, which signals that the +channel does not wish to be notified of any events. In that situation, +the handler should disable event generation completely. +.RS +.PP +\fBWarning:\fR Any return value of the subcommand is ignored. This +includes all errors thrown by the subcommand, break, continue, and +custom return codes. +.PP +This subcommand interacts with \fBchan postevent\fR. Trying to post an +event which was not listed in the last call to \fBwatch\fR will cause +\fBchan postenvent\fR to throw an error. +.RE +.SS "OPTIONAL SUBCOMMANDS" +.TP +\fIcmdPrefix \fBread \fIchannel count\fR +. +This \fIoptional\fR subcommand is called when the user requests data +from a channel. \fIcount\fR specifies how many \fBbytes\fR have been +requested. If the subcommand is not supported then it is not possible +to read from the channel handled by the command. +.RS +.PP +The return value of this subcommand is taken as the requested data +\fIbytes\fR. If the returned data contains more bytes than requested, +an error will be signalled and later thrown by the command which +performed the read (usually \fBgets\fR or \fBread\fR). However, +returning fewer bytes than requested is acceptable. +.PP +If the subcommand throws an error, the command which caused its +invocation (usually \fBgets\fR, or \fBread\fR) will appear to have +thrown this error. Any exception beyond \fIerror\fR, (e.g. +\fIbreak\fR, etc.) is treated as and converted to an error. +.RE +.TP +\fIcmdPrefix \fBwrite \fIchannel data\fR +. +This \fIoptional\fR subcommand is called when the user writes data to +the channel. The \fIdata\fR argument contains \fIbytes\fR, not +characters. Any type of transformation (EOL, encoding) configured for +the channel has already been applied at this point. If this subcommand +is not supported then it is not possible to write to the channel +handled by the command. +.RS +.PP +The return value of the subcommand is taken as the number of bytes +written by the channel. Anything non-numeric will cause an error to be +signaled and later thrown by the command which performed the write. A +negative value implies that the write failed. Returning a value +greater than the number of bytes given to the handler, or zero, is +forbidden and will cause the Tcl core to throw an error. +.PP +If the subcommand throws an error the command which caused its +invocation (usually \fBputs\fR) will appear to have thrown this error. +Any exception beyond \fIerror\fR (e.g. \fIbreak\fR, etc.) is treated +as and converted to an error. +.RE +.TP +\fIcmdPrefix \fBseek \fIchannel offset base\fR +. +This \fIoptional\fR subcommand is responsible for the handling of +\fBseek\fR and \fBtell\fR requests on the channel. If it is not +supported then seeking will not be possible for the channel. +.RS +.PP +The \fIbase\fR argument is one of +.TP 10 +\fBstart\fR +. +Seeking is relative to the beginning of the channel. +.TP 10 +\fBcurrent\fR +. +Seeking is relative to the current seek position. +.TP 10 +\fBend\fR +. +Seeking is relative to the end of the channel. +.PP +The \fIbase\fR argument of the builtin \fBchan seek\fR command takes +the same names. +.PP +The \fIoffset\fR is an integer number specifying the amount of +\fBbytes\fR to seek forward or backward. A positive number should seek +forward, and a negative number should seek backward. +.PP +A channel may provide only limited seeking. For example sockets can +seek forward, but not backward. +.PP +The return value of the subcommand is taken as the (new) location of +the channel, counted from the start. This has to be an integer number +greater than or equal to zero. +.PP +If the subcommand throws an error the command which caused its +invocation (usually \fBseek\fR, or \fBtell\fR) will appear to have +thrown this error. Any exception beyond \fIerror\fR (e.g. \fIbreak\fR, +etc.) is treated as and converted to an error. +.PP +The offset/base combination of 0/"\fBcurrent\fR" signals a \fBtell\fR +request, i.e. seek nothing relative to the current location, making +the new location identical to the current one, which is then returned. +.RE +.TP +\fIcmdPrefix \fBconfigure \fIchannel option value\fR +. +This \fIoptional\fR subcommand is for writing the type specific +options. The \fIoption\fR argument indicates the option to be written, +and the \fIvalue\fR argument indicates the value to set the option to. +.RS +.PP +This subcommand will never try to update more than one option at a +time; that is behavior implemented in the Tcl channel core. +.PP +The return value of the subcommand is ignored. +.PP +If the subcommand throws an error the command which performed the +(re)configuration or query (usually \fBfconfigure\fR or \fBchan +configure\fR) will appear to have thrown this error. Any exception +beyond \fIerror\fR (e.g. \fIbreak\fR, etc.) is treated as and +converted to an error. +.RE +.TP +\fIcmdPrefix \fBcget \fIchannel option\fR +. +This \fIoptional\fR subcommand is used when reading a single type +specific option. If this subcommand is supported then the subcommand +\fBcgetall\fR must be supported as well. +.RS +.PP +The subcommand should return the value of the specified \fIoption\fR. +.PP +If the subcommand throws an error, the command which performed the +(re)configuration or query (usually \fBfconfigure\fR) will appear to +have thrown this error. Any exception beyond \fIerror\fR (e.g. +\fIbreak\fR, etc.) is treated as and converted to an error. +.RE +.TP +\fIcmdPrefix \fBcgetall \fIchannel\fR +. +This \fIoptional\fR subcommand is used for reading all type specific +options. If this subcommand is supported then the subcommand +\fBcget\fR has to be supported as well. +.RS +.PP +The subcommand should return a list of all options and their values. +This list must have an even number of elements. +.PP +If the subcommand throws an error the command which performed the +(re)configuration or query (usually \fBfconfigure\fR) will appear to +have thrown this error. Any exception beyond \fIerror\fR (e.g. +\fIbreak\fR, etc.) is treated as and converted to an error. +.RE +.TP +\fIcmdPrefix \fBblocking \fIchannel mode\fR +. +This \fIoptional\fR subcommand handles changes to the blocking mode of +the channel. The \fImode\fR is a boolean flag. A true value means that +the channel has to be set to blocking, and a false value means that +the channel should be non-blocking. +.RS +.PP +The return value of the subcommand is ignored. +.PP +If the subcommand throws an error the command which caused its +invocation (usually \fBfconfigure\fR) will appear to have thrown this +error. Any exception beyond \fIerror\fR (e.g. \fIbreak\fR, etc.) is +treated as and converted to an error. +.RE +.SH NOTES +Some of the functions supported in channels defined in Tcl's C +interface are not available to channels reflected to the Tcl level. +.PP +The function \fBTcl_DriverGetHandleProc\fR is not supported; i.e. +reflected channels do not have OS specific handles. +.PP +The function \fBTcl_DriverHandlerProc\fI is not supported. This driver +function is relevant only for stacked channels, i.e. transformations. +Reflected channels are always base channels, not transformations. +.PP +The function \fBTcl_DriverFlushProc\fR is not supported. This is +because the current generic I/O layer of Tcl does not use this +function anywhere at all. Therefore support at the Tcl level makes no +sense either. This may be altered in the future (through extending the +API defined here and changing its version number) should the function +be used at some time in the future. +.SH "SEE ALSO" +chan(n) +.SH KEYWORDS +channel, reflection -- cgit v0.12