VOOZH about

URL: https://phabricator.services.mozilla.com/D296457

⇱ ⚙ D296457 Bug 1641989: Add FOGTransport parent/child to replace PContentChild in FOG IPC r?chutten


Bug 1641989: Add FOGTransport parent/child to replace PContentChild in FOG IPC r?chutten
Needs ReviewPublic

Authored by chumphreys on Apr 24 2026, 9:15 PM.
Tags
None
Referenced Files
Unknown Object (File)
Tue, Jun 16, 10:13 PM
Unknown Object (File)
Tue, Jun 16, 10:13 PM
Unknown Object (File)
Tue, Jun 16, 10:13 PM
Unknown Object (File)
Tue, Jun 16, 10:13 PM
Unknown Object (File)
Tue, Jun 16, 10:13 PM
Unknown Object (File)
Tue, Jun 16, 10:13 PM
Unknown Object (File)
Tue, Jun 16, 10:13 PM
Unknown Object (File)
Tue, Jun 16, 10:13 PM

Details

Reviewers
chutten
nika
Bugzilla Bug ID
1641989

Diff Detail

Repository
rFIREFOXAUTOLAND firefox-autoland
Branch
HEAD

Unit TestsBroken

TimeTest
0 mscode-review::general
WARNING: A generic error occurred in the code review bot.

Event Timeline

There are a very large number of changes, so older changes are hidden. Show Older Changes
dom/ipc/ContentParent.cpp
1245–1248

In a normal Firefox Desktop run there'll be multiple content children and each one will need their own pair of child,parent endpoints. This'll mean that we'll have multiple different parent endpoints arriving here, all of which we'll need to bind.

This ought to be testable via xpcshell with multiple simultaneous content tasks, but I'm not sure I've ever tried.

1250

bikeshed: mFOGTaskQueue

1260
toolkit/components/glean/docs/dev/ipc.md
166

Please link to the Preferences and Defines doc, and include in it a section on the new pref

toolkit/components/glean/ipc/FOGIPC.cpp
474

Weird that it's asking you to qualify these. They ought to just be from the statement up on line 49

toolkit/components/glean/ipc/FOGTransportChild.h
16

I think modern C++ prefers over like

This revision now requires changes to proceed.Tue, May 26, 2:46 PM
chumphreys updated this revision to Diff 1283531.
chumphreys marked 5 inline comments as done.
Comment Actions
NOTE: 2 documentation files were modified in diff 1283531

They can be previewed for one week:


If you see a problem in this automated review, please report it here.

chutten added a reviewer: nika.
chutten added a subscriber: nika.
Comment Actions

This is starting to look good, so I think it's time to bring in @nika to weigh in on whether we successfully understood her instructions.

Some notes:

  • This is for content children only so far, and only handles the receipt on the parent on a bg task queue (send is still main thread). If it's easy to support bg sending as well as bg receiving, we'd love to hear it (though it might be a follow-up given how the Rust calls out to C++ at the moment, and because a small, landable improvement is worth landing).
  • We're not 100% sure how to test this. Manual testing using with confirms that it runs, but it only runs a single content child. If there are examples of multi-child tests we can learn from: fantastic.
toolkit/components/glean/ipc/FOGTransportChild.h
29

Prefer to

toolkit/components/glean/ipc/FOGTransportParent.h
17–19

Prefer to

chumphreys added inline comments.
toolkit/components/glean/ipc/FOGIPC.cpp
474

Seems like re-defining that statement to be has fixed the issue

nika requested changes to this revision.Mon, Jun 1, 11:49 PM
nika added inline comments.
dom/ipc/ContentParent.cpp
1250–1256

I don't think you need to hold onto this task queue, as this will be the only time it is ever used - as it's created for this particular use. I also don't think it is possible for it to fail to create a queue when a is still able to receive IPC, so you can probably get away with .

FYI the current design creates a separate task queue for every content process. I'm not sure if that's what the intention was or not?

1252

Out of curiosity, why the vowels-removed task queue name?

toolkit/components/glean/ipc/FOGIPC.cpp
52

Where did this change come from?

451

Looks like you ran into the " is ambiguous" issue I mention below :-)

601–620

