IPDL/Getting started: Difference between revisions

Jump to navigation Jump to search
No edit summary
Line 30: Line 30:
== Messages ==
== Messages ==


Next.
It is very important to understand message semantics. It's tempting to think of protocol messages as C++ function calls, but that's not very useful.  We'll delve into gory details of the above example to illustrate these semantics.  To keep the example as concrete as possible, we first need to take a detour into how the above example is translated into something that C++ code can utilize.
 
The above specification will generate three headers: PluginProtocolParent.h, PluginProtocolChild.h, and PluginProtocol.h (we'll ignore the third completely; it's full of uninteresting implementation details).  As you might guess, PluginProtocolParent.h defines a C++ class (PluginProtocolParent) that code on the parent side utilizes, the browser in this example.  And similarly, code running in the plugin process will use the PluginProtocolChild class.
 
These Parent and Child classes are "abstract" in the Java sense.  The PluginProcotolParent class will look something like the following in C++
 
  class PluginProtocolParent {
  public:
      void SendInit()
      {
          // boilerplate generated code ...
      }
      void SendDeinit()
      {
          // boilerplate generated code ...
      }
  };
 
and the PluginProtocolChild will be something like:
 
  class PluginProtocolChild {
  protected:
      virtual void RecvInit() = 0;
      virtual void RecvDeinit() = 0;
  };
 
These Parent and Child abstract classes take care of all the "protocol layer" concerns; sending messages, checking protocol safety (we'll discuss that later), and so forth.  However, these abstract classes can do nothing but send and receive messages; they don't actually ''do'' anything, like draw to the screen or write to files.  It's up to ''implementing'' C++ code to actually do interesting things with the messages.
 
So these abstract Parent and Child classes are meant to be subclassed by C++ ''implementors''.  Below is a dirt simple example of how a browser implementor might utilize the PluginProtocolParent
 
  class PluginParent : public PluginProtocolParent {
  public:
      PluginParent(string pluginDsoFile) {
          // launch child plugin process
      }
  };
 
This is a boring class.  It simply launches the plugin child process.  Note that since PluginParent inherits from PluginProtocolParent, the browser code can invoke the <code>SendInit()</code> and <code>SendDeinit()</code> methods on PluginParent objects.  We'll show an example of this below.
 
Here's how the PluginProtocolChild might be used by a C++ implementor in the plugin process:
 
  class PluginChild : public PluginProtocolChild {
  protected:
      // implement the PluginProtocolChild "interface"
      void RecvInit() {
          printf("Init() message received\n");
          // initialize the plugin module
      }
      void RecvDeinit() {
          printf("Deinit() message received\n");
          // deinitialize the plugin module
      }
 
  public:
      PluginChild(string pluginDsoFile) {
          // load the plugin DSO
      }
  };
 
The PluginChild is more interesting: it implements the "message handlers" RecvInit() and RecvDeinit() that will be automatically invoked by the protocol code when the plugin process receives the Init() and Deinit() messages, respectively.
 
Let's run through an example of how this dirt simple protocol and its implementation could be used.  In the table below, the first column shows C++ statements executing in the browser process, and the second shows C++ statements executing in the plugin process.
 
{| border="1"
|+ Example execution of PluginParent and PluginChild
! Browser process !! Plugin process
|-
| BrowserMain.cc: PluginParent* pp = new PluginParent("libflash.so");
|
|-
| (do browser stuff)
| ''plugin process is created''
|-
| ...
| PluginMain.cc: PluginChild* pc = new PluginChild("libflash.so");
|-
| BrowserMain.cc: pp->SendInit();
| (spin event loop)
|-
| PluginProtocolParent.h: (construct Init() message, send it)
| ...
|-
| (spin event loop)
| PluginProtocolChild.h: (unpack Init() message, call RecvInit();)
|-
| ...
| PluginChild.cc: RecvInit() { // do stuff }
|-
| ...
| ...
|}
 
'''TODO: is it clear what is going on here?'''
 
=== Direction ===
 
=== Semantics ===
Confirmed users
699

edits

Navigation menu