Finishing the network protocol

Andreas Hartmetz ahartmetz at gmail.com
Thu Mar 3 09:34:35 PST 2011


On Thursday 03 March 2011 15:58:14 Kristian Høgsberg wrote:
> On Thu, Mar 3, 2011 at 9:32 AM, Andreas Hartmetz <ahartmetz at gmail.com> 
wrote:
> > Hello again and sorry for taking a few days to reply.
> 
> ...
> 
> >> > - A scheme to recycle object IDs. When a new ID is needed, pick a free
> >> >  one at random. This introduces a problem:
> >> >  Suppose the client destroys object A with ID n, then by chance
> >> >  immediately reuses ID n for object B.
> >> >  The server will only receive this information later, the Wayland
> >> >  protocol being asynchronous and the server not having to respond to
> >> > an object creation request, unless it goes wrong. In the meantime the
> >> > server could send an event intended for A which would end up at B,
> >> > causing Bad Things to happen - in my implementation most likely an
> >> > assert failure unless the objects are of the same class.
> >> >  (This is the trickiest failure mode I could think of)
> >> >  The suggested solution is a kind of "rendezvous" for objects where
> >> > this can happen, or for simplicity all objects:
> >> >  On both client and server, have a function that needs to be called
> >> >  twice to unregister an object ID.
> >> >  One call from the destructor of the local object when it destroys
> >> >  itself, one call from the remote counterpart object when it destroys
> >> >  itself. No matter in which order the method is called, the first call
> >> >  removes the ID<->object mapping and puts the object ID on a waiting
> >> >  list to avoid reuse. The second call removes the ID from the waiting
> >> >  list, making it free to reuse.
> >> 
> >> Ah, yes, very good point.  I was going to suggest that there could be
> >> an event that the server sends to acknowledge that it has bound and
> >> object to a client ID (whether through the bind request above or from
> >> the client creating a client object), but if we reuse the same ID too
> >> fast, then it's still unclear which object the ID refers to.  That
> >> could be fixed by adding a serial number, but at that point I think
> >> your idea is better and simpler.  In fact, with your idea, we can
> >> distinguish between events sent from an object that we've destroyed
> >> and server errors where the server sends an event from an object that
> >> never existed.
> > 
> > I've started implementing this in my project and I've hit a problem:
> > while the destroy() methods are basically regular methods that get an
> > opcode the regular way, the confirmation message also needs an opcode.
> > The idea I outlined above, that I maybe didn't explain optimally,
> > contains that a destroy request looks exactly like a destroy
> > confirmation. That way both sides can handle destruction the same way:
> > If the object was locally destroyed, destroy the instance and send a
> > destroy() call to the other side. The other side will send back a
> > destroy() when it's done destroying. Both sides will unregister the ID
> > when destroy() has been both sent and received, keeping track with two
> > boolean flags. That way exactly one destroy() call is sent to the other
> > side.
> > 
> > In a nutshell, I think destroy() should implicitly be both a request and
> > a response whenever it appears in a client-created object. The methods
> > could actually be added implicitly to all client-created objects which
> > wouldn't be more of a hack than "doubling" one ocurrence of destroy() or
> > adding a flag like has_destructor="true", which btw would also be fine
> > with me.
> 
> Can't we just add a "destroyed" event to the display interface?
> 
I really like the concept of doing everything to an object by calling methods 
on that object, as far as possible. Destroying objects via the display object 
breaks that concept, which is the main reason why I don't like it. I program 
in languages with built-in OOP support most of the time and it would seem 
wrong to ask object A to destroy object B.

My Connection class provides most of the glue between the local socket and the 
interfaces, which is IMHO not very much related to the display interface. 
Connection is the place where ID-object maps are, which will probably look 
similar in Wayland with per-client ID spaces. One good reason for that is that 
Connection can be used almost the same way in client and server 
(symmetrically), while doing it via display would look quite different on 
client and server side.
I have consciously avoided making display the "god interface" any more than 
necessary for boostrapping in my network implementation. The display class 
that comes out of the code generator is just another Wayland object; notably 
it doesn't have a list of objects it owns. I don't know what the 
implementation of display will look like, and I certainly don't want to force 
any decisions about it.
I may or may not make Connection owned by a display instance later, but so far 
it looks like most likely not.


More information about the wayland-devel mailing list