mozilla

Compare Revisions

IPDL Tutorial

Change Revisions

Revision 69582:

Revision 69582 by BenjaminSmedberg on

Revision 69583:

Revision 69583 by BenjaminSmedberg on

Title:
IPDL Tutorial
IPDL Tutorial
Slug:
IPDL/Tutorial
IPDL/Tutorial
Content:

Revision 69582
Revision 69583
nn10    <div class="note">
11      To experiment with adding a new IPDL protocol, see <a href=
 >"/en/IPDL/Creating_a_New_Protocol" title="en/IPDL/Creating a New 
 >Protocol"><span>Creating a New Protocol</span></a>.
12    </div>
nn303    <p>
304      To make the blocking nature more noticeable to programmers,
 > the C++ method names for synchronous and RPC messages are differ
 >ent:
305    </p>
306    <table border="1" cellpadding="2" cellspacing="0" style="tabl
 >e-layout: fixed;">
307      <thead>
308        <tr>
309          <th scope="col">
310            &nbsp;
311          </th>
312          <th scope="col">
313            sender
314          </th>
315          <th scope="col">
316            receiver
317          </th>
318        </tr>
319      </thead>
320      <tbody>
321        <tr>
322          <th scope="row">
323            async
324          </th>
325          <td>
326            Send<em>MessageName</em>
327          </td>
328          <td>
329            Recv<em>MessageName</em>
330          </td>
331        </tr>
332        <tr>
333          <th scope="row">
334            sync/rpc
335          </th>
336          <td>
337            Call<em>MessageName</em>
338          </td>
339          <td>
340            Answer<em>MessageName</em>
341          </td>
342        </tr>
343      </tbody>
344    </table>
n320  bool SendInit(bool* windowless, bool* ok) { ... };n365  bool CallInit(bool* windowless, bool* ok) { ... };
n366      <span class="mw-headline">Protocol management</span>n411      <span class="mw-headline">Subprotocols and Protocol Managem
 >ent</span>
n369      So far we've seen a protocol that Plugin actors use to commn414      So far we've seen a single protocol, but no real-world situ
>unicate. Plugins are "singletons"; there's only one copy of libfl>ation would have a single protocol in isolation. Instead, protoco
>ash.so open at any time. However, there are many plugin <em>insta>ls are arranged in a managed hierarchy of <strong>subprotocols</s
>nces</em>. (This is a very general pattern.) IPDL needs to someho>trong>. A sub-protocol is bound to a "manager" which tracks its l
>w support these "instances", and it does so through "managed" pro>ifetime and acts as a factory. A protocol hierarchy begins with a
>tocols, a.k.a. sub-protocols (the terms will be used interchangea> single top-level protocol from which all subprotocol actors are 
>bly). A sub-protocol is bound to a "manager" protocol, and actors>eventually created. In Mozilla there are two main top-level proto
> created speaking that sub-protocol are bound to the lifetime of >cols: <a class=" external" href="http://mxr.mozilla.org/projects-
>the "manager" protocol actor that created them. The managing prot>central/source/electrolysis/dom/plugins/PPluginModule.ipdl" title
>ocol acts like a "factory" for actors of the sub-protocol. In gen>="http://mxr.mozilla.org/projects-central/source/electrolysis/dom
>eral, IPDL supports <em>hierarchies</em> of protocols, descending>/plugins/PPluginModule.ipdl">PPluginModule</a> for remote plugins
> from a single <em>top-level</em> protocol.>, and <a class=" external" href="http://mxr.mozilla.org/projects-
 >central/source/electrolysis/dom/ipc/PContentProcess.ipdl" title="
 >http://mxr.mozilla.org/projects-central/source/electrolysis/dom/i
 >pc/PContentProcess.ipdl">PContentProcess</a> for remote tabs.
370    </p>
371    <p>415    </p>
372      The following example extends the Plugin protocol to manage
> a PluginInstance protocol. The Plugin protocol is top-level in t 
>his example. 
373    </p>416    <p>
417      The following example extends the toplevel plugin protocol 
 >to manage plugin instances.
