Re: The behavior of constructors in IPDL

Chris Jones <[email protected]>
Newsgroups gmane.comp.mozilla.devel.dom
Message-ID <[email protected]>
Benjamin Smedberg wrote:
> On 7/24/09 11:39 AM, Chris Jones wrote:
> 
>> No.  IPDL now allows limited "simultaneous" messages through the
>> "Diamond Rule."  This works because we assume that if the programmer
>> declares messages according to the Diamond Rule, then messages are
>> "commutative," i.e., can be processed in either order.  Specifying that
>> routing IDs must be the same on both the parent and child means that
>> constructor messages are no longer commutative, because routing IDs are
>> assigned based on the order the messages are processed.  An innocuous
>> protocol like this would break if we specify what you want:
>>
>>   manages Foo; manages Bar;
>>   parent: Foo();
>>   child: Bar();
> 
> No, I don't think it would. The parent-generated IDs would be sequential
> 
> 0x80000000
> 0x80000001
> 0x80000002 etc...
> 
> The child-generated IDs would also be sequential
> 
> 0x00000000
> 0x00000001 etc...
> 
> There would be no chance of racing.
> 

This was actually a less illustrative example than it should have been;
I used |Foo()| and |Bar()| because the current implementation only keeps
a single routing table, and uses the same global counter for all routing
IDs.  But that's just an implementation detail.

So let's just say we have the protocol |manages Foo; both: Foo();|.
Then by that spec, this is allowed

P                  C
-----              -----
send Foo()[1]      send Foo()[2]
recv Foo()[2]      recv Foo()[1]

Each constructs a distinct actor, and the routing IDs are assigned
simulatenously.  Without resorting to something fancy and painful, how
can the parent-side actor assume what the child-side actor's routing ID
will be (and vice versa)?  Remember that the protocol also allows:

P                  C
-----              -----
send Foo()[1]      send Foo()[2]
send Foo()[3]
send Foo()[4]
recv Foo()[2]      recv Foo()[1]
                   ...

This isn't substantially different, just a further illustration.

>> This is a lot of pain for undemonstrated gain.  How would notification
>> that an sync constructor finished not work for you?
> 
> The client code will want to use the returned nsIChannel immediately after
> it has been created (before the other side's routing ID is known). Would the
> client code have to implement a check:
> 
> * Channel::Open
> ** Is the routing ID known yet? if not, queue up the message until the
> routing ID is known
> 
> Or would the protocol implementation itself perform this check?
>

It sounds like you want to hide asynchronous construction/setup under a
synchronous API.  That doesn't sound like a good idea to me; the "async
way" would be to have an "Channel::OnOpened" notification or something
like that.

If you must do this, I'd recommend doing the checking and queuing in
nsIChannel.  I really don't want to add this to IPDL.

Cheers,
Chris
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.