We next show a purely sychronous protocol, called SELECT, that is typically configured on top of CHAN. SELECT's job is to dispatch request messages to the appropriate procedure. What this means is that on the client side, SELECT is given a procedure number that the client wants to invoke, puts this number it its header, and invokes a lower level request/reply protocol like CHAN. When this invocation returns, SELECT merely lets the return pass on through to the client; it has no real demultiplexing work to do. On the server side, SELECT uses the procedure number it finds in its header to select the right local procedure to invoke. When this procedure returns, SELECT simply returns to the low-level protocol that just invoked it.
The x-kernel code for selectCall and selectCallPop is given below. Notice that SELECT is like CHAN in that it is asymmetric---each session is either a client session or a server session. Unlike CHAN, however, SELECT exports the synchronous interface to both higher-level protocols ( xCall) and lower-level protocols ( xCallDemux and xCallPop).
static XkReturn selectCall(Sessn self, Msg *msg, Msg *rmsg) { SelectState *state = (SelectState *)self->state; char *buf; buf = msgPush(msg, HLEN); select_hdr_store(state->hdr, buf, HLEN); return xCall(xGetDown(self, 0), msg, rmsg); } static XkReturn selectCallPop(Sessn s, Sessn lls, Msg *msg, Msg *rmsg, void *inHdr) { return xCallDemux(xGetUp(s), s, msg, rmsg); }