374    <pre>418    </p>
419    <pre>
375// ----- file Plugin.ipdl420// ----- file PPlugin.ipdl
421include protocol "PPluginInstance.ipdl";
422 
423rpc protocol PPlugin
424{
425  manages PPluginInstance;
426 
427child:
428  rpc Init(nsCString pluginPath) returns (bool ok);
429 
430  <span style="font-weight: bold;">rpc </span>PluginInstance(nsCS
 >tring type, nsCString[] args) returns (int rv);
431  rpc ~PluginInstance();
432}
433 
434// ----- file PPluginInstance.ipdl
435 
436include protocol "PPlugin.ipdl";
437 
438rpc protocol PPluginInstance
439{
440  manager PPlugin;
441 
442child:
443  void SetSize(int width, int height);
444};
445</pre>
446    <p>
447      This example has several new elements: `include protocol` i
 >mports another protocol declaration into this file. Note that thi
 >s is not a preprocessor directive, but a part of the IPDL&nbsp;la
 >nguage. The generated C++ code will have proper #include preproce
 >ssor directives for the imported protocols.
448    </p>
449    <p>
450      The `manages` statement declares that this protocol manages
 > PPluginInstance. The PPlugin protocol must declare constructor a
 >nd destructor messages for PPluginInstance actors. The `manages` 
 >statement also means that PPluginInstance actors are tied to the 
 >lifetime of the Plugin actor that creates them: if this PPlugin i
 >nstance is destroyed, all the PPluginInstances associated with it
 > become invalid or are destroyed as well.
451    </p>
452    <p>
453      The constructor and destructor messages have syntax similar
 > to C++ constructors, but the behavior is different. Constructors
 > and destructors have parameters, direction, semantics, and retur
 >n values like other IPDL messages. A constructor and destructor m
 >essage must be declared for each managed protocol.
454    </p>
455    <p>
456      Each subprotocol must include a `manager` statement.
457    </p>
458    <p>
459      At the C++ layer, the subclasses in both the child and the 
 >parent must implement methods for allocating and deallocating the
 > subprotocol actor. The constructor and destructor are translated
 > into standard C++ methods for messages.
460    </p>
461    <pre>
462class PPluginParent
463{
464  /* Allocate a PPluginInstanceParent when the first form of Call
 >PluginInstanceConstructor is called */
465  virtual PPluginInstanceParent* AllocPPluginInstance(const nsCSt
 >ring&amp; type, const nsTArray&lt;nsCString&gt;&amp; args, int* r
 >v) = 0;
466 
467  /* Deallocate the PPluginInstanceParent after PPluginInstanceDe
 >structor is done with it */
468  virtual bool DeallocPPluginInstance(PPluginInstanceParent* acto
 >r) = 0;
469 
470  /* constructor message */
471  virtual CallPPluginInstanceConstructor(const nsCString&amp; typ
 >e, const nsTArray&lt;nsCString&gt;&amp; args, int* rv) { /* gener
 >ated code */ }
472 
473  /* alternate form of constructor message: supply your own PPlug
 >inInstanceParent* to bypass AllocPPluginInstance */
474  virtual bool CallPPluginInstanceConstructor(PPluginInstancePare
 >nt* actor, const nsCString&amp; type, const nsTArray&lt;nsCString
 >&gt;&amp; args, int* rv)
475  { /* generated code */ }
476 
477  /* destructor message */
478  virtual bool CallPPluginInstanceDestructor(PPluginInstanceParen
 >t* actor) { /* generated code */ }
479 
480  ...
481};
482 
483class PPluginChild
484{
485  /* Allocate a PPluginInstanceChild when we receive the PPluginI
 >nstance constructor */
486  virtual PPluginInstanceChild* AllocPPluginInstance(const nsCStr
 >ing&amp; type, const nsTArray&lt;nsCString&gt;&amp; args, int* rv
 >) = 0;
487 
488  /* Deallocate a PPluginInstanceChild after we handle the PPlugi
 >nInstance destructor */
489  virtual bool DeallocPPluginInstance(PPluginInstanceChild* actor
 >) = 0;
490 
491  /* Answer the constructor message. Implementing this method is 
 >optional: it may be possible to answer the message directly in Al
 >locPPluginInstance. */
492  virtual bool AnswerPPluginInstanceConstructor(PPluginInstanceCh
 >ild* actor, const nsCString&amp; type, const nsTArray&lt;nsCStrin
 >g&gt;&amp; args, int* rv) { }
493 
494  /* Answer the desctructor message. */
495  virtual bool AnswerPPluginInstanceDestructor(PPluginInstanceChi
 >ld* actor) = 0;
496 
497  ...
498};
499</pre>
500    <h4>
501      Subprotocol Actor Lifetime
502    </h4>
503    <p>
504      AllocPProtocol and DeallocPProtocol are a matched pair of f
 >unctions. The typical implementation of these functions uses `new
 >` and `delete`:
