Hello, this is my second mail describing a new proposal for libchannel's design. In this mail I will redefine the channel concept to a more useful abstraction.
Old channels are required to implement a subset of the Hurds io interface. But they also have the ability to implement arbitrary interfaces to deal with the additional operations that character devices might support. It is obvious that the io interface of channels could be handled by the same mechanism, but that would make io optional, which didn't make sense in the old channel concept. There are also objects which I have called ``channel hubs'' (yuck!), that act as trivial filesystem objects, and they implement a subset of the Hurds fs interface. It's such an object that actually gets transferred over IPC, which then produces channel objects. While I have been criticized for terms used for these two object types, it is clear that they need to be distinct in order to fully implement channels. I then started toying with the idea of hubs as a type of channels that implement the fs interface, one that can return new channels. Of course this doesn't fit at all with the old concept of a channel, instead I now propose that channels be able to implement *arbitrary* Hurd objects. All a server object has to do is implement a channel interface in order for a client to transfer it. Because channels are designed to deal with stacked translators, channels can be considered a *logical communication channel* going through the stack. Therefore I still regard ``channel'' an valid name for this abstraction. (But by all means, do feel free to object!) Henceforth, ``channel'' will refer to the new concept unless otherwise specified. Channels are now simply a mechanism to implement arbitrary objects, just like servers already do. This way we'll really cover all our bases and hopefully the design will meet the needs of all possible implementations. Arbitrary objects you say? So now we can just skip IPC altogether and reimplement the Hurd using channels, and the Hurd will be lightning fast? Unfortunately not. ;-) Channels can't provide any functionality to a process which it couldn't otherwise do. This because channels can't offer any protection whatsoever for their content. So an effort to only use channels would eventually lead to the entire system running inside a single process, or worse, inside the kernel. So, if channels doesn't bring anything new to the table that a plug-in couldn't, what are they good for? They are useful when you want to provide or use a service through either IPC or as a plug-in when the server provides it and the client can handle it. The problem is that this requires code in the client that deal with both cases. It is also important that the two cases behaves the same, anything else would likely confuse users. It's precisely in these where cases channels find there niche, a means with which to deal with the two cases uniformly. This determines a first requirement of libchannel: there must be a special channel type that wraps around a port referencing the object, if it could not be fetched. It also gives us a requirement for objects implemented in a channel: it has to have the same semantics as if it was used through a port wrapper instead. (This excludes channel junctions mentioned in the old discussion, but these couldn't be transferred in the old libchannel either, they were only coaxed in as channels to ease their implementation. A decision I believe was a mistake in hindsight, as they only need to *use* channels.) Now there's a clear goal to strive for: the closer channel objects are to the semantics of using the object through a port, the more interfaces can be implemented by channels. More specifically, the goal is to emulating full RPC calls (as opposed to the underlying message passing). Ideally channel functions should act exactly like those generated by MIG, only differing in that their name are prefixed with ``channel_'', that their port parameters are dealt with in a uniform manner, and that they might perform better. Given that MIG is well documented, it will be easy to evaluate this property of a design. Any automation would also be welcomed. If a design achieves the goal stated above, channels can handle anything the old libchannel could. The client obtains the port to a channel translators fs object, fetches the underlying channel (which correspond to a hub) and then calls ``channel_dir_lookup'' to get io channels (which correspond to old channels). It is less obvious that it can handle stores, which implements an interface slightly more powerful than the normal Hurd io interface. (Among other things it exposes the sparseness of the underlying store.) Cases like this should be handled by adding a new Hurd interface, since this additional expressiveness should not be hidden to clients that can't or do not wish to use channels. If an interface makes little sense in a IPC context, the translator can simply not handle such calls over IPC but still provide a implementation in the channel itself. To deal with this the client should be able to detect when a transfer fails, so it can apply a compatibility channel over the original port. If such a channel can't be implemented then the entire operation must fail if transfer fails. (This case is probably uninteresting, it would basically be a complicated way to implement plug-ins.) In my next mail I will present an actual design and show that it comes very close our goals. Regards, Fredrik _______________________________________________ Bug-hurd mailing list Bug-hurd@gnu.org http://lists.gnu.org/mailman/listinfo/bug-hurd