Do you aspire to also support for these other process types? I think it should be feasible to also send the endpoints over these actors as well, and uniformly use for FOG data between all child processes and the parent process (though non-content processes naturally don't have a type).

toolkit/components/glean/ipc/FOGTransportChild.cpp
27

I notice you're still sending the FOG data on the content process main thread. I take it this patch isn't intending to change that?

toolkit/components/glean/ipc/FOGTransportParent.h
23–26

I'd generally not bother with doing unless you really need to avoid a refcount.

30

AFAICT this is currently completely unused, is that correct? DO you have aspirations to do more validation based on this or something like that?

toolkit/components/glean/ipc/PFOGTransport.ipdl
8–10

In general I prefer not to add extra namespaces like when possible. We have one for , and it causes headaches every once in a while, as if you're in a translation unit which has done a , or are within the namespace, names like are now ambiguous and require full qualification. This sometimes causes build issues in unified builds.

I think I'd probably recommend just putting it into ?

13

nothing on this protocol needs to be sync.

20

isn't necessary for toplevel actors.

23–25

We like to add comments to closing namespace indicators, so that it's more clear what's going on, as often they can be quite far away from the initial declaration.

This revision now requires changes to proceed.Mon, Jun 1, 11:49 PM
Comment Actions

The ones I've marked done I'm in the process of addressing - working through build issues locally.

Thank you so much for your review, I've got some responses and questions if you don't mind.

dom/ipc/ContentParent.cpp
1250–1256

The intention was for it to create a single task queue on first use that would be used across all processes, so that's certainly something I need to adjust. I'd meant for the created task queue to have be a reference to it.

Is there something in what I wrote that didn't do that as I expected it to? That's what I understood to be doing.

1252

I think that's from when I had accidentally left it as a BackgroundThread, which had a character limit on the name. I was following previous patterns, which primarily seemed to remove the vowels.

toolkit/components/glean/ipc/FOGIPC.cpp
52

Harbormaster and my local IDE were both complaining that usages of ByteBuf later in the file were not resolving correctly, and this seemed to resolve that issue

451

Yep that's also why I ended up adding the above

601–620

My understanding is for now we are focused on content processes, but we may choose to expand it in the future.

toolkit/components/glean/ipc/FOGTransportChild.cpp
27

This would be the child process' main thread, right?

toolkit/components/glean/ipc/FOGTransportParent.h
30

I think it would be wise of us to do so, but at this time I admittedly don't have the experience in this space to know how to do that.

chumphreys marked 3 inline comments as done and an inline comment as not done.Tue, Jun 2, 4:47 PM
chumphreys added inline comments.
toolkit/components/glean/ipc/FOGTransportParent.h
23–26

I'm running into issues implementing this change due to the following errors:

0:13.37 E /Users/charlie.humphreys/git/firefox/toolkit/components/glean/FOGTransportParent.h:24:9: error: call to implicitly-deleted copy constructor of 'ThreadsafeContentParentHandle' (aka 'mozilla::dom::ThreadsafeContentParentHandle')
0:13.37 E 24 | : mThreadsafeContentParentHandle(*aThreadsafeContentParentHandle) {}
0:13.37 E | ^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
0:13.37 E /Users/charlie.humphreys/git/firefox/dom/ipc/ContentParent.h:1679:3: note: copy constructor of 'ThreadsafeContentParentHandle' is implicitly deleted because field 'mRefCnt' has a deleted copy constructor
0:13.37 E 1679 | NS_INLINE_DECL_THREADSAFE_REFCOUNTING(ThreadsafeContentParentHandle);
0:13.37 E | ^
0:13.37 E /Users/charlie.humphreys/git/firefox/xpcom/base/nsISupportsImpl.h:771:3: note: expanded from macro 'NS_INLINE_DECL_THREADSAFE_REFCOUNTING'
0:13.37 E 771 | NS_INLINE_DECL_THREADSAFE_REFCOUNTING_WITH_DESTROY(_class, delete (this), \
0:13.37 E | ^
0:13.37 E /Users/charlie.humphreys/git/firefox/xpcom/base/nsISupportsImpl.h:749:3: note: expanded from macro 'NS_INLINE_DECL_THREADSAFE_REFCOUNTING_WITH_DESTROY'
0:13.37 E 749 | NS_INLINE_DECL_THREADSAFE_REFCOUNTING_META(_class, NS_METHOD_, _destroy, \
0:13.37 E | ^
0:13.37 E /Users/charlie.humphreys/git/firefox/xpcom/base/nsISupportsImpl.h:732:35: note: expanded from macro 'NS_INLINE_DECL_THREADSAFE_REFCOUNTING_META'
0:13.37 E 732 | ::mozilla::ThreadSafeAutoRefCnt mRefCnt; \
0:13.38 E | ^
0:13.38 E /Users/charlie.humphreys/git/firefox/xpcom/base/nsISupportsImpl.h:372:3: note: 'ThreadSafeAutoRefCnt' has been explicitly marked deleted here
0:13.38 E 372 | ThreadSafeAutoRefCnt(const ThreadSafeAutoRefCnt&) = delete;
0:13.38 E | ^
0:13.38 W In file included from /Users/charlie.humphreys/git/firefox/obj-aarch64-apple-darwin25.4.0/dom/ipc/Unified_cpp_dom_ipc0.cpp:119:
0:13.38 W In file included from /Users/charlie.humphreys/git/firefox/dom/ipc/ContentParent.cpp:142:
0:13.38 E /Users/charlie.humphreys/git/firefox/toolkit/components/glean/FOGTransportParent.h:28:33: error: field of type 'ThreadsafeContentParentHandle' (aka 'mozilla::dom::ThreadsafeContentParentHandle') has private destructor
0:13.38 E 28 | ThreadsafeContentParentHandle mThreadsafeContentParentHandle;
0:13.38 E | ^
0:13.38 E /Users/charlie.humphreys/git/firefox/dom/ipc/ContentParent.h:1710:3: note: declared private here
0:13.38 E 1710 | ~ThreadsafeContentParentHandle() { MOZ_ASSERT(!mWeakActor); }
0:13.38 E | ^
0:14.72 E 2 errors generated.
chumphreys updated this revision to Diff 1289677.
toolkit/components/glean/ipc/FOGTransportParent.h
23–26

Figured it out!

nika requested changes to this revision.Tue, Jun 2, 9:58 PM
nika added inline comments.
dom/ipc/ContentParent.cpp
1250–1256

is a per-process actor, so if you're storing the task queue on as a member, then it will still be per-content-process.

If you want to have a task queue which is global, you need to make it a static, rather than having it on the object. The easiest way is perhaps to add a (e.g. https://searchfox.org/firefox-main/rev/7c07e6f277dd6d5122183d6feecb7473277ab5bb/xpcom/tests/gtest/TestStaticBackgroundTaskQueue.cpp#14-17), which is a helper to declare background task queues which are process global.

This could look something like this:

// in the header
class FOGTransportParent : ... {
 ...
 static already_AddRefed<nsISerialEventTarget> GetQueue();
 ...
};
// in the .cpp
already_AddRefed<nsISerialEventTarget> FOGTransportParent::GetQueue() {
 static StaticBackgroundTaskQueue sQueue("FOGTransportTaskQueue");
 return sQueue.Get();
}
// when using it:
nsCOMPtr<nsISerialEventTarget> queue = FOGTransportParent::GetQueue();
...
queue->Dispatch(...);
toolkit/components/glean/ipc/FOGIPC.cpp
451

Now that you've dropped the namespace, you can probably also drop the other changes in this file removing prefixes. They're not necessary due to the statement, but it's nice to keep the diff smaller if possible.

toolkit/components/glean/ipc/FOGTransportChild.h
17

FWIW I think that IPDL will already generate a typedef for this on PFOGTransportChild.

29

FWIW I think that IPDL will already generate a typedef for this on PFOGTransportChild.

toolkit/components/glean/ipc/FOGTransportParent.h
17

This is probably already defined with a typedef from .

30

This should still be a strong reference. My feedback about using a raw pointer was just for the signature of the constructor.

30

If you're not using it for now, you can probably drop the entirely unless you think you'll want to use it in the near future.

Does Glean actually preserve any information about which process sent the telemetry? My vague understanding is that there is no "process identity" as far as glean is concerned, so the buffers sent here are just blindly replayed onto the global state from the parent process. Is that right?

toolkit/components/glean/ipc/PFOGTransport.ipdl
22

You're missing a newline at end of file.

This revision now requires changes to proceed.Tue, Jun 2, 9:58 PM
chumphreys updated this revision to Diff 1293916.
chumphreys marked 8 inline comments as done.
chumphreys added inline comments.
toolkit/components/glean/ipc/FOGTransportParent.h
30

I believe that's correct. In which case I agree, I think we can completely drop that handle.

Comment Actions
NOTE: 2 documentation files were modified in diff 1293916

They can be previewed for one week:


If you see a problem in this automated review, please report it here.

nika requested changes to this revision.Wed, Jun 10, 8:50 PM
nika added inline comments.
dom/ipc/ContentParent.cpp
1254–1255

If you're not using the threadsafe handle, there's no reason to capture it.

1256–1258

Let's not have a 0 refcount object sitting around in a local - best practice these days is to use like this.

toolkit/components/glean/ipc/FOGTransportParent.h
15–18

this is dead code now

This revision now requires changes to proceed.Wed, Jun 10, 8:50 PM
chumphreys updated this revision to Diff 1297907.
chumphreys marked 3 inline comments as done.
nika requested changes to this revision.Mon, Jun 15, 4:53 PM
nika added inline comments.
toolkit/components/glean/ipc/FOGIPC.cpp
474

Looks like you still have an extra change here removing

478–480

Thing which I just noticed, sorry I didn't catch this in an earlier pass:

This patch currently doesn't change the logic such that we're sending the message over the actor. In fact, it will be sent over the normal actor like before.

I think this could have surprising consequences if the FOG transport is turned on, as it means that the flush may not actually have flushed all data (due to different threads being involved). Effectively, now that you're using a second actor, there's nothing guaranteeing that all FOG data messages sent over have arrived & been processed before the response from arrives.

This is complicated even more more by timing. Currently the actor isn't created at all until the first message is ready to be sent by the child, which means that even if we send over the actors, the parent process may have actors which don't have a corresponding actor to send the message over.


Looking at the way that is used, it appears it's used in only the following two ways:

  1. During testing, to ensure that data is available in the parent before checking what data is stored (https://searchfox.org/firefox-main/rev/4524afcc186654ad357e48fec686249515860ac8/toolkit/components/glean/xpcom/FOG.cpp#392-424), and
  2. During "idle" events (https://searchfox.org/firefox-main/rev/4524afcc186654ad357e48fec686249515860ac8/toolkit/components/glean/xpcom/FOG.cpp#431-438)

Neither of these appear to be super worried about the edge cases of trying to flush FOG data for a content process which is _extremely_ early during startup, so I would propose the following solution:

  1. We don't want to wait until the content process is ready to send up to create the actor, instead we probably want to create it early during content process startup, and pass that actor down to the FOGIPC code, so we replace with this:
// FOGTransportChild.h

/**
 * Get the singleton FOGTransportChild instance for the current process.
 * Returns null if the FOG transport actor either hasn't been created yet, or is disabled.
 */
static FOGTransportChild* GetSingleton();

/**
 * Create the FOGTransportActor for the current process, binding it
 * to the parent process over the given endpoint.
 */
static void Create(Endpoint<PFOGTransportChild> aEndpoint);
  1. Now the actor needs to be created manually early during content process startup.

    For this, we add some code to early during content process startup, but after IPC has been established. Arbitrarily, I think we could get away with doing the following, but feel free to tweak to something which feels better:
  1. In the content process, when flushing the FOG transport, check if there is a by checking (you could even do this before checking process type if you wanted), and send the message over the transport singleton if it's available.
  1. In , replace the direct call with a wrapper which does something like this:
RefPtr<FlushFOGDataPromise> ContentParent::DoFlushFOGData() {
 if (mFOGTransport) {
 nsCOMPtr<nsISerialEventTarget> queue = glean::FOGTransportParent::GetQueue();
 return InvokeAsync(queue, __func__, [transport = RefPtr{mFOGTransport}] {
 return transport->SendFlushFOGData();
 });
 }
 return SendFlushFOGData();
}
toolkit/components/glean/ipc/FOGTransportChild.cpp
27

Yeah, the "content process" is our name for the child process which renders web content.

This revision now requires changes to proceed.Mon, Jun 15, 4:53 PM
chumphreys updated this revision to Diff 1301476.
chumphreys marked an inline comment as done.
chumphreys added inline comments.
toolkit/components/glean/ipc/FOGIPC.cpp
474

Whoopsie, thank you

478–480

I ended up pairing with @chutten on this and we _think_ we've fully covered what you shared in this comment. Great callout, thank you for the in-depth description of what needed to be done.

If you don't mind double checking our work I think that would be very greatly appreciated.

toolkit/components/glean/ipc/FOGTransportChild.cpp
27

Yep we aren't changing that at the moment, as best I'm aware

Revision Contents

PathSize
dom/
ipc/
3 lines
12 lines
7 lines
47 lines
3 lines
modules/
libpref/
init/
5 lines
toolkit/
components/
glean/
docs/
dev/
5 lines
6 lines
ipc/
26 lines
46 lines
34 lines
24 lines
21 lines
21 lines
8 lines
nimbus/
6 lines
CommitTreeParentsAuthorSummaryDate
bd0e5f6c8ddcd1a65227e9ad960d5e224813Charlie Humphreys
Bug 1641989: Add FOGTransport parent/child to replace PContentChild in FOG IPC… (Show More…)
Apr 24 2026, 9:14 PM

Diff 1301476

dom/ipc/ContentChild.h

Loading...

dom/ipc/ContentChild.cpp

Loading...

dom/ipc/ContentParent.h

Loading...

dom/ipc/ContentParent.cpp

Loading...

dom/ipc/PContent.ipdl

Loading...

modules/libpref/init/StaticPrefList.yaml

Loading...

toolkit/components/glean/docs/dev/ipc.md

Loading...

toolkit/components/glean/docs/dev/preferences.md

Loading...

toolkit/components/glean/ipc/FOGIPC.cpp

Loading...

toolkit/components/glean/ipc/FOGTransportChild.h

Loading...

toolkit/components/glean/ipc/FOGTransportChild.cpp

Loading...

toolkit/components/glean/ipc/FOGTransportParent.h

Loading...

toolkit/components/glean/ipc/FOGTransportParent.cpp

Loading...

toolkit/components/glean/ipc/PFOGTransport.ipdl

Loading...

toolkit/components/glean/moz.build

Loading...

toolkit/components/nimbus/FeatureManifest.yaml

Loading...