505    </p>
506    <pre>
507class PluginChild : PPluginChild
508{
509 virtual PPluginInstanceChild* AllocPPluginInstance(const nsCStri
 >ng&amp; type, const nsTArray&lt;nsCString&gt;&amp; args, int* rv)
510  {
511    return new PluginInstanceChild(type, args, rv);
512  }
513 
514  virtual bool DeallocPPluginInstanceChild(PPluginInstanceChild* 
 >actor)
515  {
516    delete actor; // actor destructors are always virtual, so it'
 >s safe to call delete on them!
517    return true;
518  }
519 
520  ...
521};
522</pre>
523    <p>
524      In some cases, however, external code may hold references t
 >o actor implementations which require refcounting or other lifeti
 >me strategies. In this case, the alloc/dealloc pairs can perform 
 >different actions. Here is an example of refcounting:
525    </p>
526    <pre>
527class ExampleChild : public nsIObserver, public PExampleChild { .
 >.. };
528 
529virtual PExampleChild* TopLevelChild::AllocPExample()
530{
531  nsRefPtr&lt;ExampleChild*&gt; actor = new ExampleChild();
532  return actor.forget();
533}
534 
535virtual bool TopLevelChild::DeallocPExample(PExampleChild* actor)
536{
537  NS_RELEASE(static_cast&lt;ExampleChild*&gt;(actor));
538  return true;
539}
540</pre>
541    <h2>
542      <span class="mw-headline">Protocol state machines</span>
543    </h2>
544    <p>
545      The astute reader might question why IPDL includes the word
 > "protocol" when all that has been introduced so far are unstruct
 >ured grab-bags of messages. IPDL allows protocol authors to defin
 >e the order and structure of how messages may be sent/received by
 > defining protocol <em>state machines</em> (finite state machines
 >).
546    </p>
547    <p>
548      [Note that the state machine portion of the IPDL compiler i
 >s not complete as of this writing, 22 October 2009. IPDL code for
 > state machines is accepted by the compiler, but it does not affe
 >ct the generated C++, yet.]
549    </p>
550    <p>
551      IPDL parent and child actors communicating via a protocol a
 >re paired. Each actor in the pair follows the same state machine.
 > The pair attempts to keep their single collective state synchron
 >ized. Though, it is possible that the parent and child actors may
 > be momentarily out of sync while messages are transmitted.
552    </p>
553    <p>
554      IPDL (arbitrarily) requires state machines to be defined fr
 >om the perspective of the <strong>parent</strong> side of the pro
 >tocol. For example, when you see the <code><strong>send</strong> 
 >Msg</code> syntax, it means "when the parent actor sends Msg".
555    </p>
556    <p>
557      The following example shows one such state machine for the 
 >Plugin protocol.
