chiark / gitweb /
New manual pages.
authormdw <mdw>
Sun, 16 Jul 2000 18:56:47 +0000 (18:56 +0000)
committermdw <mdw>
Sun, 16 Jul 2000 18:56:47 +0000 (18:56 +0000)
man/pkbuf.3 [new file with mode: 0644]
man/selpk.3 [new file with mode: 0644]

diff --git a/man/pkbuf.3 b/man/pkbuf.3
new file mode 100644 (file)
index 0000000..2bf9d17
--- /dev/null
@@ -0,0 +1,222 @@
+.\" -*-nroff-*-
+.TH pkbuf 3 "16 July 2000" mLib
+.SH "NAME"
+pkbuf \- split packets out of asynchronously received blocks
+.\" @pkbuf_flush
+.\" @pkbuf_close
+.\" @pkbuf_free
+.\" @pkbuf_snarf
+.\" @pkbuf_want
+.\" @pkbuf_init
+.\" @pkbuf_destroy
+.SH "SYNOPSIS"
+.nf
+.B "#include <mLib/pkbuf.h>"
+
+.BI "void pkbuf_flush(pkbuf *" pk ", octet *" p ", size_t " len );
+.BI "void pkbuf_close(pkbuf *" pk );
+.BI "size_t pkbuf_free(pkbuf *" pk ", octet **" p );
+.BI "void pkbuf_snarf(pkbuf *" pk ", const void *" p ", size_t " sz );
+.BI "void pkbuf_want(pkbuf *" pk ", size_t " want );
+.BI "void pkbuf_init(pkbuf *" pk ,
+.BI "                void (*" func ")(octet *" b ", size_t " sz ", pkbuf *" pk ,
+.BI "                                 size_t *" keep ", void *" p ),
+.BI "                void *" pk );
+.BI "void pkbuf_destroy(pkbuf *" pk );
+.fi
+.SH "DESCRIPTION"
+The declarations in
+.B <mLib/pkbuf.h>
+implement a
+.IR "packet buffer" .
+Given unpredictably-sized chunks of data, the packet buffer extracts
+completed packets of data, with sizes ascertained by a handler
+function. 
+.PP
+The state of a packet buffer is stored in an object of type
+.BR pkbuf .
+This is a structure which must be allocated by the caller.  The
+structure should normally be considered opaque (see the section on
+.B Disablement
+for an exception to this).
+.SS "Initialization and finalization"
+The function
+.B pkbuf_init
+initializes a packet buffer ready for use.  It is given three arguments:
+.TP
+.BI "pkbuf *" pk
+A pointer to the block of memory to use for the packet buffer.  The packet
+buffer will allocate memory to store incoming data automatically: this
+structure just contains bookkeeping information.
+.TP
+.nf
+.BI "void (*" func ")(octet *" b ", size_t " sz ", pkbuf *" p ,
+.BI "      size_t *" keep ", void *" p )
+.fi
+The
+.I packet-handler
+function to which the packet buffer should pass packets of data when
+they're received.
+.TP
+.BI "void *" p
+A pointer argument to be passed to the function when a packet arrives.
+.PP
+By default, the buffer is
+allocated from the current arena,
+.BR arena_global (3);
+this may be changed by altering the buffer's
+.B a
+member to refer to a different arena at any time when the buffer is
+unallocated.
+.PP
+A packet buffer must be destroyed after use by calling
+.BR pkbuf_destroy ,
+passing it the address of the buffer block.
+.SS "Inserting data into the buffer"
+There are two interfaces for inserting data into the buffer.  One's much
+simpler than the other, although it's less expressive.
+.PP
+The simple interface is
+.BR pkbuf_snarf .
+This function is given three arguments: a pointer
+.I pk
+to a packet buffer structure; a pointer
+.I p
+ to a chunk of data to read; and the size
+.I sz
+of the chunk of data.  The data is pushed through the packet buffer and
+any complete packets are passed on to the packet handler.
+.PP
+The complex interface is the pair of functions
+.I pkbuf_free
+and
+.IR pkbuf_flush .
+.PP
+The 
+.B pkbuf_free
+function returns the address and size of a free portion of the packet
+buffer's memory into which data may be written.  The function is passed
+the address 
+.I pk
+of the packet buffer.  Its result is the size of the free area, and it
+writes the base address of this free space to the location pointed to by
+the argument
+.IR p .
+The caller's data must be written to ascending memory locations starting
+at
+.BI * p
+and no data may be written beyond the end of the free space.  However,
+it isn't necessary to completely fill the buffer.
+.PP
+Once the free area has had some data written to it,
+.B pkbuf_flush
+is called to examine the new data and break it into packets.  This is
+given three arguments:
+.TP
+.BI "pkbuf *" pk
+The address of the packet buffer.
+.TP
+.BI "octet *" p
+The address at which the new data has been written.  This must be the
+base address returned from
+.BR pkbuf_free .
+.TP
+.BI "size_t " len
+The number of bytes which have been written to the buffer.
+.PP
+The
+.B pkbuf_flush
+function breaks the new data into packets as described below, and passes
+each one in turn to the packet-handler function.
+.PP
+The
+.B pkbuf_snarf
+function is trivially implemented in terms of the more complex
+.B pkbuf_free / pkbuf_flush
+interface.
+.SS "Packet breaking and the handler fucntion"
+The function
+.B pkbuf_want
+is used to inform the packet buffer of the expected length of the next
+packet.  It is given the pointer
+.I pk
+to the packet buffer and a size
+.I sz
+of the packet.
+.PP
+When enough data has arrived, the packet-handler function is called, and
+passed:
+.TP
+.BI "octet *" b
+A pointer to the packet data in the buffer, or zero to signify
+end-of-file.
+.TP
+.BI "size_t " sz
+The size of the packet, as previously configured via
+.BR pkbuf_want .
+.TP
+.BI "pkbuf *" pk
+A pointer to the packet buffer.
+.TP
+.BI "size_t *" keep
+A location in which to store the number of bytes of the current packet
+to be retained.  The bytes kept are from the end of the current packet:
+if you want to keep bytes from the beginning of the packet, you should
+move them into the right place.
+.TP
+.BI "void *" p
+The pointer which was set up in the call to
+.BR pkbuf_init .
+.PP
+.SS "Flushing the remaining data"
+When the client program knows that there's no more data arriving (for
+example, an end-of-file condition exists on its data source) it should
+call the function
+.BR pkbuf_close .
+This will call the handler one final time with a null pointer to inform
+it of the end-of-file.
+.SS "Disablement"
+The packet buffer is intended to be used in higher-level program
+objects, such as the packet selector described in
+.BR selpk (3).
+Unfortunately, a concept from this high level needs to exist at the
+packet buffer level, which complicates the description somewhat.  The
+idea is that, when a packet-handler attached to some higher-level object
+decides that it's read enough, it can
+.I disable
+the object so that it doesn't see any more data.
+.PP
+Clearly, since an
+.B pkbuf_flush
+call can emit more than one packet, so it must be aware that the packet
+handler isn't interested in any more packet.  However, this fact must
+also be signalled to the higher-level object so that it can detach
+itself from its data source.
+.PP
+Rather than invent some complex interface for this, the packet buffer
+exports one of its structure members,
+.BR flags .
+A higher-level object wishing to disable the packet buffer simply clears
+the bit
+.B PKBUF_ENABLE
+in the flags word.
+.PP
+Disabling a buffer causes an immediate return from
+.BR pkbuf_flush .
+However, it is not permitted for the functions
+.B pkbuf_flush
+or
+.B pkbuf_close
+to be called on a disabled buffer.  (This condition isn't checked for;
+it'll just do the wrong thing.)  Furthermore, the
+.B pkbuf_snarf
+function does not handle disablement at all, because it would complicate
+the interface so much that it wouldn't have any advantage over the more
+general
+.BR pkbuf_free / pkbuf_flush .
+.SH "SEE ALSO"
+.BR lbuf (3),
+.BR selpk (3),
+.BR mLib (3).
+.SH "AUTHOR"
+Mark Wooding, <mdw@nsict.org>
diff --git a/man/selpk.3 b/man/selpk.3
new file mode 100644 (file)
index 0000000..57574fb
--- /dev/null
@@ -0,0 +1,111 @@
+.\" -*-nroff-*-
+.TH selpk 3 "23 May 1999" mLib
+.SH NAME
+selpk \- packet-buffering input selector
+.\" @selpk_enable
+.\" @selpk_disable
+.\" @selpk_want
+.\" @selpk_init
+.\" @selpk_destroy
+.SH SYNOPSIS
+.nf
+.B "#include <mLib/selpk.h>"
+
+.BI "void selpk_enable(selpk *" pk );
+.BI "void selpk_disable(selpk *" pk );
+.BI "void selpk_want(selpk *" pk ", size_t " sz );
+.BI "void selpk_init(selpk *" pk ,
+.BI "                sel_state *" s ,
+.BI "                int " fd ,
+.BI "                void (*" func ")(octet *" b ", size_t " sz ", pkbuf *" pk ,
+.BI "                                 size_t *" keep ", void *" p ),
+.BI "                void *" p );
+.BI "void selpk_destroy(selpk *" b );
+.fi
+.SH DESCRIPTION
+The
+.B selpk
+subsystem is a selector which integrates with the
+.BR sel (3)
+system for I/O multiplexing.  It reads packets from a file descriptor
+and passes them to a caller-defined function.  It uses the packet buffer
+described in
+.BR pkbuf (3)
+to do its work: you should read about it in order to understand exactly
+how the packet buffer decides how much data is in each packet and the
+exact rules about what your packet handling function should and
+shouldn't do.
+.PP
+The data for a packet selector is stored in an object of type
+.BR selpk .
+This object must be allocated by the caller, and initialized using the
+.B selpk_init
+function.  This requires a fair few arguments:
+.TP
+.BI "selpk *" pk
+Pointer to the
+.B selpk
+object to initialize.
+.TP
+.BI "sel_state *" s
+Pointer to a multiplexor object (type
+.BR sel_state )
+to which this selector should be attached.  See
+.BR sel (3)
+for more details about multiplexors, and how this whole system works.
+.TP
+.BI "int " fd
+The file descriptor of the stream the selector should read from.
+.TP
+.nf
+.BI "void (*" func ")(octet *" b ", size_t " sz ", pkbuf *" p ,
+.BI "      size_t *" keep ", void *" p )
+.fi
+The
+.I "packet handler"
+function.  It is passed a pointer to each packet read from the file (or
+null to indicate end-of-file) and an arbitrary pointer (the
+.I p
+argument to
+.B selpk_init
+described below).
+.TP
+.BI "void *" p
+A pointer argument passed to
+.I func
+for each packet read from the file.  Apart from this, the pointer is not
+used at all.
+.PP
+The
+.B selpk
+selector is immediately active.  Subsequent calls to
+.B sel_select
+on the same multiplexor will cause any packets read from the file to be
+passed to your handling function.  This function can at any time call
+.B selpk_disable
+to stop itself from being called any more.  The selector is then
+disengaged from the I/O multiplexor and won't do anything until
+.B selpk_enable
+is called.  Note that
+.B selpk_enable
+may well immediately start emitting complete packets of text which were
+queued up from the last I/O operation: it doesn't necessarily wait for
+the next
+.B sel_select
+call.
+.PP
+The size of packets read by the buffer is set by calling
+.BR selpk_want .
+See
+.BR pkbuf (3)
+for more details about how packet buffering works.
+.PP
+When it's finished with, a packet selector must be destroyed by calling
+.BR selpk_destroy .
+.SH "SEE ALSO"
+.BR pkbuf (3),
+.BR sel (3),
+.BR selbuf (3),
+.BR mLib (3).
+.SH AUTHOR
+Mark Wooding, <mdw@nsict.org>