--- sio.pod 2002/11/08 10:36:35 1.2
+++ sio.pod 2002/11/08 11:03:13 1.3
@@ -405,7 +405,6 @@
char *c;
} private_t;
- static
sio_rc_t XXX_init(sio_t *sio, void **up) {
private_t *my;
@@ -427,7 +426,6 @@
B<sio_create_stage> and a corresponding cleanup function is called
when the stage is detroyed with B<sio_destroy_stage>.
- static
sio_rc_t XXX_cleanup(sio_t *sio, void *u)
{
private_t *my = (private_t *)u;
@@ -444,7 +442,6 @@
parameters are passed through B<sio_configure_stage> to the
configure function of the module.
- static
sio_rc_t XXX_configure(sio_t *sio, void *u, void *o, void *v)
{
private_t *my = (private_t *)u;
@@ -538,6 +535,86 @@
assembly line and B<sio_output> schedules all stages attached
to the output assembly line.
+A full-duplex protocol however needs to mix input and output
+operations. This can be done by telling the scheduler to
+cross sides with the result code SIO_XSTREAM and by maintaining
+a state machine that directs the scheduler back to the
+originating track.
+
+Example:
+
+ sio_rc_t XXX_openr(sio_t *sio, al_t *al, void *u)
+ {
+ private_t *my = (private_t *)u;
+ ...
+ /* cache reference to input assembly line */
+ my->al_in = al;
+ my->state = INIT;
+ ...
+ }
+ sio_rc_t XXX_openw(sio_t *sio, al_t *al, void *u)
+ {
+ private_t *my = (private_t *)u;
+ ...
+ /* cache reference to output assembly line */
+ my->al_out = al;
+ my->state = INIT;
+ ...
+ }
+ sio_rc_t XXX_input(sio_t *sio, al_t *al, void *u)
+ {
+ return XXX_protocol(sio, (private_t *)u, 0);
+ }
+ sio_rc_t XXX_output(sio_t *sio, al_t *al, void *u)
+ {
+ return XXX_protocol(sio, (private_t *)u, 1);
+ }
+
+
+ sio_rc_t XXX_protocol(sio_t *sio, private_t *my, int isoutput)
+ {
+ switch (my->state) {
+ case INIT:
+ my->isoutput = isoutput;
+ my->state = NEXT;
+ ...
+ /* protocol needs global assembly lines,
+ * we need to put aside any data */
+ XXX_preserve_al(my);
+
+ /* protocol starts with output */
+ if (isoutput) {
+
+ return SIO_LOOP; /* next state on this side */
+ } else
+ return SIO_XSTREAM; /* next state on other side */
+
+ case NEXT:
+ ....
+ case INPUT:
+ al_append_bytes(my->al_in, ...);
+ ...
+ case OUTPUT:
+ al_append_bytes(my->al_out, ...);
+ ...
+ case LAST:
+ ...
+ my->state = DONE;
+
+ /* restore global asembly lines */
+ XXX_restore_output(my);
+
+ if (isoutput != my->isoutput)
+ return SIO_XSTREAM;
+ else
+ return SIO_LOOP;
+
+ case DONE:
+ ...
+ }
+ ...
+ }
+
=back
|