558    </p>
559    <pre>
n377 n
378<strong>sync</strong> <strong>protocol</strong> Plugin {
379  <strong>manages</strong> PluginInstance;
380 
381<strong>child</strong>:
382  <strong>sync</strong> Init() <strong>returns</strong> (int rv);
383  Deinit();
384 
385  <strong>sync</strong> PluginInstance(String type, StringArray a
>rgs) <strong>returns</strong> (int rv); 
386  ~PluginInstance();
387}
388</pre>
389    <p>
390      We added four new chunks of syntax. The first is a "protoco
>l include," which are different from C++ includes in IPDL. IPDL i 
>mplicitly defines "include guards" for protocol specifications, a 
>nd actually reads and parses included protocol files. IPDL also a 
>llows C++ headers to be included, but these are completely transp 
>arent to IPDL (see PluginInstance.ipdl below). 
391    </p>
392    <p>
393      The second new statement is a "manages statement." Here we 
>declare that the Plugin protocol manages the PluginInstance proto 
>col (which is defined in the included "PluginInstance.ipdl" speci 
>fication). This means that the Plugin protocol must provide a "co 
>nstructor" and "destructor" for PluginInstance actors; these are  
>akin to factory methods. The "manages" statement also means that  
>PluginInstance actors are tied to the lifetime of the Plugin acto 
>r that creates them --- that is, once the Plugin actor dies, all  
>the PluginInstances become invalid. 
394    </p>
395    <p>
396      The third and fourth new statements are "constructor" and "
>destructor" message declarations. The syntax was borrowed from C+ 
>+, but the semantics are different. The first difference is that  
>constructors and destructors have a direction, like other IPDL me 
>ssages. They also can have arbitrary parameters and return values 
>, and can additionally have any IPDL messaging semantics. Take ou 
>r word that this is useful; the reason that constructors and dest 
>ructors behave like other messages will be explained below. 
397    </p>
398    <p>
399      Managed protocols require constructor and destructor declar
>ations. The IPDL compiler ensures this. The constructor declarati 
>on for a managed protocol must appear in the managing protocol's  
>IPDL file. Similarly for the destructor declaration. 
400    </p>
401    <p>
402      Constructors and destructors turn into C++ interface method
>s that are almost the same as other IPDL interface methods genera 
>ted for message declarations, with one notable exception: the imp 
>lementing C++ class must provide actual methods for allocating an 
>d deallocating the sub-protocol actors. This is shown below. 
403    </p>
404    <pre>
405//class PluginParent { ...
406  // NOTE: these two methods are basically the same for PluginPar
>ent and PluginChild 
407  <strong>virtual</strong> PluginInstanceParent* PluginInstanceCo
>nstructor( 
408          <strong>const</strong> String&amp; type,
409          <strong>const</strong> StringArray&amp; args,
410          <strong>int</strong>* rv) = 0;
411  <strong>virtual</strong> nsresult PluginInstanceDestructor(Plug
>inInstanceParent* __a) = 0; 
412  
413  // NOTE: PluginChild does not have "Recv*" analogues of these m
>ethods 
414  PluginInstanceParent* SendPluginInstanceConstructor(
415          <strong>const</strong> String&amp; type,
416          <strong>const</strong> StringArray&amp; args,
417          <strong>int</strong>* rv)
418  { /* boilerplate code */ }
419  nsresult SendPluginInstanceDestructor(PluginInstanceParent* __a
>) 
420  { /* boilerplate code */ }
421</pre>
422    <pre>
423//class PluginChild {...
424  // NOTE: these two methods are basically the same for PluginPar
>ent and PluginChild 
425  <strong>virtual</strong> PluginInstanceChild* PluginInstanceCon
>structor( 
426          <strong>const</strong> String&amp; type,
427          <strong>const</strong> StringArray&amp; args,
428          <strong>int</strong>* rv) = 0;
429  <strong>virtual</strong> nsresult PluginInstanceDestructor(Plug
>inInstanceChild* __a) = 0; 
430</pre>
431    <p>
432      Let's break apart this example quickly. Both the PluginPare
>nt and PluginChild have to be able to allocate and deallocate raw 
> PluginInstance's; IPDL requires your C++ code to do this by impl 
>ementing the PluginInstanceConstructor/PluginInstanceDestructor i 
>nterface. (Your code must do this, because IPDL has no idea what  
>concrete classes you'll have implementing the PluginInstance abst 
>ract classes, and it's best that IPDL does not know this.) 
433    </p>
434    <p>
435      Different from this <em>raw</em> C++ allocation/deallocatio
>n is the <em>protocol-level</em> allocation/deallocation, done by 
> actors sending each other constructor/destructor messages. This  
>is the second component of the C++ interface above; note that the 
> interface generated for ctor/dtor messages is basically identica 
>l to that generated for other messages. (There's one exception: t 
>he PluginChild does not need to implement "RecvPluginInstanceCons 
>tructor()" and "RecvPluginInstancecDestructor()" handlers. IPDL k 
>nows what this code should do and thus generates it for you.) The 
> real secret "secret sauce" to IPDL ctors/dtors is that the gener 
>ated code is smart enough to know when to invoke the C++-level al 
>location/deallocation "factory methods." Your code need not worry 
> about this. 
436    </p>
437    <p>
438      Next, let's take a look at the PluginInstance sub-protocol.
439    </p>
440    <pre>
441// ----- file PluginInstance.ipdl
442<strong>include</strong> "mozilla/plugins/PluginTypes.h"
443<strong>using</strong> mozilla::plugins::PluginWindow;
444 
445<strong>sync</strong> <strong>protocol</strong> PluginInstance {
446  <strong>manager</strong> Plugin;
447 
448<strong>child</strong>:
449  SetWindow(PluginWindow window);
450  Paint();
451 
452<strong>parent</strong>:
453  <strong>sync</strong> GetBrowserValue(String key) <strong>retur
>ns</strong> (String value); 
454};
455</pre>
456    <p>
457      This protocol doesn't introduce any wildly new features; th
>ree new bits of syntax. First, PluginInstance.ipdl contains a "C+ 
>+ include." This is transparent to IPDL, and is merely passed thr 
>ough to generated C++ code (i.e., IPDL doesn't even care if the f 
>ile exists.) The second bit of new syntax is the "using statement 
>," which pulls a non-builtin C++ type into IPDL's type system. Th 
>is statement is modeled after C++'s using statement and should ho 
>pefully be familiar. 
458    </p>
459    <p>
460      The last bit of new syntax is the "manager statement." This
> tells IPDL that the PluginInstance protocol is managed by the Pl 
>ugin protocol. (Yes, "manager" is redundant. It exists for a vari 
>ety of uninteresting reasons.) 
461    </p>
462    <p>
463      At this point, it's worth noting two more facts about proto
>col management: first, to reiterate, the PluginInstance protocol  
>can manage <em>its own</em> protocols. For example, in real life, 
> PluginInstances manage "PluginScriptObject" and "PluginStream" p 
>rotocols. The second bit of trivia is an implementation detail: i 
>n the current IPDL implementation, there is exactly one top-level 
> protocol per underlying socket. However, this might change. 
464    </p>
465    <p>
466      <a id="Protocol_state_machines" name="Protocol_state_machin
>es"></a> 
467    </p>
468    <h2>
469      <a id="Protocol_state_machines" name="Protocol_state_machin
>es"><span class="mw-headline">Protocol state machines</span></a> 
470    </h2>
471    <p>
472      <a id="Protocol_state_machines" name="Protocol_state_machin
>es">The astute reader might question why IPDL includes the word " 
>protocol" when all that has been introduced so far are unstructur 
>ed grab-bags of messages. IPDL allows protocol authors to define  
>the order and structure of how messages may be sent/received by d 
>efining protocol <em>state machines</em> (finite state machines). 
></a> 
473    </p>
474    <p>
475      <a id="Protocol_state_machines" name="Protocol_state_machin
>es">[Note that the state machine portion of the IPDL compiler is  
>not complete as of this writing, 22 October 2009. IPDL code for s 
>tate machines is accepted by the compiler, but it does not affect 
> the generated C++, yet.]</a> 
476    </p>
477    <p>
478      <a id="Protocol_state_machines" name="Protocol_state_machin
>es">IPDL parent and child actors communicating via a protocol are 
> paired. Each actor in the pair follows the same state machine. T 
>he pair attempts to keep their single collective state synchroniz 
>ed. Though, it is possible that the parent and child actors may b 
>e momentarily out of sync while messages are transmitted.</a> 
479    </p>
480    <p>
481      <a id="Protocol_state_machines" name="Protocol_state_machin
>es">IPDL (arbitrarily) requires state machines to be defined from 
> the perspective of the <strong>parent</strong> side of the proto 
>col. For example, when you see the <code><strong>send</strong> Ms 
>g</code> syntax, it means "when the parent actor sends Msg".</a> 
482    </p>
483    <p>
484      <a id="Protocol_state_machines" name="Protocol_state_machin
>es">The following example shows one such state machine for the Pl 
>ugin protocol.</a> 
485    </p>
486    <pre>
487<a id="Protocol_state_machines" name="Protocol_state_machines"><s
>trong>include</strong> <strong>protocol</strong> "PluginInstance. 
>ipdl"; 
n514</a>n
n516    <p>n
517      <a id="Protocol_state_machines" name="Protocol_state_machin
>es">There are three new syntactic elements, above. First are "sta 
>te declarations": the code <code><strong>state</strong> FOO:</cod 
>e> declares a state "FOO". (States are capitalized by convention, 
> not because of syntactic rules.) The first state to be declared  
>is the protocol's "start state"; when an actor is created, its in 
>itial state is the "start state."</a> 
518    </p>588    <p>
589      There are three new syntactic elements, above. First are "s
 >tate declarations": the code <code><strong>state</strong> FOO:</c
 >ode> declares a state "FOO". (States are capitalized by conventio
 >n, not because of syntactic rules.) The first state to be declare
 >d is the protocol's "start state"; when an actor is created, its 
 >initial state is the "start state."
