Re: Simultaneous destructors

Chris Jones <[email protected]>
Newsgroups gmane.comp.mozilla.devel.dom
Message-ID <[email protected]>
Chris Jones wrote:
> Benjamin Smedberg wrote:
>> How does IPDL deal with destructors that are fired simultaneously from 
>> both
>> sides, e.g. ~PBrowserStream? Even if we make one side "win the race", 
>> won't
>> IPDL reject the second destructor message (because it has an invalid 
>> actor
>> ID) and abort the process? If it doesn't abort the process, what is the
>> behavior (return values) of the second destructor message?
>>
> 
> Right now, IPDL treats dtors as it does any other message, and by "any 
> message" standards that's not a race.
> 
> But this is just a good old fashioned bug, as dtors define an implicit 
> transition, [alive]-->DEAD.  I'll add this in soon.
> 

Hmm, I was hasty in my response.  On further consideration this is a 
deeper problem.

There are two facets to the problem.  The first mainly applies to 
nominally stateless, inherently racy protocols like NPAPI.  The example 
you present with ~PBrowserStream forces a design decision: whether or 
not to allow destructor messages to race.  I would prefer to just 
disallow racy destructors; I think there's a workaround for the NPAPI 
(generally, crappy API) case.  The workaround is two-phase destruction. 
  For example:

   protocol PBrowserStream {
      child:   RequestDestruction;  // first phase
      parent:  NotifyDestruction;   // first phase
   };

   protocol PPluginInstance {
      manages PBrowserStream;

      parent:  PBrowserStream;
               ~PBrowserStream;     // second phase
   };

(I'm not sure "which" NPStream the PBrowserStream models; I'm assuming 
it's the one created with NPN_NewStream() and so sort of "owned" by the 
child).

If the browser wants to destroy the BrowserStream, instead of directly 
invoking the dtor, it destroys the "real" NPStream wrt to NPAPI and then 
sends "RequestDestruction."  In the common case, the plugin will be idle 
wrt the stream and simply send back the actual ~PBrowserStream message.

If the plugin wants to destroy a BrowserStream, it first sends 
"NotifyDestruction" to warn the browser.  In the common case, the 
browser will be idle wrt the stream, clean up the NPStream, and send 
"RequestDestruction" back to the plugin, upon which ~PBrowserStream will 
be sent.

If, however, RequestDestruction and NotifyDestruction race, it causes no 
problems as the browser is guaranteed to have processed 
NotifyDestruction *before* ~PBrowserStream arrives.  The C++ 
implementations of browser stream actors just have to be careful not to 
double-"free" the NPStreams.

That's one option, again (to me eyes) a hack around NPAPI limitations. 
Another option for this case is to *allow* racy destructor messages. 
All that has to be done in IPDL is, only for protocols with racy 
destructors, not to blow up when a destructor references an unknown 
actor.  This approach trades a safety check for racy destructors.  Both 
are feasible and easy, but again I lean towards two-phase destruction.

I now see that the second facet of this problem isn't worth discussing 
until we resolve this first issue.

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.