Open Bug 1570616 Opened 6 years ago Updated 1 year ago

[meta] Move away from sync CoCreateInstance to RoGetAgileReference or similar (to avoid mainthread IO)

Categories

(Core :: Widget: Win32, task, P3)

Unspecified
Windows
task

Tracking

()

Performance Impact medium

People

(Reporter: florian, Unassigned)

References

(Blocks 1 open bug)

Details

(4 keywords)

See this startup profile: https://perfht.ml/2Zk22hX

The slowness seems to be due to opening the C:\WINDOWS\Registration\R00000000000d.clb and C:\WINDOWS\Registration\R000000000001.clb files several times on the main thread.

I wonder if we could:

  • do something to make this happen faster.
  • do something to delay these calls much further (ie. at least after first paint), and prevent new calls from being introduced during startup.
  • move some of this off main thread or off of the main process.

(In reply to Florian Quèze [:florian] from comment #0)

  • move some of this off main thread or off of the main process.

Potentially possible, but here be dragons:

  1. The background thread must be initialized in a COM apartment.

  2. Any COM interfaces instantiated by CoCreateInstance live in the "apartment" (concurrency boundary) that the CoCreateInstance call originated in. In other words, if you create an interface off the main thread, you cannot directly use it on the main thread without marshaling the interface. In Gecko, the best way to hand off interfaces between threads is to use mscom::AgileReference.

  3. A few COM components (particularly older ones) are very finicky about how they are used; some of them require being instantiated in a single-threaded apartment, which in Gecko terms essentially implies that they absolutely must be created on the main thread. You'll learn about this pretty quickly if that is the case, though: CoCreateInstance will fail with any such components.

Given points 1 and 2, I have filed a dependent bug 1570701 to add an asynchronous CreateInstance method to mscom::EnsureMTA that would handle those things for you.

At any rate, as the MSCOM module owner I should be included as a reviewer on any other changes relating to this bug.

Whiteboard: [fxperf] → [fxperf:p2][fxperfsize:L]
Performance Impact: --- → P2
Whiteboard: [fxperf:p2][fxperfsize:L] → [fxperfsize:L]
Severity: normal → S3
Priority: -- → P3

(In reply to (No longer employed by Mozilla) Aaron Klotz from comment #1)

Given points 1 and 2, I have filed a dependent bug 1570701 to add an asynchronous CreateInstance method to mscom::EnsureMTA that would handle those things for you.

This was replaced in bug 1869053.

At this point ISTM that any consumers could be updated for this - fixing all of them is probably too large a task for a single bug. We can't actually change the mechanics of the sync version of CreateInstance, so I'm going to morph this into a metabug.

The profile in comment 0 relates to the parental control service. The relevant API for which we were using CreateInstance was replaced with sync registry reads. I filed bug 1893948 to avoid the mainthread registry reads.

Keywords: main-thread-io
OS: Unspecified → Windows
Summary: Calls to CoCreateInstance are slow → [meta] Move away from sync CoCreateInstance to RoGetAgileReference or similar (to avoid mainthread IO)
Whiteboard: [fxperfsize:L]

(In reply to (No longer employed by Mozilla) Aaron Klotz from comment #1)

  1. A few COM components (particularly older ones) are very finicky about how they are used; some of them require being instantiated in a single-threaded apartment, which in Gecko terms essentially implies that they absolutely must be created on the main thread.

Note that this has changed, somewhat. Per previous discussion with :handyman (the current MSCOM module owner), if you need an STA-only COM object, especially a short-lived one, it may not be a bad idea to create your own private thread with its own single-threaded apartment rather than loading more work onto the main thread. The object can then have work explicitly submitted to its thread via an appropriate asynchronous interface (probably read: MozPromise-returning functions on the owner). Consult an MSCOM peer if you suspect this might be the right approach.

In theory you could also pass the COM object across threads by means of AgileReference; but I have to differ from :aklotz here and advise never doing that, regardless of what apartment owns the object or what thread invokes it. Every cross-apartment invocation of an AgileReference's member functions will block while work is implicitly submitted to the owning apartment, and processed on a thread therewithin, in order to fake a synchronous interface.

As :Gijs notes, this is no longer relevant to the parental control service, but it may still matter to any new dependents of this meta-bug.

You need to log in before you can comment on or make changes to this bug.