aboutsummaryrefslogtreecommitdiff
path: root/files/ja/archive/b2g_os/security/b2g_ipc_internals/index.html
diff options
context:
space:
mode:
Diffstat (limited to 'files/ja/archive/b2g_os/security/b2g_ipc_internals/index.html')
-rw-r--r--files/ja/archive/b2g_os/security/b2g_ipc_internals/index.html254
1 files changed, 0 insertions, 254 deletions
diff --git a/files/ja/archive/b2g_os/security/b2g_ipc_internals/index.html b/files/ja/archive/b2g_os/security/b2g_ipc_internals/index.html
deleted file mode 100644
index 46f203dbd2..0000000000
--- a/files/ja/archive/b2g_os/security/b2g_ipc_internals/index.html
+++ /dev/null
@@ -1,254 +0,0 @@
----
-title: B2G IPC internals
-slug: Archive/B2G_OS/Security/B2G_IPC_internals
-translation_of: Archive/B2G_OS/Security/B2G_IPC_internals
----
-<div class="note">
-<p>この記事は Firefox OS (Boot2Gecko) のプロセス間通信(IPC)の内部実装について記載しています。<br>
- これはまだ開発中で今後変わる可能性があります。この記事の目的はプロセス間通信の内部動作と実装の詳細を知ってもらうことです。<br>
- IPC のセキュリティ局面を知りたい場合は、これ以外の記事を参考にしてください。(TODO: 記事へのリンクを追加する)。フェードバックや提案を歓迎します。</p>
-</div>
-
-<h2 id="アーキテクチャ">アーキテクチャ</h2>
-
-<p><img alt="" src="https://mdn.mozillademos.org/files/8103/illu1_arch.png" style="border-style: solid; border-width: 1px; float: right; height: 283px; width: 300px;"><br>
- In FirefoxOS we have a Multi-process Architecture where the apps on the phone are running in a different process which has the least amount of privileges.<br>
- Firefo OS では最小限の権限を持った異なる複数のプロセスが端末で動作するように、マルチプロセスのアーキテクチャを持っています。システム上1つの b2g と呼ばれる親プロセスが存在します。b2g は nuwa と呼ばれる子プロセスがいます。このプロセスはアプリプロセスとしてフォークするために利用されます。アプリが起動する際に、b2g は nuwa に新規プロセス起動を通知します。通常、子プロセスは最小の権限で起動します。実行させたい動作(権限が必要なもの)は、親プロセス(b2g)を通す必要があります。これはプロセス間通信(Inter-process Communication : IPC)で実現しています。各子プロセスは IPC チャンネルを利用し、親プロセスと通信しています。プロセスのレイアウトは右図の通りです。</p>
-
-<h2 id="セットアップ">セットアップ</h2>
-
-<p>設計の概要を知るためには、どのように通信しているか詳細を知る必要があります。<br>
- 実際には Unix socket を利用しており、これはプロセスを超えてメッセージを送信するために <strong>socketpair</strong> システムを使って作成されます。通信の送受信をする際に、<strong>sendmsg</strong> や <strong>recvmsg</strong> を使うことで実現しています。各プロセスはソケット操作を行うための専用のスレッドを持っており、これは <em>IOLoop</em> と呼ばれます。各 <em>IOLoop</em> スレッドは送信メッセージのキューを持っており、これはチャンネルを超えたメッセージを送れるようにメインスレッドを利用しています。</p>
-
-<p><img alt="" src="https://mdn.mozillademos.org/files/8105/illu2_ioloop.png" style="height: 203px; width: 700px;"></p>
-
-<h3 id="IOLoop">IOLoop</h3>
-
-<p>IOLoop スレッドは b2g 起動時に 親プロセスで作成され、nuwa をフォークした後に各プロセスでも作成されます。</p>
-
-<h4 id="親プロセス"><strong>親プロセス</strong></h4>
-
-<p>親プロセス(b2g) では IOLoop が早い段階で作成されます。もっと詳しく何が怒っているかを知るには <strong><a href="https://github.com/mozilla/gecko-dev/blob/afdf8e01dd69dc75c88acebafd773508f97f91e4/xpcom/build/nsXPComInit.cpp#L451">NS_InitXPCOM2</a></strong> 関数をみてください。以下は実際にスレッドが始まるための初期化のコードの一例です。</p>
-
-<pre>...
-scoped_ptr&lt;BrowserProcessSubThread&gt; ioThread(
- new BrowserProcessSubThread(BrowserProcessSubThread::IO));
-...
-ioThread-&gt;StartWithOptions(options)
-...</pre>
-
-<p><strong><em>ioThread</em></strong> は <strong><a href="https://github.com/mozilla/gecko-dev/blob/e72ffaed408cab53a4cf4ca152089c9c38d2921c/ipc/chromium/src/base/thread.h">base::Thread</a></strong> を継承した <strong><a href="https://github.com/mozilla/gecko-dev/blob/82ff7027aac0f7578d5c26567d8ac8e4b5d2b647/ipc/glue/BrowserProcessSubThread.h">BrowserProcessSubThread</a></strong> インスタンスです。これは <strong><a href="https://github.com/mozilla/gecko-dev/blob/e2ff646a3cd6d91020d037e633c9776026871b71/ipc/chromium/src/base/platform_thread.h">PlatformThread::Delegate</a></strong> のサブクラスです。</p>
-
-<p><strong>StartWithOptions</strong> は実際に、<strong>base::Thread </strong>で定義されています。<br>
- The call will lead to a couple of more calls which will eventually end up at <strong>pthread_create</strong>. The function started in the new thread is <strong><a href="https://github.com/mozilla/gecko-dev/blob/e2ff646a3cd6d91020d037e633c9776026871b71/ipc/chromium/src/base/platform_thread_posix.cc#L36">ThreadFunc</a></strong>. <strong><em>ioThread</em></strong> object is passed along the calls and <strong><em>ioThread</em>-&gt;<a href="https://github.com/mozilla/gecko-dev/blob/e2ff646a3cd6d91020d037e633c9776026871b71/ipc/chromium/src/base/thread.cc#L139">ThreadMain()</a></strong> is called in the new thread.</p>
-
-<p><img alt="" src="https://mdn.mozillademos.org/files/8107/illu3_parent_startup.png" style="height: 469px; width: 900px;"></p>
-
-<p><strong>ThreadMain</strong> is now running in the <em>IOLoop</em> thread, it will call <strong>Init()</strong> of the current instance and also create a <strong>MessageLoop</strong> instance to call the <strong>Run()</strong> method. We will &lt;come any="" back="" is="" it="" later="" not="" of="" p="" part="" since="" startup="" that="" the="" thread="" to=""&gt; &lt;/come&gt;revisit this part later on, since it is not involved further in thread startup.</p>
-
-<pre>...
-// The message loop for this thread.
-MessageLoop message_loop(startup_data_-&gt;options.message_loop_type);
-...
-// Let the thread do extra initialization.
-// Let's do this before signaling we are started.
-Init();
-...
-message_loop.Run();
-...
-</pre>
-
-<h4 id="Child"><strong>Child<a name="section_child"></a></strong></h4>
-
-<p>For the child <em>IOLoop</em> thread spawn, we have to look at the <em>nuwa</em> process as a child of <em>b2g</em> and also at the forked processes of <em>nuwa</em>.</p>
-
-<p>Exactly how <em>b2g</em> spawns <em>nuwa</em> will be covered later; for now we assume that the <em>nuwa</em> process already exists. Once <em>nuwa</em> is created, we eventually reach the <strong><a href="https://github.com/mozilla/gecko-dev/blob/9ce7e9c08958e1c4f059fed6fedf07b49ab7285f/toolkit/xre/nsEmbedFunctions.cpp#L272">XRE_InitChildProcess</a></strong> function. This function is responsible for creating the <em>IOLoop</em> thread at <strong><a href="https://github.com/mozilla/gecko-dev/blob/9ce7e9c08958e1c4f059fed6fedf07b49ab7285f/toolkit/xre/nsEmbedFunctions.cpp#L493">this</a></strong> line:</p>
-
-<pre>process = new ContentProcess(parentHandle);
-</pre>
-
-<p>In the <strong><a href="https://github.com/mozilla/gecko-dev/blob/d768d99a05bb25d2b97bcdd3c08e887ae3a1c98d/dom/ipc/ContentProcess.h#L30">ContentProcess</a></strong> constructor, the <strong><a href="https://github.com/mozilla/gecko-dev/blob/fdbc9a2330b9e9c80aa81ff1bc39b39c04af2c9f/ipc/glue/ProcessChild.cpp#L19">ProcessChild</a></strong> constructor is called, which leads to a call of the <strong><a href="https://github.com/mozilla/gecko-dev/blob/a64afe22b9cae676a20c4d72776922ca6756648c/ipc/chromium/src/chrome/common/child_process.cc#L20">ChildProcess</a></strong> constructor. The important part to note here is that the <strong>ChildProcess</strong> constructor gets passed a new instance of <strong><a href="https://github.com/mozilla/gecko-dev/blob/82ff7027aac0f7578d5c26567d8ac8e4b5d2b647/ipc/glue/IOThreadChild.h#L18">IOThreadChild</a></strong>. Within the constructor, the <strong><a href="https://github.com/mozilla/gecko-dev/blob/f5213d3e6666c532cbcd20837188d3b0fbcc950d/ipc/chromium/src/chrome/common/child_thread.cc#L33">Run()</a></strong> is called on the passed <strong>IOThreadChild</strong> object:</p>
-
-<pre>ChildProcess::ChildProcess(ChildThread* child_thread)
- : child_thread_(child_thread),
- ...
-{
- ...
- child_thread_-&gt;Run();
-}
-</pre>
-
-<p>From there, the <strong><a href="https://github.com/mozilla/gecko-dev/blob/e72ffaed408cab53a4cf4ca152089c9c38d2921c/ipc/chromium/src/base/thread.cc#L77">StartWithOptions</a></strong> function is called. At this point it follows the same code path as for the main <em>IOLoop</em> startup. The only exception is that it is an <strong>IOThreadChild</strong> instance and not a <strong>BrowserProcessSubThread</strong> (see the b2g process illustration above for reference).</p>
-
-<p>Below is an illustration of the <em>IOLoop</em> thread spawn in the  <em>nuwa</em> process :</p>
-
-<p><img alt="" src="https://mdn.mozillademos.org/files/8115/ipc_nuwa_ioloop.png" style="height: 566px; width: 650px;"></p>
-
-<p>This is the case for the original <em>nuwa</em> process. All future children will be forked from <em>nuwa</em>, and since <strong>fork</strong> only copies the thread it was called in to the new process, all threads so far would be lost.</p>
-
-<p>We want to have all threads from <em>nuwa</em> (along with the <em>IOLoop</em>) in the forked process. In order to do that, <strong>pthread_create</strong> is not called directly, instead, the call is routed to <strong><a href="https://github.com/mozilla/gecko-dev/blob/58e49a079d477e5963a4180f674fbbd88534f76c/mozglue/build/Nuwa.cpp#L656">__wrap_pthread_create</a></strong> which wraps the real <strong>pthread_create</strong>. The purpose of the wrapper function is to maintain a static list of startup information for all created threads (<strong><a href="https://github.com/mozilla/gecko-dev/blob/58e49a079d477e5963a4180f674fbbd88534f76c/mozglue/build/Nuwa.cpp#L255">sAllThreads</a></strong>). This list will be copied to the new process, and the new process will then call <strong><a href="https://github.com/mozilla/gecko-dev/blob/58e49a079d477e5963a4180f674fbbd88534f76c/mozglue/build/Nuwa.cpp#L1390">RecreateThreads</a></strong> to restore all threads based on the information maintained in the list.</p>
-
-<h3 id="Channel">Channel<a name="section_channel"></a></h3>
-
-<p>In order to be able to send and receive messages, we have to create a channel between the parent and the child. This section covers the classes used for this - the actual setup between parent and child will be covered once we get to the process spawning part.</p>
-
-<p>Here is a short illustration of the call flow:</p>
-
-<p><img alt="" src="https://mdn.mozillademos.org/files/8109/ipc_channel_create.png" style="height: 353px; width: 790px;"></p>
-
-<ol>
- <li> This flow illustrates the creation of an <strong><a href="https://github.com/mozilla/gecko-dev/blob/eacb45e46d4b67a0d309e44af5de1ebede88d27b/ipc/chromium/src/chrome/common/ipc_channel.h#L15">IPC::Channel</a></strong> instance (the process of creating the instance will be covered later on). This class has two important attributes:
-
- <ul>
- <li><strong>channel_impl_</strong> which is the actual implementation of the channel (platform specific)</li>
- <li><strong>listener_</strong> which is used to pass incoming messages to</li>
- </ul>
- </li>
- <li>The posix class for the <strong>channel_impl_</strong> object can be found here (<strong><a href="https://github.com/mozilla/gecko-dev/blob/6f80c55849c36f46f48941f735c8228b7e2f36d0/ipc/chromium/src/chrome/common/ipc_channel_posix.h#L24">Channel::ChannelImpl</a></strong>). <strong>Channel::ChannelImpl</strong> has the following important attributes:
- <ul>
- <li><strong>pipe_</strong> the file descriptor of the pipe (created by <strong>socketpair</strong>) for the parent side</li>
- <li><strong>client_pipe_</strong> the client end of the pipe</li>
- <li><strong>listener_</strong> the object that receives the incoming messages</li>
- <li><strong>output_queue_</strong> a queue where all outgoing messages are pushed to</li>
- </ul>
- </li>
- <li><strong>Channel::ChannelImpl</strong> has two overloaded constructors which can be used to create an object. One of them takes a file descriptor as the first argument which will be stored in <strong>pipe_</strong>. The more interesting constructor is the one which takes a <strong>channel_id</strong> (which can also be empty). Both of them also take a <strong>Mode</strong> and a <strong>Listener*</strong> pointer as second and third argument. <strong>Mode</strong> just specifies if we are the server or the client. When the constructor with the <strong>channel_id</strong> is called, <strong><a href="https://github.com/mozilla/gecko-dev/blob/6f80c55849c36f46f48941f735c8228b7e2f36d0/ipc/chromium/src/chrome/common/ipc_channel_posix.cc#L303">CreatePipe</a></strong> will be called from there. We have to distinguish two different cases from here:
- <ul>
- <li><code>Mode == MODE_SERVER</code>: In this case, <strong>socketpair</strong> will be called. One end of the pipe will be stored in <strong>pipe_</strong> the other in <strong>client_pipe_</strong>. If <strong>channel_id</strong> is not empty, we insert a new entry in a <strong><a href="https://github.com/mozilla/gecko-dev/blob/6f80c55849c36f46f48941f735c8228b7e2f36d0/ipc/chromium/src/chrome/common/ipc_channel_posix.cc#L83">PipeMap</a></strong> where we associate <strong>client_pipe_</strong> with the given <strong>channel_id</strong>.</li>
- <li><code>Mode != MODE_SERVER</code>: In this case, we call <strong><a href="https://github.com/mozilla/gecko-dev/blob/6f80c55849c36f46f48941f735c8228b7e2f36d0/ipc/chromium/src/chrome/common/ipc_channel_posix.cc#L129">ChannelNameToClientFD</a></strong>, which looks inside the <strong>PipeMap</strong> for an entry with the given <strong>channel_id</strong>. The result will be stored in <strong>pipe_</strong>.</li>
- </ul>
- </li>
- <li>After the object creation is completed, the <strong><a href="https://github.com/mozilla/gecko-dev/blob/6f80c55849c36f46f48941f735c8228b7e2f36d0/ipc/chromium/src/chrome/common/ipc_channel_posix.cc#L395">Connect</a></strong> method can be called. This method will tell <em>libevent</em> to notify us whenever something has been written to <strong>pipe_</strong> and is ready to be received.</li>
- <li><strong><a href="https://github.com/mozilla/gecko-dev/blob/6f80c55849c36f46f48941f735c8228b7e2f36d0/ipc/chromium/src/chrome/common/ipc_channel_posix.cc#L818">OnFileCanReadWithoutBlocking</a></strong> is the callback for this event. This function will then call a function to read the message from the file descriptor, and then the message will be passed to the <strong>OnMessageReceived</strong> function inside the <strong>listener_</strong> (this will be covered later).</li>
-</ol>
-
-<h2 id="Spawning">Spawning</h2>
-
-<p>In the previous section, we learned how <em>IOLoop</em> is created and how a channel is created. Throughout the last sections, we made the assumption that a process has already been started. This section will cover how those processes actually get started and how they connect to the IPC::Channel. We will again have to distinguish between the <em>nuwa</em> process and the children of <em>nuwa</em>.</p>
-
-<p>At this point, if you are not already familiar with IPDL consider reading the <a href="https://developer.mozilla.org/en-US/docs/IPDL/Tutorial">IPDL Tutorial</a> because from this point on we will reference some of the classes generated from those IPDL files.</p>
-
-<h3 id="Nuwa">Nuwa</h3>
-
-<h4 id="Creating_the_process"><strong>Creating the process</strong></h4>
-
-<p>Throughout the initialization phase of the <em>b2g</em> process, an instance of the singleton class <strong><a href="https://github.com/mozilla/gecko-dev/blob/6f80c55849c36f46f48941f735c8228b7e2f36d0/dom/ipc/PreallocatedProcessManager.cpp#L36">PreallocatedProcessManagerImpl</a></strong> will be created. This instance is mainly accessed through a couple of static functions defined in the <strong><a href="https://github.com/mozilla/gecko-dev/blob/6f80c55849c36f46f48941f735c8228b7e2f36d0/dom/ipc/PreallocatedProcessManager.h#L39">PreallocatedProcessManager</a></strong> class. The purpose of this manager is to keep track of pre-allocated processes. This will be explained in more detail in the <a href="#section_preallocated">#Preallocated </a>section.</p>
-
-<p>The implementation class has two important attributes:</p>
-
-<ul>
- <li><strong>mSpareProcesses</strong> which is an array that contains the preallocated processes (which will be important later on)</li>
- <li><strong>mPreallocatedAppProcess</strong> which will be the <em>nuwa</em> process</li>
-</ul>
-
-<p>This initialization happens inside the <strong><a href="https://github.com/mozilla/gecko-dev/blob/6f80c55849c36f46f48941f735c8228b7e2f36d0/dom/ipc/ContentParent.cpp#L602">ContentParent::StartUp</a></strong> function when executing the following code:</p>
-
-<pre>...
-// Try to preallocate a process that we can transform into an app later.
-PreallocatedProcessManager::AllocateAfterDelay();
-...
-</pre>
-
-<p>This call will lead to the creation of the one and only instance of <strong>PreallocatedProcessManagerImpl</strong> (located inside the <strong><a href="https://github.com/mozilla/gecko-dev/blob/6f80c55849c36f46f48941f735c8228b7e2f36d0/dom/ipc/PreallocatedProcessManager.cpp#L102">PreallocatedProcessManagerImpl::Singleton</a></strong> function). Right after the constructor call, the <strong><a href="https://github.com/mozilla/gecko-dev/blob/6f80c55849c36f46f48941f735c8228b7e2f36d0/dom/ipc/PreallocatedProcessManager.cpp#L125">Init</a></strong> function is invoked. Following the call flow from there, we will end up in <strong><a href="https://github.com/mozilla/gecko-dev/blob/6f80c55849c36f46f48941f735c8228b7e2f36d0/dom/ipc/PreallocatedProcessManager.cpp#L174">Enable</a></strong>. <strong>Enable</strong> will then schedule the <em>nuwa</em> fork, with a 1 second delay (<a href="https://github.com/mozilla/gecko-dev/blob/6f80c55849c36f46f48941f735c8228b7e2f36d0/dom/ipc/PreallocatedProcessManager.cpp#L23">DEFAULT_ALLOCATE_DELAY</a>), by calling <strong><a href="https://github.com/mozilla/gecko-dev/blob/6f80c55849c36f46f48941f735c8228b7e2f36d0/dom/ipc/PreallocatedProcessManager.cpp#L237">ScheduleDelayedNuwaFork</a></strong>. This gives the <em>b2g</em> process enough time to finish its initialization.</p>
-
-<p>As soon as the delay time has passed, the <strong><a href="https://github.com/mozilla/gecko-dev/blob/6f80c55849c36f46f48941f735c8228b7e2f36d0/dom/ipc/PreallocatedProcessManager.cpp#L255">DelayedNuwaFork</a></strong> function is called inside the main thread. Inside the function, we will call <strong><a href="https://github.com/mozilla/gecko-dev/blob/6f80c55849c36f46f48941f735c8228b7e2f36d0/dom/ipc/ContentParent.cpp#L551">ContentParent::RunNuwaProcess</a></strong> which returns a pointer to a <strong><a href="https://github.com/mozilla/gecko-dev/blob/6f80c55849c36f46f48941f735c8228b7e2f36d0/dom/ipc/ContentParent.h#L66">ContentParent</a></strong> object; this object represents our <em>nuwa</em> process.</p>
-
-<p>Inside the <strong>ContentParent</strong> constructor, a couple of interesting things happen.</p>
-
-<ul>
- <li>we insert the new <strong>ContentParent</strong> into the global static list, called <strong><a href="https://github.com/mozilla/gecko-dev/blob/6f80c55849c36f46f48941f735c8228b7e2f36d0/dom/ipc/ContentParent.cpp#L512">sContentParent</a></strong></li>
- <li>we create a <strong><a href="https://github.com/mozilla/gecko-dev/blob/6f80c55849c36f46f48941f735c8228b7e2f36d0/ipc/glue/GeckoChildProcessHost.h#L28">GeckoChildProcessHost</a></strong> instance</li>
- <li>we call the <strong><a href="https://github.com/mozilla/gecko-dev/blob/6f80c55849c36f46f48941f735c8228b7e2f36d0/ipc/glue/GeckoChildProcessHost.cpp#L385">LaunchAndWaitForProcessHandle</a></strong> method of <strong>GeckoChildProcessHost</strong></li>
-</ul>
-
-<p>The <strong>LaunchAndWaitForProcessHandle</strong> method will schedule a task inside the <em>IOLoop</em> thread. In the <em>IOLoop</em> thread, <strong><a href="https://github.com/mozilla/gecko-dev/blob/6f80c55849c36f46f48941f735c8228b7e2f36d0/ipc/glue/GeckoChildProcessHost.cpp#L479">RunPerformAsyncLaunch</a></strong> is called. After a few calls, we will end up in the <strong><a href="https://github.com/mozilla/gecko-dev/blob/6f80c55849c36f46f48941f735c8228b7e2f36d0/ipc/chromium/src/base/process_util_linux.cc#L191">LaunchApp</a></strong> function. This is where the forking happens. After the <strong>fork</strong>, it will call <strong>execve</strong> in the child to re-execute itself.</p>
-
-<p><img alt="" src="https://mdn.mozillademos.org/files/8113/ipc_nuwa_fork.png" style="height: 618px; width: 1000px;"></p>
-
-<h4 id="Connecting_to_the_channel"><strong>Connecting to the channel</strong></h4>
-
-<p>We covered the actual spawning. What's left is the part where the parent (<em>b2g</em>) and the child (<em>nuwa</em>) connect to the same IPC channel. We have two important calls for that on the parent side: one is made before the child is spawned and the other after the spawn. The first one is in the <strong>RunPerformAsynchLaunch</strong> function. Before actually calling <strong>PerformAsynchLaunch</strong> (the position is marked with a 'x' in the above diagram), we call <strong><a href="https://github.com/mozilla/gecko-dev/blob/6f80c55849c36f46f48941f735c8228b7e2f36d0/ipc/glue/GeckoChildProcessHost.cpp#L405">InitializeChannel</a></strong>, and this will call <strong><a href="https://github.com/mozilla/gecko-dev/blob/6f80c55849c36f46f48941f735c8228b7e2f36d0/ipc/chromium/src/chrome/common/child_process_host.cc#L77">CreateChannel</a></strong>. At this point a new <strong>IPC::Channel</strong> object is created, so please check out the <a href="#channel_section">#Channel</a> section above.</p>
-
-<p>The <strong>GeckoChildProcessHost</strong> object created inside the <strong>ContentParent</strong> constructor serves as the <strong>listener_</strong> inside the <strong>IPC::Channel</strong> object, thus, <strong>GeckoChildProcessHost</strong> will supply the <strong><a href="https://github.com/mozilla/gecko-dev/blob/6f80c55849c36f46f48941f735c8228b7e2f36d0/ipc/glue/GeckoChildProcessHost.cpp#L895">OnMessageReceived</a></strong> function. There is nothing done there; it just saves all the incoming messages.</p>
-
-<p>At this point we can consider the parent process to be connected to the channel. This was the first important call.</p>
-
-<p>The second one is called as soon as <strong>LaunchAndWaitForProcessHandle</strong> returns (<em>nuwa</em> process is running at this point). Since the current <strong>OnMessageReceived</strong> handler doesn't do any good, we will have to assign a new <strong>listener_</strong>. In order to do that, this is being executed (<strong>mSubprocess</strong> is an instance of <strong>GeckoChildProcessHost</strong> which is created in <strong>ContentParent</strong>):</p>
-
-<pre>Open(mSubprocess-&gt;GetChannel(), mSubprocess-&gt;GetOwnedChildProcessHandle());
-</pre>
-
-<p>What happens now is a little complicated to explain just with text. I will try to illustrate the process in the end, so you might want to follow the process again with the illustration.</p>
-
-<p><strong>ContentParent</strong> actually extends <strong>PContentParent</strong> (this class is generated from the *.ipdl files that, unfortunately, I can't reference to any github or mxr location) which is defined in <em>./objdir-gecko/ipc/ipdl/PContentParent.cpp</em> relative to the root directory of FirefoxOS. <strong>PContentParent</strong> has a member variable which will be important during the <strong>Open</strong> (defined in PContentParent.cpp) call.</p>
-
-<ul>
- <li><strong>mChannel</strong> instance of <strong><a href="https://github.com/mozilla/gecko-dev/blob/6f80c55849c36f46f48941f735c8228b7e2f36d0/ipc/glue/MessageChannel.h#L40">MessageChannel</a></strong></li>
-</ul>
-
-<p><strong>MessageChannel</strong> takes a <strong>MessageListener</strong> object as the one and only argument. <strong>mChannel</strong> is created during the <strong>PContentParent</strong> construction and passes <strong>this</strong> as the <strong>MessageListener</strong> object to <strong>MessageChannel</strong> (<strong>ContentParent</strong> extends <strong>MessageListener</strong> shown below).</p>
-
-<p><strong>Open</strong> gets the <strong>IPC::Channel</strong> instance taken from <strong>mSubprocess</strong> (TODO: GetOwnedChildProcessHandle???) and calls <strong><a href="https://github.com/mozilla/gecko-dev/blob/6f80c55849c36f46f48941f735c8228b7e2f36d0/ipc/glue/MessageChannel.cpp#L299">Open</a></strong> on <strong>mChannel</strong></p>
-
-<pre>auto PContentParent::Open(
- Channel::Transport* aTransport,
- ProcessHandle aOtherProcess,
- MessageLoop* aThread,
- mozilla::ipc::Side aSide) -&gt; bool
-{
- mOtherProcess = aOtherProcess;
- return (mChannel).Open(aTransport, aThread, aSide);
-}
-</pre>
-
-<p>As a side note, <strong>Channel::Transport</strong> is a typedef of <strong>IPC::Channel</strong>. <strong>aThread</strong> and <strong>aSide</strong> are set to 0 and <em>UnknownSide</em> by default if not specified. <strong>Open</strong> inside of the <strong>MessageChannel</strong> class will create a <strong><a href="https://github.com/mozilla/gecko-dev/blob/6f80c55849c36f46f48941f735c8228b7e2f36d0/ipc/glue/MessageLink.h#L126">ProcessLink</a></strong>. <strong>This</strong> is passed to the constructor which will set <strong>mChan</strong> inside the <strong><a href="https://github.com/mozilla/gecko-dev/blob/6f80c55849c36f46f48941f735c8228b7e2f36d0/ipc/glue/MessageLink.h#L105">MessageLink</a></strong> class which <strong>ProcessLink</strong> inherits from.</p>
-
-<p>After an instance of <strong>ProcessLink</strong> is created, we call <strong><a href="https://github.com/mozilla/gecko-dev/blob/6f80c55849c36f46f48941f735c8228b7e2f36d0/ipc/glue/MessageLink.cpp#L83">Open</a></strong> on it. This sets the member variable <strong>mTransport</strong> (which represents the IPC::Channel). So <strong>mTransport</strong> is the <strong>IPC::Channel</strong> pointer we retrieved from <strong>mSubprocess</strong>.</p>
-
-<p>Since <strong>Connect</strong> has already been called when the <strong>IPC::Channel</strong> was created, we will schedule <strong>IOLoop</strong> to run <strong><a href="https://github.com/mozilla/gecko-dev/blob/6f80c55849c36f46f48941f735c8228b7e2f36d0/ipc/glue/MessageLink.cpp#L309">OnTakeConnectedChannel</a></strong>. The channel state inside the <strong>MessageChannel</strong> object will be set to <strong>ChannelConnected,</strong> and we also call <strong><a href="https://github.com/mozilla/gecko-dev/blob/eacb45e46d4b67a0d309e44af5de1ebede88d27b/ipc/chromium/src/chrome/common/ipc_channel_posix.cc#L962">set_listener</a></strong> on the <strong>IPC::Channel</strong> instance to let it know that <strong>ProcessLink</strong> will handle incoming messages. That means <strong><a href="https://github.com/mozilla/gecko-dev/blob/6f80c55849c36f46f48941f735c8228b7e2f36d0/ipc/glue/MessageLink.cpp#L270">OnMessageReceived</a></strong> inside <strong>ProcessLink</strong> is called. Those received messages will be passed to the <strong>MessageChannel</strong> and from there to the <strong>OnMessageReceived</strong> funciton inside the <strong>PContentParent</strong> class.</p>
-
-<p><img alt="" src="https://mdn.mozillademos.org/files/8117/ipc_parent_channel_connect.png" style="height: 579px; width: 1500px;"></p>
-
-<p>Now everything has been set up on the parent side. Let's get to the <em>nuwa</em> side.</p>
-
-<p>After the <strong>fork</strong>, <em>nuwa</em> inherited all the open file descriptors from the parent <em>b2g</em>, and one of them is its end of the pipe. Every child expects its end of the pipe to be file descriptor 3 (<strong><a href="https://github.com/mozilla/gecko-dev/blob/6f80c55849c36f46f48941f735c8228b7e2f36d0/ipc/chromium/src/chrome/common/ipc_channel_posix.cc#L126">kClientChannelFd</a></strong>). In order to guarantee that file descriptor 3 will be the child's end of the pipe, we call <strong><a href="https://github.com/mozilla/gecko-dev/blob/6f80c55849c36f46f48941f735c8228b7e2f36d0/ipc/chromium/src/base/file_descriptor_shuffle.h#L72">ShuffleFileDescriptors</a></strong>. This function will <strong>dup</strong> the child end of the pipe to 3. It also makes sure that in case 3 is a file descriptor needed by the child that it will be remapped to the next available.</p>
-
-<p>After the file descriptors have been remapped, we call <strong><a href="https://github.com/mozilla/gecko-dev/blob/6f80c55849c36f46f48941f735c8228b7e2f36d0/ipc/chromium/src/base/process_util_posix.cc#L107">CloseSuperfluousFds</a></strong> to close all the ones that <em>nuwa</em> doesn't need. When everything is done the child will call <strong>execve</strong> to re-execute itself.</p>
-
-<p>From here please have a look at the <a href="#section_child">#Child</a> section. The actual channel connection will happen inside the <strong>ThreadMain</strong> function inside the <em>IOLoop</em> thread. <strong>ThreadMain</strong> will call <strong><a href="https://github.com/mozilla/gecko-dev/blob/6f80c55849c36f46f48941f735c8228b7e2f36d0/ipc/chromium/src/chrome/common/child_thread.cc#L91">Init</a></strong> defined in <strong><a href="https://github.com/mozilla/gecko-dev/blob/6f80c55849c36f46f48941f735c8228b7e2f36d0/ipc/chromium/src/chrome/common/child_thread.h#L15">ChildThread</a></strong>. Inside this function, we will create a new <strong>IPC::Channel</strong> object, and you can refer to the <a href="#section_channel">#Channel</a> section from here. You will have to consider the part Mode != MODE_SERVER, therefore <strong>ChannelNameToClientFD</strong> will be called, which returns our magic file descriptor 3 (remember the child end of the pipe is mapped to this fd).</p>
-
-<p>So now, we have a connection to the channel. What is left is to set the correct listener for the incoming messages. To do so, the <strong><a href="https://github.com/mozilla/gecko-dev/blob/6f80c55849c36f46f48941f735c8228b7e2f36d0/dom/ipc/ContentProcess.cpp#L23">Init</a></strong> funciton inside <strong>ContentProcess</strong> is called. From there it will call <strong>Open</strong> in the <strong>PContentChild</strong> class, and this will lead to the same call flow as for the parent in the above diagram. The only exception we have is that these calls originate from <strong>ContentChild</strong> which inherits from <strong>PContentChild</strong>.</p>
-
-<h3 id="Preallocated">Preallocated<a name="section_preallocated"></a></h3>
-
-<h4 id="Creating_the_process_2"><strong>Creating the process</strong></h4>
-
-<p><img alt="" src="https://mdn.mozillademos.org/files/8111/ipc_fork_msg.png" style="float: right; height: 219px; width: 350px;">A <em>preallocated process</em> is a process fork()ed from <em>nuwa</em> which <em>b2g</em> keeps around to turn it later into a app process. At some point in time, <em>b2g</em> tells the <em>preallocated process</em> to turn into an app that has been started on the phone. The process will then be assigned to the privileges of the app, and the app will be able to access privleged functionality via API calls to the parent. As soon as a <em>preallocated process</em> has been turned into an app, <em>b2g</em> will tell <em>nuwa</em> to create a new <em>preallocated process</em>. So how exactly does <em>b2g</em> tell <em>nuwa</em> to create a new <em>preallocated process</em>? (NB: at this point we have an active channel connection between <em>b2g</em> and <em>nuwa.</em>)</p>
-
-<p>For initiating the <strong>fork</strong>, <em>b2g</em> sends a message through the IPC channel, and <em>nuwa</em> sends one back once it creates the new process. The message contains the PID of the new process. On the right is a little illustration of the message flow.</p>
-
-<p>Sending the initial message is initiated inside the <strong><a href="https://github.com/mozilla/gecko-dev/blob/6f80c55849c36f46f48941f735c8228b7e2f36d0/dom/ipc/PreallocatedProcessManager.cpp#L381">NuwaFork</a></strong> function. Rememeber the <strong>mPreallocatedAppProcess</strong> is an instance of <strong>ContentParent</strong> and the invoked <strong>SendNuwaFork</strong> function is actually implemented inside <strong>PContentParent</strong>.</p>
-
-<p>As soon as the child receives this messages, it will call <strong><a href="https://github.com/mozilla/gecko-dev/blob/6f80c55849c36f46f48941f735c8228b7e2f36d0/dom/ipc/ContentChild.cpp#L1876">RecvNuwaFork</a></strong> which is defined in <strong>ContentChild</strong>. Following the calls from there, we will end up in <strong><a href="https://github.com/mozilla/gecko-dev/blob/6f80c55849c36f46f48941f735c8228b7e2f36d0/mozglue/build/Nuwa.cpp#L1602">ForkIPCProcess</a></strong>.</p>
-
-<p>From there we call <strong><a href="https://github.com/mozilla/gecko-dev/blob/6f80c55849c36f46f48941f735c8228b7e2f36d0/mozglue/build/Nuwa.cpp#L1564">PrepareProtoSockets</a></strong> which calls <strong>socketpair</strong> to create a new pipe for the new child and the parent.<br>
- It is also where <strong>fork</strong> is called and our new process is born. After the <strong>fork</strong> we will call <strong><a href="https://github.com/mozilla/gecko-dev/blob/6f80c55849c36f46f48941f735c8228b7e2f36d0/mozglue/build/Nuwa.cpp#L1553">AddNewProcess</a></strong> inside <em>nuwa</em>. <strong><a href="https://github.com/mozilla/gecko-dev/blob/6f80c55849c36f46f48941f735c8228b7e2f36d0/dom/ipc/ContentChild.cpp#L1979">AddNewIPCProcess</a></strong> will then be responsible for initiating the second message. The message contains the parent side file descriptor for the pipe as well as the PID of the new process.</p>
-
-<p>On the <em>b2g</em> side the <strong><a href="https://github.com/mozilla/gecko-dev/blob/6f80c55849c36f46f48941f735c8228b7e2f36d0/dom/ipc/ContentParent.cpp#L2314">RecvAddNewProcess</a></strong> will handle the message. It will create a new <strong>ContentParent</strong> instance. This time we call the second <strong><a href="https://github.com/mozilla/gecko-dev/blob/6f80c55849c36f46f48941f735c8228b7e2f36d0/dom/ipc/ContentParent.cpp#L1767">ContentParent</a></strong> constructor. It will create the <strong>ContentParent</strong> instance based on the already existing one and with the information of the new process. This also leads to a new instance in our static <strong>sContentParents</strong> list. This basically means that we have a <strong>ContentParent</strong> instance for each process that is running.</p>
-
-<p>There is also a check in place which makes sure that only the <em>nuwa</em> process actually sends <strong>Msg_AddNewProcess</strong>:</p>
-
-<pre>...
-if (!IsNuwaProcess()) {
-...
-</pre>
-
-<p><strong><a href="https://github.com/mozilla/gecko-dev/blob/6f80c55849c36f46f48941f735c8228b7e2f36d0/dom/ipc/ContentParent.cpp#L1962">IsNuwaProcess</a></strong> checks a member variable of <strong>ContentParent</strong> whether or not it is <em>nuwa</em> who sent the message. This member variable can only be set from the parent side, and it does this during the creation of the <strong>ContentParent</strong> for the <em>nuwa</em> process.</p>
-
-<p>After initialization is finished, <strong>RecvAddNewProcess</strong> will then call <strong><a href="https://github.com/mozilla/gecko-dev/blob/6f80c55849c36f46f48941f735c8228b7e2f36d0/dom/ipc/PreallocatedProcessManager.cpp#L299">PublishSpareProcess</a></strong> to add the process to the managers list which will keep track of all existing Preallocated processes. Whenever a Preallocated process will be turned into an app process, it will be removed from that spare processes list. Here an illustration of the process:</p>
-
-<p><img alt="" src="https://mdn.mozillademos.org/files/8119/ipc_prealloc_fork.png" style="height: 540px; width: 1500px;"></p>
-
-<h4 id="Connecting_to_the_channel_2"><strong>Connecting to the channel</strong></h4>
-
-<p>TODO: write it</p>