519    <p>590    </p>
520      <a id="Protocol_state_machines" name="Protocol_state_machin591    <p>
>es">The second new syntactic element is the <em>trigger</em>. The 
> syntax <code><strong>send</strong> MsgDecl</code> defines a trig 
>ger for a state <em>transition</em>; in this case, the trigger is 
> <code><strong>send</strong></code>ing the async or sync message  
>"MsgDecl." The triggers are:</a> 
592      The second new syntactic element is the <em>trigger</em>. T
 >he syntax <code><strong>send</strong> MsgDecl</code> defines a tr
 >igger for a state <em>transition</em>; in this case, the trigger 
 >is <code><strong>send</strong></code>ing the async or sync messag
 >e "MsgDecl." The triggers are:
n524        <a id="Protocol_state_machines" name="Protocol_state_machn596        <code><strong>send</strong></code>ing an async or sync me
>ines"><code><strong>send</strong></code>ing an async or sync mess>ssage
>age</a> 
n527        <a id="Protocol_state_machines" name="Protocol_state_machn599        <code><strong>recv</strong></code>ing an async or sync me
>ines"><code><strong>recv</strong></code>ing an async or sync mess>ssage
>age</a> 
n530        <a id="Protocol_state_machines" name="Protocol_state_machn602        <code><strong>call</strong></code>ing an RPC
>ines"><code><strong>call</strong></code>ing an RPC</a> 
n533        <a id="Protocol_state_machines" name="Protocol_state_machn605        <code><strong>answer</strong></code>ing an RPC
>ines"><code><strong>answer</strong></code>ing an RPC</a> 
n537      <a id="Protocol_state_machines" name="Protocol_state_machinn609      <strong>Aside</strong>: this is why actor ctors/dtors act l
>es"><strong>Aside</strong>: this is why actor ctors/dtors act lik>ike normal messages, with directions etc.: this allows them to be
>e normal messages, with directions etc.: this allows them to be c> checked against the protocol state machine like any other messag
>hecked against the protocol state machine like any other message.>e.
></a> 
538    </p>
539    <p>610    </p>
540      <a id="Protocol_state_machines" name="Protocol_state_machin
>es">The third new syntactic element is a state <em>transition</em 
>>. The syntax is: <code><strong>goto</strong> NEXT_STATE</code>.  
>When the trigger preceding this transition occurs, the protocol a 
>ctor's internal state is changed to, in this case, "NEXT_STATE."< 
>/a> 
541    </p>611    <p>
612      The third new syntactic element is a state <em>transition</
 >em>. The syntax is: <code><strong>goto</strong> NEXT_STATE</code>
 >. When the trigger preceding this transition occurs, the protocol
 > actor's internal state is changed to, in this case, "NEXT_STATE.
 >"
