STREAMS represent a collection of system calls, kernel resources, and kernel utility routines that can create, use, and dismantle a stream. A stream is a full-duplex processing and data transfer path between a driver in kernel space and a process in user space.
The STREAMS mechanism constructs a
stream by serially connecting kernel-resident STREAMS components, each
constructed from a specific set of structures. As shown in the Stream Detail diagram, the primary STREAMS
|stream head||Provides the interface between the stream and user processes. Its principal function is to process STREAMS-related user system calls. STREAMS system calls can be used from 64-bit and 32-bit user processes.|
|module||Processes data that travels between the stream head and driver. Modules are optional.|
|stream end||Provides the services of an external input/output device or an internal software driver. The internal software driver is commonly called a pseudo-device driver.|
Figure 10-1. Stream Detail. This diagram shows the user process at the top with a bidirectional arrow going into the kernel space to the stream head. On the downstream path (or left) an arrow travels from the stream head to queue "Bd" in module B, and then an arrow goes to queue "Ad" in module A (with message "Ad" as a parameter). An arrow then travels from queue "Ad" to queue pair in the stream end. The driver routine is connected to the queue pair in the driver. There is a bidirectional arrow from the driver routine to the external interface. On the upstream path (or right), an arrow travels from the queue pair to queue "Au" in module A, and then an arrow travels to queue "Bu" in module B (with message "Bu" as a parameter). An arrow then travels from queue "Bu" to the stream head.
STREAMS defines standard interfaces for character input and output within the system kernel and between the kernel and the rest of the system. The associated mechanism is simple and open-ended. It consists of a set of system calls, kernel resources, and kernel utility routines. The standard interface and open-ended mechanism enable modular, portable development and easy integration of high-performance network services and components. STREAMS does not impose any specific network architecture. Instead, it provides a powerful framework with a consistent user interface that is compatible with the existing character input/output interface.
Using a combination of system calls, kernel routines, and kernel utilities, STREAMS passes data between a driver and the stream head in the form of messages. Messages that are passed from the stream head toward the driver are said to travel downstream while messages passed in the other direction travel upstream.
The stream head transfers data between the data space of a user process and STREAMS kernel data space. Data sent to a driver from a user process is packaged into STREAMS messages and transmitted downstream. Downstream messages arriving at the stream head are processed by the stream head, and data is copied from user buffers. STREAMS can insert one or more modules into a stream between the stream head and the driver to process data passing between the two.
The stream head provides an interface between the stream and an application program. The stream head processes STREAMS-related operations from the application and performs the bidirectional transfer of data and information between the application (in user space) and messages (in STREAMS kernel space).
Messages are the only means of transferring data and communicating within a stream. A STREAMS message contains data, status or control information, or a combination of both. Each message includes a specified message type indicator that identifies the contents.
See "STREAMS Messages" for more information about the STREAMS message-passing scheme.
A module performs intermediate transformations on messages passing between the stream head and the driver. Zero or more modules can exist in a stream (zero when the driver performs all the required character and device processing).
Each module is constructed from a pair of QUEUE structures (see the Au/Ad QUEUE pair and the Bu/Bd QUEUE pair in the Stream Detail diagram shown previously). A pair of such structures is required to implement the bidirectional and symmetrical attributes of a stream. One QUEUE (such as the Au or Bu QUEUE) performs functions on messages passing upstream through the module. The other QUEUE (the Ad or Bd QUEUE) performs another set of functions on downstream messages. (A QUEUE, which is part of a module, is different from a message queue, which is described in "STREAMS Flow Control" .)
Each of the two QUEUEs in a module generally have distinct functions; that is, unrelated processing procedures and data. The QUEUEs operate independently so that the Au QUEUE does not know if a message passes though the Ad QUEUE unless the Ad QUEUE is programmed to inform it. Messages and data can be shared only if the developer specifically programs the module functions to perform the sharing.
Each QUEUE can directly access the adjacent QUEUE in the direction of message flow (for example, Au to Bu or stream head to Bd). In addition, within a module, a QUEUE can readily locate its mate and access its messages (for example, for echoing) and data.
Each QUEUE in a module can contain or point to:
See "Put and Service Procedures" for more information about processing procedures.
In general, each of the two QUEUEs in a module has a distinct set of all these elements. Additional module elements are described later. Although depicted as distinct from modules, a stream head and a stream end also contain a pair of QUEUEs.
A stream end is a module in which the module processing procedures are the driver routines. The procedures in the stream end are different from those in other modules because they are accessible from an external device and because the STREAMS mechanism allows multiple streams to be connected to the same driver.
The driver can be a device driver, providing an interface between kernel space and an external communications device, or an internal pseudo-device driver. A pseudo-device driver is not directly related to any external device, and it performs functions internal to the kernel.
Device drivers must transform all data and status or control information between STREAMS message formats and their external representation. See "STREAMS Drivers and Modules" for more information on the differences between STREAMS and character device drivers.
STREAMS modularity and design reflect the layers and option characteristics of contemporary networking architectures. The basic components in a STREAMS implementation are referred to as modules. The modules, which reside in the kernel, offer a set of processing functions and associated service interfaces. From a user level, modules can be selected dynamically and interconnected to provide any rational processing sequence. Kernel programming, assembly, and link editing are not required to create the interconnection. Modules can also be dynamically plugged into existing connections from user level. STREAMS modularity allows:
In addition to modularity, STREAMS
provides developers with integral functions, a library of utility routines,
and facilities that expedite software design and implementation. The
principal facilities are:
|Buffer management||Maintains an independent buffer pool for STREAMS.|
|Scheduling||Incorporates a scheduling mechanism for STREAMS.|
|Asynchronous operation of STREAMS and user processes||Allows STREAMS-related operations to be performed efficiently from user level.|
Other facilities include flow control to conserve STREAMS memory and processing resources.