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