Keeping track of the lifetime of mojo::Handle across process

53 views
Skip to first unread message

Patrice Blin

unread,
Apr 22, 2021, 4:46:36 PM4/22/21
to chromi...@chromium.org, chromi...@chromium.org
Hello,
 
I'm using mojo to wrap an opaque structure (some platform resource) into a mojo::ScopedHandle which I then later use to pass around mojom interfaces and processes.
In normal scenarios, this handle is held by an existing Chromium object (media::DecoderBuffer) and once I'm consuming this object I can then free my opaque structure inside the mojo::ScopedHandle.
But during error cases, when the object holding ownership of this handle is freed (it's a unique_ptr<>) the Handle is closed and I'm leaking the platform resource referenced as the opaque pointer inside the ScopedHandle.

I would like to know if it's possible for a process/interface (initial producer of the ScopedHandle) to know if at some point it's closed ?

Looking at the documentation it seems there is the mojo::HandleSignalTracker interface but it's only for MessagePipe and DataPipe.

What would be the best way to know when a mojo::ScopedHandle is closed by another process ?

So far the only solutions I found were (1) to send a PendingRemote<> alongside the Handle to free what's inside or (2) Also send a MessagePipe and use the signal API to watch for the "peer closed" event.
But none of those solutions are appealing.

PS: My problem is not with the memory of the opaque structure inside the handle but the platform resource it's referring to

Thanks,
---
Patrice Blin

Ken Rockot

unread,
Apr 26, 2021, 1:14:57 PM4/26/21
to Patrice Blin, chromium-mojo, Chromium-dev
On Thu, Apr 22, 2021 at 9:17 AM Patrice Blin <pb...@wyplay.com> wrote:
Hello,
 
I'm using mojo to wrap an opaque structure (some platform resource) into a mojo::ScopedHandle which I then later use to pass around mojom interfaces and processes.
In normal scenarios, this handle is held by an existing Chromium object (media::DecoderBuffer) and once I'm consuming this object I can then free my opaque structure inside the mojo::ScopedHandle.

It's not clear to me what you mean by this arrangement. How are you wrapping an opaque structure? You say a platform resource, so do you mean you're using mojo::WrapPlatformHandle? If so, the lifetime of the platform handle is owned by the MojoHandle, so when the MojoHandle is closed, the platform handle is closed. But I assume that can't be what you mean or you wouldn't have this problem.

But during error cases, when the object holding ownership of this handle is freed (it's a unique_ptr<>) the Handle is closed and I'm leaking the platform resource referenced as the opaque pointer inside the ScopedHandle.

I would like to know if it's possible for a process/interface (initial producer of the ScopedHandle) to know if at some point it's closed ?

No, not possible in the general case.
 

Looking at the documentation it seems there is the mojo::HandleSignalTracker interface but it's only for MessagePipe and DataPipe.

What would be the best way to know when a mojo::ScopedHandle is closed by another process ?

So far the only solutions I found were (1) to send a PendingRemote<> alongside the Handle to free what's inside or (2) Also send a MessagePipe and use the signal API to watch for the "peer closed" event.
But none of those solutions are appealing. 

If you want to use Mojo to track the lifetime of something in another process, this is in fact the nicest way to do it. We used to have a helper in //mojo/public for exactly this purpose -- it internally used a MessagePipe and a HandleSignalTracker and hid the details -- but it appears to be gone now.


PS: My problem is not with the memory of the opaque structure inside the handle but the platform resource it's referring to  

Thanks,
---
Patrice Blin

--
You received this message because you are subscribed to the Google Groups "chromium-mojo" group.
To unsubscribe from this group and stop receiving emails from it, send an email to chromium-moj...@chromium.org.
To view this discussion on the web visit https://groups.google.com/a/chromium.org/d/msgid/chromium-mojo/CA%2BrBgJiAEnyV-%3DFE4xcHpPQMhtsNAynyoPpWZEzYFJ%2BRurcCCg%40mail.gmail.com.

Patrice Blin

unread,
Apr 27, 2021, 6:32:48 AM4/27/21
to Ken Rockot, chromium-mojo, Chromium-dev
On Mon, 26 Apr 2021 at 19:13, Ken Rockot <roc...@google.com> wrote:


On Thu, Apr 22, 2021 at 9:17 AM Patrice Blin <pb...@wyplay.com> wrote:
Hello,
 
I'm using mojo to wrap an opaque structure (some platform resource) into a mojo::ScopedHandle which I then later use to pass around mojom interfaces and processes.
In normal scenarios, this handle is held by an existing Chromium object (media::DecoderBuffer) and once I'm consuming this object I can then free my opaque structure inside the mojo::ScopedHandle.

It's not clear to me what you mean by this arrangement. How are you wrapping an opaque structure? You say a platform resource, so do you mean you're using mojo::WrapPlatformHandle? If so, the lifetime of the platform handle is owned by the MojoHandle, so when the MojoHandle is closed, the platform handle is closed. But I assume that can't be what you mean or you wouldn't have this problem.

As you guessed I'm not using mojo::WrapPlatformHandle. I'm literally wrapping a structure.

I'm using the C api MojoCreateSharedBuffer() and MojoMapBuffer() to create a MojoHandle then create a mojo::Handle with it.

 

But during error cases, when the object holding ownership of this handle is freed (it's a unique_ptr<>) the Handle is closed and I'm leaking the platform resource referenced as the opaque pointer inside the ScopedHandle.

I would like to know if it's possible for a process/interface (initial producer of the ScopedHandle) to know if at some point it's closed ?

No, not possible in the general case.
 

Looking at the documentation it seems there is the mojo::HandleSignalTracker interface but it's only for MessagePipe and DataPipe.

What would be the best way to know when a mojo::ScopedHandle is closed by another process ?

So far the only solutions I found were (1) to send a PendingRemote<> alongside the Handle to free what's inside or (2) Also send a MessagePipe and use the signal API to watch for the "peer closed" event.
But none of those solutions are appealing. 

If you want to use Mojo to track the lifetime of something in another process, this is in fact the nicest way to do it. We used to have a helper in //mojo/public for exactly this purpose -- it internally used a MessagePipe and a HandleSignalTracker and hid the details -- but it appears to be gone now.


Maybe you are thinking of mojo::SimpleWatcher ?

 
I will try my hand with MessagePipe then, thanks for the feedback.

Ken Rockot

unread,
Apr 27, 2021, 10:36:02 AM4/27/21
to Patrice Blin, chromium-mojo, Chromium-dev
On Tue, Apr 27, 2021 at 3:31 AM Patrice Blin <pb...@wyplay.com> wrote:
On Mon, 26 Apr 2021 at 19:13, Ken Rockot <roc...@google.com> wrote:


On Thu, Apr 22, 2021 at 9:17 AM Patrice Blin <pb...@wyplay.com> wrote:
Hello,
 
I'm using mojo to wrap an opaque structure (some platform resource) into a mojo::ScopedHandle which I then later use to pass around mojom interfaces and processes.
In normal scenarios, this handle is held by an existing Chromium object (media::DecoderBuffer) and once I'm consuming this object I can then free my opaque structure inside the mojo::ScopedHandle.

It's not clear to me what you mean by this arrangement. How are you wrapping an opaque structure? You say a platform resource, so do you mean you're using mojo::WrapPlatformHandle? If so, the lifetime of the platform handle is owned by the MojoHandle, so when the MojoHandle is closed, the platform handle is closed. But I assume that can't be what you mean or you wouldn't have this problem.

As you guessed I'm not using mojo::WrapPlatformHandle. I'm literally wrapping a structure.

I'm using the C api MojoCreateSharedBuffer() and MojoMapBuffer() to create a MojoHandle then create a mojo::Handle with it.

Oh, shared memory. Just to confirm, no there's no signaling mechanism attached to shared memory objects.


 

But during error cases, when the object holding ownership of this handle is freed (it's a unique_ptr<>) the Handle is closed and I'm leaking the platform resource referenced as the opaque pointer inside the ScopedHandle.

I would like to know if it's possible for a process/interface (initial producer of the ScopedHandle) to know if at some point it's closed ?

No, not possible in the general case.
 

Looking at the documentation it seems there is the mojo::HandleSignalTracker interface but it's only for MessagePipe and DataPipe.

What would be the best way to know when a mojo::ScopedHandle is closed by another process ?

So far the only solutions I found were (1) to send a PendingRemote<> alongside the Handle to free what's inside or (2) Also send a MessagePipe and use the signal API to watch for the "peer closed" event.
But none of those solutions are appealing. 

If you want to use Mojo to track the lifetime of something in another process, this is in fact the nicest way to do it. We used to have a helper in //mojo/public for exactly this purpose -- it internally used a MessagePipe and a HandleSignalTracker and hid the details -- but it appears to be gone now.


Maybe you are thinking of mojo::SimpleWatcher ?

No, it was a class designed specifically for the use case you describe, i.e. tracking the lifetime of a remote object without directly exposing any details about message pipes or how they're observed.


 
I will try my hand with MessagePipe then, thanks for the feedback.

--
You received this message because you are subscribed to the Google Groups "chromium-mojo" group.
To unsubscribe from this group and stop receiving emails from it, send an email to chromium-moj...@chromium.org.

Ken Rockot

unread,
May 30, 2023, 11:42:11 AM5/30/23
to Gabriel FORTE, chromium-mojo, Chromium-dev


On Tue, May 30, 2023 at 12:09 AM Gabriel FORTE <gfo...@wyplay.com> wrote:
Hi,

I'll answer my own question there... switching to mojo::SimpleWatcher instead of mojo::HandleSignalTracker seems to do the trick (anyway it doesn't seem like necessary to have HandleSignalTracker's more complex high/low watcher mechanism since I only need to watch a single peer disconnected event that only occurs one for each instance)
 
I'm just curious about why mojo::HandleSignalTracker is not supported with ipcz if you care to explain that ;)

HandleSignalTracker had no actual value in production Chrome (after bindings' lazy serialization was removed) and it would have required additional effort to support on ipcz.

As you have already discovered, it was overkill for your use case.


Cheers,

On Friday, May 26, 2023 at 4:25:02 PM UTC+2 Gabriel FORTE wrote:
Hello Ken,

I'm resurrecting this thread, since I'm now in charge of the code Patrice wrote after getting your advice (he's now a former colleague)

The mojo::HandleSignalTracker solution did the job satisfyingly for two years now, but between M111 and M112 MojoIpcz has been enabled by default for our configuration, and I stumbled across mentions that it's not supported in this case (cf. https://chromium.googlesource.com/chromium/src/+/a142771d6f2c0838c2c61a67bb0b47d2faaf4732%5E%21/#F24)

We currently have a workaround based on --disable-features=MojoIpcz, so it's not particularly urgent, but I expect at some point in the future MojoIpcz will become the only available backend so we need to find out a long-term way to implement this.

Is there a proper way to implement this using MojoIpcz, or should I resort to Patrice's #1 option (ie. "to send a PendingRemote<> alongside the Handle to free what's inside") ?

Thanks,

Gabriel FORTE

unread,
Jun 1, 2023, 10:57:22 AM6/1/23
to chromium-mojo, Gabriel FORTE, Ken Rockot, chromium-mojo, Chromium-dev
Hi,

I'll answer my own question there... switching to mojo::SimpleWatcher instead of mojo::HandleSignalTracker seems to do the trick (anyway it doesn't seem like necessary to have HandleSignalTracker's more complex high/low watcher mechanism since I only need to watch a single peer disconnected event that only occurs one for each instance)

I'm just curious about why mojo::HandleSignalTracker is not supported with ipcz if you care to explain that ;)

Cheers,

On Friday, May 26, 2023 at 4:25:02 PM UTC+2 Gabriel FORTE wrote:
Hello Ken,

I'm resurrecting this thread, since I'm now in charge of the code Patrice wrote after getting your advice (he's now a former colleague)

The mojo::HandleSignalTracker solution did the job satisfyingly for two years now, but between M111 and M112 MojoIpcz has been enabled by default for our configuration, and I stumbled across mentions that it's not supported in this case (cf. https://chromium.googlesource.com/chromium/src/+/a142771d6f2c0838c2c61a67bb0b47d2faaf4732%5E%21/#F24)

We currently have a workaround based on --disable-features=MojoIpcz, so it's not particularly urgent, but I expect at some point in the future MojoIpcz will become the only available backend so we need to find out a long-term way to implement this.

Is there a proper way to implement this using MojoIpcz, or should I resort to Patrice's #1 option (ie. "to send a PendingRemote<> alongside the Handle to free what's inside") ?

Thanks,


On Tuesday, April 27, 2021 at 4:34:37 PM UTC+2 Ken Rockot wrote:
Reply all
Reply to author
Forward
0 new messages