User:Tedd/ipc-doc-preview: Difference between revisions

Jump to navigation Jump to search
no edit summary
No edit summary
No edit summary
Line 1: Line 1:
This article will focus around the internal working of the Inter-Process Communication (IPC) implementation in B2G (FirefoxOS).
This article will focus on the internal workings of the Inter-Process Communication (IPC) implementation in FirefoxOS (Boot2Gecko).
It is still in development and might change a lot along the way. The main purpose of this article is, to give a detailed insight of the internal working and implementaiton.
It is still in development and might change a lot along the way. The main purpose of this article is, to give a detailed insight of the internal working and implementaiton.
To read more about the security aspect of the IPC, please check out this article (TODO: link to other article). Any feedback or suggestion is greatly appreciated.
To read more about the security aspect of the IPC, please check out this article (TODO: link to other article). Any feedback or suggestion is greatly appreciated.
Line 6: Line 6:
= Architecture =
= Architecture =
[[File:Ipc process architecture.png|300x300px|framed|right|Process architecture]]
[[File:Ipc process architecture.png|300x300px|framed|right|Process architecture]]
In FirefoxOS (Boot2Gecko) we have a Multi-process Architecture, where the apps on the phone are running in a different process, which has the least amount of priviledges. On a running system we have a signle parent process called ''b2g''. The ''b2g'' process has a child process called ''nuwa'', this process will be used to fork the app processes. Whenever a new app is being started on the phone, ''b2g'' tells ''nuwa'' that we need a new process. All child processes have the least amount of privileges possible. For every action they want to perform (that needs more privileges), they need to go through the parent process (b2g). This is where the Inter-process Communication (IPC) comes into place. Each child has a connection, using an IPC channel, to the parent which will be used for their communication. The process layout is illustrated on the right.  
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 priviledges. On a running system we have a signle parent process called ''b2g''. The ''b2g'' process has a child process called ''nuwa'', this process will be used to fork the app processes. Whenever a new app is being started on the phone, ''b2g'' tells ''nuwa'' that we need a new process. All child processes have the least amount of privileges possible. For every action they want to perform (that needs more privileges), they need to go through the parent process (b2g). This is where the Inter-process Communication (IPC) comes into place. Each child has a connection, using an IPC channel, to the parent which will be used for their communication. The process layout is illustrated on the right.  


