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
|
.TH MUX 3
.SH NAME
Mux, muxinit, muxrpc, muxthreads \- protocol multiplexor
.SH SYNOPSIS
.B #include <mux.h>
.PP
.nf
.B
.ta +4n
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 *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);
.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
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 Libmux
will arrange that only one call to
.I recv
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.
.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.
.PP
Using
.I mintag
other than zero is not well tested and probably buggy.
|