542    <p>613    </p>
543      <a id="Protocol_state_machines" name="Protocol_state_machin
>es">Another example state machine, for PluginInstance, follows.</ 
>a> 
544    </p>614    <p>
615      Another example state machine, for PluginInstance, follows.
545    <pre>616    </p>
546<a id="Protocol_state_machines" name="Protocol_state_machines"><s617    <pre>
>trong>sync</strong> <strong>protocol</strong> PluginInstance { 
618<strong>sync</strong> <strong>protocol</strong> PluginInstance {
n565</a>n
n568      <a id="Protocol_state_machines" name="Protocol_state_machinn639      <br>
>es"><br> 
569      Note:</a>640      Note:
tt643      <li>The following points will apply when the IPDL compiler 
 >fully supports states. It is incomplete as of this writing, on 22
 > October 2009.
572      <li>644      </li>
573        <a id="Protocol_state_machines" name="Protocol_state_mach645      <li>Protocol state machines are optional, but strongly enco
>ines">The following points will apply when the IPDL compiler full>uraged. Even simple state machines are useful.
>y supports states. It is incomplete as of this writing, on 22 Oct 
>ober 2009.</a> 
574      </li>
575      <li>646      </li>
576        <a id="Protocol_state_machines" name="Protocol_state_mach647      <li>All actor states, trigger matching, and transitions are
>ines">Protocol state machines are optional, but strongly encourag> managed by IPDL-generated code. Your C++ code need not manage th
>ed. Even simple state machines are useful.</a>>ese things.
577      </li>
578      <li>648      </li>
579        <a id="Protocol_state_machines" name="Protocol_state_mach649      <li>All messages sent and received are checked against the 
>ines">All actor states, trigger matching, and transitions are man>protocol's state machine. <em>If a message violates the state mac
>aged by IPDL-generated code. Your C++ code need not manage these >hine semantics defined in the IPDL code, the child process contai
>things.</a>>ning the child actor will be terminated with extreme prejudice, a
 >nd all parent actors will be made invalid!</em> It is up to the d
 >eveloper to make sure that this never happens.
580      </li>
581      <li>650      </li>
582        <a id="Protocol_state_machines" name="Protocol_state_mach
>ines">All messages sent and received are checked against the prot 
>ocol's state machine. <em>If a message violates the state machine 
> semantics defined in the IPDL code, the child process containing 
> the child actor will be terminated with extreme prejudice, and a 
>ll parent actors will be made invalid!</em> It is up to the devel 
>oper to make sure that this never happens.</a> 
583      </li>
584      <li>
585        <id="Protocol_state_machines" name="Protocol_state_mach651      <li>Lots of syntactic sugar is possible for state machine d
>ines">Lots of syntactic sugar is possible for state machine defin>efinitions. Ping the Electrolysis team if you have a good proposa
>itions. Ping the Electrolysis team if you have a good proposal.</>l
>a> 
586      </li>
587    </ul>
588    <p>
589      <a id="Protocol_state_machines" name="Protocol_state_machin
>es"></a><a id="Checkpoint_2" name="Checkpoint_2"></a> 
590    </p>
591    <h2>
592      <a id="Checkpoint_2" name="Checkpoint_2"><span class="mw-he
>adline">Checkpoint 2</span></a> 
593    </h2>
594    <p>
595      <a id="Checkpoint_2" name="Checkpoint_2">By this point in t
>he guide, you should understand</a> 
596    </p>
597    <ul>
598      <li>
599        <a id="Checkpoint_2" name="Checkpoint_2">what "protocol m
>anagement" means, and how manages/manager statements are used</a> 
600      </li>
601      <li>
602        <a id="Checkpoint_2" name="Checkpoint_2">sub-protocol act
>or constructors and destructors</a> 
603      </li>
604      <li>
605        <a id="Checkpoint_2" name="Checkpoint_2">the IPDL actor c
>tor/dtor C++ interface</a> 
606      </li>
607      <li>
608        <a id="Checkpoint_2" name="Checkpoint_2">how protocol sta
>te machines are used</a> 
609      </li>
610      <li>
611        <a id="Checkpoint_2" name="Checkpoint_2">how to define st
>ates, triggers, and transitions</a> 

Back to History