Next: , Previous: Miscellaneous I/O internals, Up: I/O system


4.5.4 Channels

Channels represent the OS's native I/O transmission channels. On Unix, channels are essentially boxed file descriptors, for example. The only operations on channels are block reads & writes. Blocks in this sense may be either strings or byte vectors.

4.5.4.1 Low-level channel operations

The low-level base of the interface to channels described here is exported from the channels structure.

— procedure: channel? –> boolean

Disjoint type predicate for channels.

— procedure: channel-id channel –> value
— procedure: channel-status channel –> integer-enumerand
— procedure: channel-os-index channel –> integer

Channel-id returns channel's id. The id is some identifying characteristic of channels. For example, file channels' ids are usually the corresponding filenames; channels such as the standard input, output, or error output channels have names like "standard input" and "standard output". Channel-status returns the current status of channel; see the channel-status-option enumeration below. Channel-os-index returns the OS-specific integer index of channel. On Unix, for example, this is the channel's file descriptor.

— procedure: open-channel filename option close-silently? –> channel

Open-channel opens a channel for a file given its filename. Option specifies what type of channel this is; see the channel-status-option enumeration below. Close-silently? is a boolean that specifies whether a message should be printed (on Unix, to stderr) when the resulting channel is closed after a garbage collector finds it unreachable.

— procedure: close-channel channel –> unspecified

Closes channel after aborting any potential pending I/O transactions it may have been involved with.

— procedure: channel-ready? channel –> boolean

If channel is an input channel: returns #t if there is input ready to be read from channel or #f if not; if channel is an output channel: returns #t if a write would immediately take place upon calling channel-maybe-write, i.e. channel-maybe-write would not return #f, or #f if not.

— procedure: channel-maybe-read channel buffer start-index octet-count wait? –> octet count read, error status cell, EOF object, or #f
— procedure: channel-maybe-write channel buffer start-index octet-count –> octet count written, error status cell, or #f
— procedure: channel-abort channel –> unspecified

Channel-maybe-read attempts to read octet-count octets from channel into buffer, starting at start-index. If a low-level I/O error occurs, it returns a cell containing a token given by the operating system indicating what kind of error occurred. If wait? is #t, and channel is not ready to be read from, channel is registered for the VM's event polling mechanism, and channel-maybe-read returns #f. Otherwise, it returns either the number of octets read, or an EOF object if channel was was at the end.

Channel-maybe-write attempts to write octet-count octets to channel from buffer, starting at start-index. If a low-level I/O error occurs, it returns a cell indicating a token given by the operating system indicating what kind of error occurred. If no such low-level error occurs, it registers channel for the VM's event polling mechanism and returns #f iff zero octets were immediately written or the number of octets immediately written if any were.

Channel-abort aborts any pending operation registered for the VM's event polling mechanism.

— procedure: open-channels-list –> channel-list

Returns a list of all open channels in order of the os-index field.

— enumeration: channel-status-option
          (define-enumeration channel-status-option
            (closed
             input
             output
             special-input
             special-output))

Enumeration for a channel's status. The closed enumerand is used only after a channel has been closed. Note that this is not suitable for a bit mask; that is, one may choose exactly one of the enumerands, not use a bit mask of status options. For example, to open a file frob for input that one wishes the garbage collector to be silent about on closing it:

          (open-channel "frob"
                        (enum channel-status-option input)
                        #t)
              => #{Input-channel "frob"}
4.5.4.2 Higher-level channel operations

More convenient abstractions for operating on channels, based on condition variables, are provided from the channel-i/o structure. They are integrated with Scheme48's optimistic concurrency facilities.

Note: Transactions on channels can not be atomic in the sense of optimistic concurrency. Since they involve communication with the outside world, they are irrevocable transactions, and thus an invalidated proposal cannot retract the transaction on the channel.

— procedure: channel-maybe-commit-and-read channel buffer start-index octet-count condvar wait? –> committed?
— procedure: channel-maybe-commit-and-write channel buffer start-index octet-count condvar –> committed?

These attempt to commit the current proposal. If they fail, they immediately return #f; otherwise, they proceed, and return #t. If the commit succeeded, these procedures attempt an I/O transaction, without blocking. Channel-maybe-commit-and-read attempts to read octet-count octets into buffer, starting at start-index, from channel. Channel-maybe-commit-and-write attempts to write octet-count octets from buffer, starting at start-index, to channel. Condvar is noted as waiting for the completion of the I/O transaction. When the I/O transaction finally completes — in the case of a read, there are octets ready to be read into buffer from channel or the end of the file was struck; in the case of a write, channel is ready to receive some octets —, condvar is set to the result of the I/O transaction: the number of octets read, an I/O error condition, or an EOF object, for reads; and the number of octets written or an I/O error condition, for writes.

— procedure: channel-maybe-commit-and-close channel closer –> committed?

Attempts to commit the current proposal; if successful, this aborts any wait on channel, sets the result of any condvars waiting on channel to the EOF object, closes channel by applying closer to channel (in theory, closer could be anything; usually, however, it is close-channel from the channels structure or some wrapper around it), and returns #t. If the commit failed, channel-maybe-commit-and-close immediately returns #f.

— procedure: channel-write channel buffer start-index octet-count –> octet-count-written

Atomically attempts to write octet-count octets to channel from buffer, starting at start-index in buffer. If no I/O transaction immediately occurs — what would result in channel-maybe-write returning #f —, channel-write blocks until something does happen. It returns the number of octets written to channel.

— procedure: wait-for-channel channel condvar –> unspecified

Registers condvar so that it will be set to the result of some prior I/O transaction when some I/O event regarding channel occurs. (Contrary to the name, this does not actually wait or block. One must still use maybe-commit-and-wait-for-condvar on condvar; see condition variables.) This is useful primarily in conjunction with calling foreign I/O routines that register channels with the VM's event polling system.

Note: wait-for-channel must be called with interrupts disabled.