PreviousNext

Pipe Summary

The pipe examples show how the client and server tasks are complementary. The client implements the appropriate callback routines (test_pipe.alloc and either test_pipe.push or test_pipe.pull), and the server manager makes a cycle of calls to either test_pipe.push or test_pipe.pull of the stub. The application code gives the illusion that the server manager is calling the client-supplied callbacks. In fact, the manager is actually calling stub-supplied callbacks, and the client callbacks are asynchronous: a server manager call to one of the callback routines does not necessarily result in a call to the corresponding client callback.

One result of this is that the client and server should not count on the chunk sizes being the same at each end. For example, in the last directory reading example, the manager calls the test_pipe.push routine once with each NULL-terminated filename. However, the client test_push routine does not necessarily receive the data stream one file name at a time. For example, if the test_push routine attempted to print the file names using printf("%s\n",buf);, it might fail. An interesting exercise would be to add printf( ) routines to the client callbacks and the server manager to show when each callback is made.

Note also that the use of the pipe state field by the client is purely local and entirely at the discretion of the client. The state is not marshalled between client and server, and the server stubs use the local state field in a private manner. The server manager should not alter the state field.

Pipes may also be [in,out], although the utility of this construct is somewhat limited. Ideally, a client would like to be able to pass a stream of data to the server and have it processed and returned asynchronously. In practice, the input and output streams must be processed synchronously; that is, all input processing must be finished before any output processing can be done. This means that [in, out] pipes, while they can reduce latency within both the server and the client, cannot reduce latency between server and client; the client must still wait for all server processing to finish before it can begin to process the returned data stream.

For an in,out pipe, both the pull routine (for the in direction) and a push routine (for the out direction) must be initialized, as well as the alloc routine and the state. During the last pull call (when it will return a zero count to indicate that the pipe is "drained''), the application's pull routine must reinitialize the pipe state so that the pipe can be used by the push routine correctly.