1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
|
.TH MUX 3
.SH NAME
Mux, muxinit, muxrpc, muxthreads \- protocol multiplexor
.SH SYNOPSIS
.B #include <mux.h>
.PP
.nf
.B
.ta +4n
.ft B
struct Mux
{
uint mintag;
uint maxtag;
int (*settag)(Mux *mux, void *msg, uint tag);
int (*gettag)(Mux *mux, void *msg);
int (*send)(Mux *mux, void *msg);
void *(*recv)(Mux *mux);
void *(*nbrecv)(Mux *mux);
void *aux;
\&... /* private fields follow */
};
.ta +\w'\fLvoid* 'u
.PP
.B
void muxinit(Mux *mux);
.PP
.B
void* muxrpc(Mux *mux, void *request);
.PP
.B
void muxprocs(Mux *mux);
.PP
.B
Muxrpc* muxrpcstart(Mux *mux, void *request);
.PP
.B
void* muxrpccanfinish(Muxrpc *rpc);
.SH DESCRIPTION
.I Libmux
is a generic protocol multiplexor.
A client program initializes a
.B Mux
structure with information about the protocol
(mainly in the form of helper functions)
and can then use
.I muxrpc
to execute individual RPCs without worrying
about details of multiplexing requests
and demultiplexing responses.
.PP
.I Libmux
assumes that the protocol messages contain a
.I tag
(or message ID) field that exists for the sole purpose of demultiplexing messages.
.I Libmux
chooses the tags and then calls a helper function
to put them in the outgoing messages.
.I Libmux
calls another helper function to retrieve tags
from incoming messages.
It also calls helper functions to send and receive packets.
.PP
A client should allocate a
.B Mux
structure and then call
.I muxinit
to initialize the library's private elements.
The client must initialize the following elements:
.TP
.I mintag\fR, \fPmaxtag
The range of valid tags;
.I maxtag
is the maximum valid tag plus one, so that
.IR maxtag \- mintag
is equal to the number of valid tags.
If
.I libmux
runs out of tags
(all tags are being used for RPCs currently in progress),
a new call to
.IR muxrpc
will block until an executing call finishes.
.TP
.I settag\fR, \fPgettag
Set or get the tag value in a message.
.TP
.I send\fR, \fPrecv\fR, \fPnbrecv
Send or receive protocol messages on the connection.
.I Recv
should block until a message is available and
should return nil if the connection is closed.
.I Nbrecv
should not block; it returns nil if there is no
message available to be read.
.I Libmux
will arrange that only one call to
.I recv
or
.I nbrecv
is active at a time.
.TP
.I aux
An auxiliary pointer for use by the client.
.PD
Once a client has initialized the
.B Mux
structure, it can call
.I muxrpc
to execute RPCs.
The
.I request
is the message passed to
.I settag
and
.IR send .
The return value is the response packet,
as provided by
.IR recv ,
or
nil if an error occurred.
.I Muxprocs
allocates new procs
(see
.IR thread (3))
in which to run
.I send
and
.IR recv .
After a call to
.IR muxprocs ,
.I muxrpc
will run
.I send
and
.I recv
in these procs instead of in the calling proc.
This is useful if the implementation of
either (particularly
.IR recv )
blocks an entire proc
and there are other threads in the calling proc
that need to remain active.
.PP
.I Libmux
also provides a non-blocking interface, useful for programs forced
to use a
.IR select (2)-based
main loop.
.I Muxrpcstart
runs the first half of
.IR muxrpc :
it assigns a tag and sends the request,
but does not wait for the reply.
Instead it returns a pointer to a
.B Muxrpc
structure that represents the in-progress call.
.I Muxrpccanfinish
checks whether the given call
can finish.
If no mux procs have been started,
.I muxrpccanfinish
may call
.I nbrecv
to poll for newly arrived responses.
.SH EXAMPLE
See
.B \*9/src/lib9pclient/fs.c
for an example of using
.I libmux
with
9P
(see
.IR intro (9p)).
.SH SOURCE
.B \*9/src/libmux
.SH SEE ALSO
.IR thread (3),
.IR intro (9p)
.SH BUGS
.I Libmux
does not know how to free protocol messages,
so message arriving with unexpected or invalid
tags are leaked.
|