Description
Introduction
The set of functions and strucutres that make up the
Buffered Request Streams library provide a means to perform blocking
I/O using a single-threaded, non-blocking
dp
server.
Server objects which utilize Buffered Request
Streams do not guarantee that reads and writes will complete
immediately.
Reads and writes on these objects will complete eventually;
notification is normally sent to the client by means of an IoWait
invocation.
Requirements
Dp Servers that implement blocking I/O need a way to accept and buffer
Tread and
Twrite commands. The server itself must promptly return
to fufill other requests. In other words, the server cannot wait while trying
to satisfy a
Tread on, say, an empty pipe. Instead, the server needs to buffer
the Tread until it can be satisfied.
Furthermore, blocking I/O servers need a way to remove buffered
requests according to their tag. Therefore, while an object
in the server maintains a continuous "stream" of data, it
must also keep track of which data is associated with which request.
Finally, the server must work with a fixed buffer area -- that is,
no memory can be dynamically allocated during server operation.
Implementation
The primary structure in this library is the
buf_stream,
which implements a doubly-linked list of buffers, each containing
Tread or
Twrite requests, depending on the type of
buf_stream. Requests can be
- appended to a buf_stream,
- fufilled by a data xfer between a two buf_streams, or
- removed from a buf_stream at any time prior to being fufilled.
Buf_streams guarantee that requests will be fufilled in the order
in which they were sent. Also guaranteed is an
R-response
(Rread, Rwrite, Rerror) for each Tread or Twrite removed from a buf_stream,
unless it is removed by a Tflush, in which case no response is sent.
Internally, each buf_stream takes buffers from the doubly-linked circular
global buffer list as needed, and relinquishes them as requests
are completed. Hence, the number of request buffers is not dependent
on the number of buffered request streams. Instead, the number of
request
buffers is #defined by REQ_BUFS in srvr-params.h.
The typical server configuration (Fig. 1) has two buf_streams,
one containing Twrite
requests and the other containing Tread requests.
Fig 1: Two streams in a pipe server or an IP server.
Whenever a Tread or Twrite request is sent to the server, it should
be added to the buf_stream using AppendReadRequest or
AppendWriteRequest.
After any Append- function call, the server should attempt a
to satisfy some of the requests pending in its buf_streams
by performing an Xfer command. Tabort requests should
utitlize the RemoveRequest function.
Functions
- InitGlobalBufs ()
-
Initialize a the global buffer list. Must be called
before any of the buffered request streams functions are used.
- InitBufStream (buf_stream *st)
-
Initialize a buf_stream.
- AppendWriteRequest (buf_stream *st, Word session, HalfWord tag,
HalfWord cid, HalfWord count, Byte *buffer)
-
Append a Twrite onto a buf_stream. Sends Rerror if there is
no room left in the buffer.
Note that there is no mechanism for offset.
- AppendReadRequest (buf_stream *st, Word session, HalfWord tag,
HalfWord cid, HalfWord count)
-
Append a Tread onto a buf_stream. Sends Rerror if there is
no room left in the buffer. Note that there is no mechanism for offset.
- RemoveRequest (Word session, HalfWord tag, HalfWord how)
-
Search through all buf_streams for Twrite or Tread requests
matching tag. Removes the requests from their
associated buf_streams and sends Rread, Rwrite, or
no response in accordance with how:
#define BUF_ABORT 0 /* how parameter of RemoveRequest*/
#define BUF_FLUSH 1 /* how parameter of RemoveRequest*/
Note that the buf_stream is not specified in this function.
All buf_streams are searched for requests (there should
be no more than one) matching session and tag.
Internally, a hash table is used to locate requests
quickly by their tag.
- Halfword BytesPending (buf_stream *st)
-
Return the number of bytes available for Xfer in a
read or write stream.
- XferStrStr (buf_stream *st_write, buf_stream *st_read, HalfWord count)
-
Transfer count bytes of data from a write stream
to a read stream. Sends Rread upon completing each
Tread in the read buf_stream.
- XferStrBuf (buf_stream *st_write, Byte *buffer, HalfWord count)
-
Transfer count bytes of data from a write stream
to buffer. The size of the buffer is not checked
before copying data into it.
- XferBufStr (buf_stream *st_read, Byte *buffer, HalfWord count)
-
Transfer count bytes of data from buf
to a read stream. Sends Rread upon completing each
Tread in the read buf_stream.
How to use this library in your server code
- Check
#DEFINES in srvr-params.h
/* Size of each request buffer for blocking i/o */
#define REQ_BUFSZ 4096
/* Number of global request buffers */
#define REQ_BUFS 128
- Include srvr_buf.h in the server code
- Declare your streams in the server code. For example, in a pipe
server we might see:
buf_stream my_test_pipe_stream[2];
Where my_test_pipe_stream[0] would be used as the Tread stream
and my_test_pipe_stream[1] would be used as the Twrite stream.
Mike Berry <berrym@eros-os.org>