Hello, after some careful thinking I think I have pretty good idea of how to handle sessions, demuxing and buffering. My solution is simple enough; they should all be implemented in channels (as opposed to being implemented in channelio.) This will be more general and give the user more control. The downside is that it will be a bit more unwieldy, almost every translator will introduce a chain of channels at a time, instead of just one.
Multiplexors are primarily used to gain multiple sessions to exclusive access devices and also balances io over sub-channels. E.g. they multiplex in both directions. Multiplexors are also useful to simply reduce the number of sessions, as a multiplexor will have one session to each back-end and clients will have one session each to the multiplexor. Contranst this with a `file'-channel, where each client session reopens the file inorder to forward the session accross the process boundary. I have identified two generally useful multiplexors. The simpler one I will just call a `tee'. It simply forwards each read and write to it's children, to whichever is most responsive or cyclicly if they are equally so. The figures below illustrates a read. A write would be similar, just exchange the devices and clients. Before After | ----- | ----- ( 1 ) | ( 1 ) ----- | ----- +------+ / +------+ | +------+ \ +------+ |Device|----+ |Client| | |Device| +--->|Client| +------+ | +---+ +------+ | +------+ +---+ | +------+ +===>|Tee| | |Tee|====+ +------+ | +---+ +------+ | +------+ +---+ | +------+ |Device|----+ |Client| | |Device| +--->|Client| +------+ \ +------+ | +------+ / +------+ ----- | ----- ( 2 ) | ( 2 ) ----- | ----- | More interesting perhaps is a `broadcast' multiplexor, which forwards any input to all it's children and output to all clients in the order received. The broadcaster must be able to determine that all clients receive the data which requires session data. The broadcast channel can't be transfered to other processes without losing it's broadcasting property. Like above the following figure shows a read and a write just exchanges the parties' positions. Before After | ----- | ----- ----- ( 1 ) | ( 2 )( 1 ) ----- | ----- ----- +------+ / +------+ | +------+ \/ +------+ |Device|----+ |Client| | |Device| +--->|Client| +------+ | +---+ +------+ | +------+ +---+ | +------+ +===>|Tee| | |Tee|====+ +------+ | +---+ +------+ | +------+ +---+ | +------+ |Device|----+ |Client| | |Device| +--->|Client| +------+ \ +------+ | +------+ /\ +------+ ----- | ----- ----- ( 2 ) | ( 2 )( 1 ) ----- | ----- ----- | With these two one can create a hybrid multiplexor that broadcasts data to clients but alternates it between back-ends. This is done by layering a broadcaster over a tee. Of course vice-versa is also possible. There are also other multiplexors that are conceivable, but they are more domain specific. For instance, an audio multiplexor will need to mix the incoming audio streams into a single one. This is the primary reason why multiplexors can't be in channelio, it must be extensible to handle these cases. The main purpose of buffering is to limit the amount of IPC by aggregating many small reads or writes to a large read or write. It is complicated by the introduction of sessions, since different sessions will get different data one buffer per session is needed. If the buffer is a channel however, it can be put behind a multiplexor, which only opens a single session. So if Richard (or anybody else) doesn't object, I'll add the changes required to implement sessions to the libchannel spec, I've also been thinking if channels need to support multiple threads operating it at the same time (e.g. one per session), perhaps even allowing channels their own threads. This might be required to implement multiplexors (in order to time-out unresponsive clients.) That would require a lock in the channel struct, which libchannel code must respect. Regards, Fredrik _______________________________________________ Bug-hurd mailing list Bug-hurd@gnu.org http://lists.gnu.org/mailman/listinfo/bug-hurd