= Setup =
= Setup =
Line 118: Line 118:
Here a short illustration of the call flow:
Here a short illustration of the call flow:
[[File:Ipc channel create.png|700px|frameless|center|Call flow for IPC Channel creation]]
[[File:Ipc channel create.png|700px|frameless|center|Call flow for IPC Channel creation]]
= Spawning =
In the previous section, we learned how ''IOLoop'' 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 ''nuwa'' process and the children of ''nuwa''.
At this point I would suggest reading the [https://developer.mozilla.org/en-US/docs/IPDL/Tutorial IPDL Tutorial], because from this point on we will reference to some of the classes generated from those IPDL files.
== Nuwa ==
=== creating the process ===
Throughout the initialization phase of the ''b2g'' process, an instance of the singleton class '''[https://github.com/mozilla/gecko-dev/blob/6f80c55849c36f46f48941f735c8228b7e2f36d0/dom/ipc/PreallocatedProcessManager.cpp#L36 PreallocatedProcessManagerImpl]''' will be created. This instance is mainly accessed through a couple of static functions defined in the '''[https://github.com/mozilla/gecko-dev/blob/6f80c55849c36f46f48941f735c8228b7e2f36d0/dom/ipc/PreallocatedProcessManager.h#L39 PreallocatedProcessManager]''' class. The purpose of this manager is to keep track of pre-allocated processes, this will be explained in more detail in the [[#Preallocated]] seciton.
The implementation class has two important attributes:
* '''mSpareProcesses''' which is an array that contains the preallocated processes (will be important later on)
* '''mPreallocatedAppProcess''' which will be the ''nuwa'' process
This initialization happens inside the '''[https://github.com/mozilla/gecko-dev/blob/6f80c55849c36f46f48941f735c8228b7e2f36d0/dom/ipc/ContentParent.cpp#L602 ContentParent::StartUp]''' function, when exuting the following code:
<pre>
...
// Try to preallocate a process that we can transform into an app later.
PreallocatedProcessManager::AllocateAfterDelay();
...
</pre>
This call will lead to the creation of the one and only instance of '''PreallocatedProcessManagerImpl''' is created (inside the '''[https://github.com/mozilla/gecko-dev/blob/6f80c55849c36f46f48941f735c8228b7e2f36d0/dom/ipc/PreallocatedProcessManager.cpp#L102 PreallocatedProcessManagerImpl::Singleton]''' function). Right after the constructor call, the '''[https://github.com/mozilla/gecko-dev/blob/6f80c55849c36f46f48941f735c8228b7e2f36d0/dom/ipc/PreallocatedProcessManager.cpp#L125 Init]''' function is invoked. Following the call flow from there, we will end up in '''[https://github.com/mozilla/gecko-dev/blob/6f80c55849c36f46f48941f735c8228b7e2f36d0/dom/ipc/PreallocatedProcessManager.cpp#L174 Enable]'''. '''Enable''' will then schedule the ''nuwa'' fork, with a 1 second delay ([https://github.com/mozilla/gecko-dev/blob/6f80c55849c36f46f48941f735c8228b7e2f36d0/dom/ipc/PreallocatedProcessManager.cpp#L23 DEFAULT_ALLOCATE_DELAY]), by calling '''[https://github.com/mozilla/gecko-dev/blob/6f80c55849c36f46f48941f735c8228b7e2f36d0/dom/ipc/PreallocatedProcessManager.cpp#L237 ScheduleDelayedNuwaFork]'''. This gives the ''b2g'' process enough time to finish its initalization.
As soon as the delay time has passed,  the '''[https://github.com/mozilla/gecko-dev/blob/6f80c55849c36f46f48941f735c8228b7e2f36d0/dom/ipc/PreallocatedProcessManager.cpp#L255 DelayedNuwaFork]''' function is called inside the main thread.
Inside the function, we will call '''[https://github.com/mozilla/gecko-dev/blob/6f80c55849c36f46f48941f735c8228b7e2f36d0/dom/ipc/ContentParent.cpp#L551 ContentParent::RunNuwaProcess]''' which returns a pointer to a '''[https://github.com/mozilla/gecko-dev/blob/6f80c55849c36f46f48941f735c8228b7e2f36d0/dom/ipc/ContentParent.h#L66 ContentParent]''' object, this object represents our ''nuwa'' process.
Inside the '''ContentParent''' constructor, a couple of interesting things happen.
* we insert the new '''ContentParent''' into the global static list called '''[https://github.com/mozilla/gecko-dev/blob/6f80c55849c36f46f48941f735c8228b7e2f36d0/dom/ipc/ContentParent.cpp#L512 sContentParent]'''
* we create a '''[https://github.com/mozilla/gecko-dev/blob/6f80c55849c36f46f48941f735c8228b7e2f36d0/ipc/glue/GeckoChildProcessHost.h#L28 GeckoChildProcessHost]''' instance
* we call the '''[https://github.com/mozilla/gecko-dev/blob/6f80c55849c36f46f48941f735c8228b7e2f36d0/ipc/glue/GeckoChildProcessHost.cpp#L385 LaunchAndWaitForProcessHandle]''' method of '''GeckoChildProcessHost'''
The '''LaunchAndWaitForProcessHandle''' method will schedule a task inside the ''IOLoop'' thread. In the ''IOLoop'' thread, '''[https://github.com/mozilla/gecko-dev/blob/6f80c55849c36f46f48941f735c8228b7e2f36d0/ipc/glue/GeckoChildProcessHost.cpp#L479 RunPerformAsyncLaunch]''' is called. After a few calls, we will end up in the '''[https://github.com/mozilla/gecko-dev/blob/6f80c55849c36f46f48941f735c8228b7e2f36d0/ipc/chromium/src/base/process_util_linux.cc#L191 LaunchApp]''' function. This is where the forking happens. After the '''fork''', it will call '''execve''' to re-execute itself.
[[File:Ipc nuwa fork.png|900px|frameless|center|Call flow for nuwa fork]]
=== connect to the channel ===
== Preallocated ==
Confirmed users
85

edits

Navigation menu