IPDL/Shmem
Contents
Introduction
IPDL provides a built-in Shmem
type. Shmem
represents a segment of memory mapped into both a parent's and child's address space. Shmem
s are used to avoid copying large amounts of data across the IPC pipe.
Ownership model
The model is very simple: at any given time, a Shmem
is owned by either the parent or the child. Only the owner has read/write privileges; the other side has no privileges. One side transfers ownership of a Shmem
to the other by sending the Shmem
in an IPDL message, or returning it in a reply to a synchronous message.
It's illegal for C++ code to read/write a Shmem
it doesn't own. We enforce ownership semantics by mapping segments with full read/write access in the owning process, and mapping them with no access in the other process. C++ code that violates the ownership model will die from a SEGFAULT.
Using Shmem in protocols
sync protocol UsesShmem { child: // transfers ownership of |s| from parent to child async HereYouGo(Shmem s); parent: // transfers ownership of |s| from child to parent, then back to child sync GiveAndGetBack(Shmem s) returns (Shmem ss); // transfers ownership of |s| from child to parent async ThanksDone(Shmem s); };
Using Shmem in C++
class Foo : public UsesShmemParent { using mozilla::ipc::Shmem; Shmem mShmem; bool Init() { // this may fail; always check return value if (!AllocShmem(&mShmem, 10000)) return false; // get() and Size() check for proper alignment of the segment memset(mShmem.get<char>(), 0, mShmem.Size<char>()); } bool Foo() { // [do stuff] char* p = mShmem.get<char>(); if (!SendHereYouGo(mShmem)) return false; // mShmem is now unusable; both of the following would fail: // *p = 1; // mShmem.get<char>(); }
NS_OVERRIDE virtual bool RecvGiveAndGetBack(Shmem& s, Shmem* ss) { // we own |s| again // [do stuff with |s|] *ss = s; // when this method returns, we don't own |s| anymore } NS_OVERRIDE virtual bool RecvThanksDone(Shmem& s) { // we own |s| again mShmem = s; } };
Shmem
s are automatically managed by IPDL-generated code. When your protocol tree is deleted, all Shmem
s still open are unmapped and deleted.
Aside: it's not necessary to know this, but Shmem
s are actually just handles to other objects managed by IPDL-generated code.
"Unsafe" Shmem
Code that has special needs can allocate "unsafe" Shmem. "Unsafe" Shmem allows full read/write access by all processes with a reference to the segment. This means that data races are possible, unlike with normal Shmem. To create a segment, use the interface AllocUnsafeShmem()
instead of AllocShmem()
. Use with care.