Hi,

When a content process is started, a bunch of pref values are sent via
some -intPrefs/-boolPrefs/-stringPrefs arguments on the command line. This
is
ugly and limiting and causes multiple problems, so I'd like to find a
different
way to send this data.

The use case is pretty simple, because it's one way data transfer. The
important thing is that it must happen very early, i.e. before the normal
IPC
mechanism gets going.

I figured shared memory would be a reasonable way to do this, something like
the following.

- The parent sets up a shared memory segment, and writes some data to it.

- The parent spawns the child, and passes identifying information about the
  shared memory segment to the child (e.g. via the command line).

- The child gets the shared memory segment identifer, uses it to open the
  segment, and reads the data.

- The child disposes of the shared memory segment.

At first I tried using NSPR's shared memory functions, but they're not used
anywhere else in Firefox, and they have bugs, and shmget() is blocked by the
Linux sandbox.

So then I tried using base::SharedMemory instead, from
ipc/chromium/src/base/shared_memory.h, basically like this:

Parent:
    SharedMemory shm;
    shm.Create(name, size);
    shm.Open();
    shm.Map();
    char* p = shm.memory();
    ... write data to p ...
    ... launch child process, passing `name` via cmdline ...
    shm.Unmap();    // done automatically when shm is destroyed
    shm.Close();    // done automatically when shm is destroyed

Child:
    ... get `name` from the command line...
    SharedMemory shm;
    shm.Open(name);
    shm.Map();
    char* p = shm.memory();
    ... read data from p ...
    shm.Delete();   // this is a no-op on Windows
    shm.Unmap();    // done automatically when shm is destroyed
    shm.Close();    // done automatically when shm is destroyed

This works fine on Unix. If the shared memory file is closed by the parent
before it's opened by the child, that's ok, because it persists until it is
explicitly deleted.

But it doesn't work on Windows. On Windows Delete() does nothing. Instead, a
file mapping object is auto-deleted when its refcount falls to zero. So if
the
parent calls Close() before the child calls Open() -- which happens in
practice -- then the file mapping object is auto-deleted and the child
Open()
fails.

If I change the parent to heap-allocate `shm` so it's not auto-destroyed at
the
end of the function, things work out, but we'll end up with leaks: the
SharedMemory object, opened file view, the handle, and the file mapping will
all leak.

I then tried using SharedMemory::ShareToProcess(), but that requires that
the
child process already exist and the parent has its PID, which is a pain.

I then found this blog post from Raymond Chen:
https://blogs.msdn.microsoft.com/oldnewthing/20031211-00/?p=41543

It describes exactly what I want, but it requires using the bInheritHandle
parameter, which base::SharedMemory doesn't do. I could change it to do so,
but
then it looks like I'd need to deal with I then found
LaunchOptions::handles_to_inherit as well... and at this point I figure it's
worth asking for help!

Does anybody have suggestions about the best way to do this? Thanks.

Nick
_______________________________________________
dev-platform mailing list
dev-platform@lists.mozilla.org
https://lists.mozilla.org/listinfo/dev-platform

Reply via email to