This patch simplifies and cleans up the RemoteWorker state machine by:
- (In a previous patch in the stack) making PRemoteWorker refcounted instead of
ManualAlloc allows us to eliminate use of ThreadSafeWeakPtr and some legwork
that was attempting to ensure we only drop references to RemoteWorkerChild on
the "Worker Launcher" thread.
- Although we are not allowed to call IPC methods on a different thread, we
can absolutely add and remove refcounts on other threads as needed.
- This allowed removal of the `SelfHolder` class as well as a number of calls
to NS_ProxyRelease.
- This allowed removal of the `{get,m}RemoteWorkerControllerWeakRef` hack.
- Adding 2 optional lambda callbacks to the WorkerPrivate constructor that will
be notified on the parent thread in order to simplify tracking the state of
the worker:
- CancellationCallback: Invoked when the parent thread tells the worker to
cancel itself. This can be the automatic result of a script load error,
a call to `self.close()`, or an explicit call to Cancel() by the parent.
- Note that cancellation was always being initiated by the parent thread,
even in the case of `self.close()`!
- TerminationCallback: Invoked when the worker thread has finished and the
WorkerPrivate's self-ref is about to be dropped. This indicates that the
worker transitioned to Killing and fully completed that process.
- Changing the RemoteWorkerChild to always perform state transitions on the
owning parent thread (although the state may be checked from other threads,
more in the code comments).
- The CancellationCallback mechanism replaces a complicated use of
WorkerRefs. This allowed removal of ReleaseWorkerRunnable.
- In general this reduces the number of permutations of thread interactions
we have to worry about.
- Changing the RemoteWorkerChild to only report that the worker has finished
shutting down as a result of the TerminationCallback rather than when the
worker has transitioned to Cancelling.
- Changing the states to better represent the worker's state in terms of
WorkerStatus terminology.
Some related cleanups:
- Use of mechanisms provided by IPC:
- RemoteWorkerChild had an mOwningEventTarget with a GetOwningEventTarget
getter that we were able to replace with the IPC-maintained
GetActorEventTarget().
- We replaced the `mIPCActive` with use of IPC's CanSend().
- MOZ_LOG logging was added under "RemoteWorkerChild".
Differential Revision: https://phabricator.services.mozilla.com/D164644
Response Timing should be reported before the body stream completing.
In the original implementation, the response timing is recorded when OnResponseEnd is called, but it is too late. Response timing could not be ready when response.text() or response.blob() resolves the promise.
This is the fourth patch for reporting the preload response timing for ServiceWorker NavigationPreload.
This patch adds the needed IPCs PFetchEventOp and PFetchEventOpProxy to propagate the preload response timing from the parent process main thread to the content process worker thread.
Since navigation preload is an asynchronous action, corresponding promises for asynchronous propagation are also created in FetchService, FetchEventOpChild, FetchEventOpProxyChild, and FetchEventOp.
Depends on D167938
Differential Revision: https://phabricator.services.mozilla.com/D167939
Response Timing should be reported before the body stream completing.
In the original implementation, the response timing is recorded when OnResponseEnd is called, but it is too late. Response timing could not be ready when response.text() or response.blob() resolves the promise.
This is the first patch to remove response timing from ResponseEndArgs, and also remove the timing recording from OnResponseEnd for PFetch and ServiceWorker NavigationPreload.
Differential Revision: https://phabricator.services.mozilla.com/D167936
Response Timing should be reported before the body stream completing.
In the original implementation, the response timing is recorded when OnResponseEnd is called, but it is too late. Response timing could not be ready when response.text() or response.blob() resolves the promise.
This is the fourth patch for reporting the preload response timing for ServiceWorker NavigationPreload.
This patch adds the needed IPCs PFetchEventOp and PFetchEventOpProxy to propagate the preload response timing from the parent process main thread to the content process worker thread.
Since navigation preload is an asynchronous action, corresponding promises for asynchronous propagation are also created in FetchService, FetchEventOpChild, FetchEventOpProxyChild, and FetchEventOp.
Depends on D167938
Differential Revision: https://phabricator.services.mozilla.com/D167939
Response Timing should be reported before the body stream completing.
In the original implementation, the response timing is recorded when OnResponseEnd is called, but it is too late. Response timing could not be ready when response.text() or response.blob() resolves the promise.
This is the first patch to remove response timing from ResponseEndArgs, and also remove the timing recording from OnResponseEnd for PFetch and ServiceWorker NavigationPreload.
Differential Revision: https://phabricator.services.mozilla.com/D167936
This is largely a straightforward find and replace of various methods, with the
unnecessary arguments removed and compiler errors fixed.
Differential Revision: https://phabricator.services.mozilla.com/D148532
In the previous implementation, FetchEvent.preloadResponse is resolved when the response fetching finishes.
However, ServiceWorker responding letency could be increased since waiting for preloadResponse finishes.
The patch resolves FetchEvent.preloadResponse earlier when the response is available.
The basic idea is to resolve the preload response when FetchInstance::OnResponseAvailableInternal() is called.
Then propagating the response from the parent process main thread to the content process worker thread. This is achieved by IPC PFetchEventOp::Send/RecvPreloadResponse -> PFetchEventOpProxy::Send/RecvPreloadResponse.
Since we can only get the response's ResourceTiming when FetchInstance::OnResponseEnd() is called. This patch introduces a new IPC method to propagate the ResourceTiming information from the parent process main thread to the content process worker thread.
PFetchEventOp::Send/RecvPreloadResponseEnd -> PFetchEventOpProxy->Send/RecvPreloadResponseEnd.
The tricky of this patch is we must extend the life cycle of FetchEventOp object if preloadResponse is set into FetchEvent.
That because ServiceWorker could resolve FetchEvent.respondWith() by using FetchEvent.preloadResponse.
In that case, FetchEventOp will get into a finish state and try to call FetchEventOpProxyChild::Senddelete with the operation result.
However, the ResponseEnd could not be called at the moment, and we need to wait for the corresponding timing information and its end reason.
To extend the life cycle of FetchEventOp, this patch cached the operation result while we get FetchEventOp::Callback is called. Then call FetchEventOpProxyChile::Senddelete() in FetchEventOpProxyChild::RecvPreloadResponseEnd() to close IPC. Or Senddelete() will be called while ActorDestroy() caused by shutdown.
Differential Revision: https://phabricator.services.mozilla.com/D145338
#include "mozilla/dom/WorkerScope.h" is removed from WorkerPrivate.h, where calling WorkerPrivate::GlobalScope() without include "WorkerScope.h" makes WorkerScope as an incomplete type.
Depends on 132800
Depends on D132800
Differential Revision: https://phabricator.services.mozilla.com/D133483
This patch includes a set of changes to the ServiceWorker internals to introduce a new
nsIServiceWorkerManager.wakeForExtensionAPIEvent method, to be used by the WebExtensions internals
to request an active background service worker to be spawned (if it is not yet) in response to
a WebExtension API event.
The new method gets as parameters:
- the scope URL for the extension background service worker to spawn
- WebExtensions API namespace and API event name which we are going to spawn an active worker for
and return a promise which would be:
- rejected if the worker could not be spawned
- resolved to a boolean if the worker was spawned successfully (or already running)
The value of the boolean value resolved is meant to represent if the worker did actually
have any listener subscribed for the given WebExtensions API event listener
(which the WebExtensions internals may then use to decide if it is worth to send that event
to be handled by the worker script or not).
In this patch the ExtensionBrowser::HasWakeupEventListener used to determine if an WebExtensions
API event was subscribed syncronously when the worker was being loaded is not implemented yet
and it is always returning false (a proposed implementation for that method is going to be
added in a separate patch part of this same bugzilla issue).
A unit test for the new proposed nsIServiceWorkerManager method is also part of a separate patch
(attached to this bugzilla issue as the child revision for this one).
Differential Revision: https://phabricator.services.mozilla.com/D130756
#include "mozilla/dom/WorkerScope.h" is removed from WorkerPrivate.h, where calling WorkerPrivate::GlobalScope() without include "WorkerScope.h" makes WorkerScope as an incomplete type.
Depends on 132800
Depends on D132800
Differential Revision: https://phabricator.services.mozilla.com/D133483
This commit replaces IPCInternalResponse with three different structs:
ParentToParentInternalResponse, ParentToChildInternalResponse, and
ChildToParentInternalResponse. Doing this lets us convert runtime
checks into compile-time type checks and simplifies relevant code.
Differential Revision: https://phabricator.services.mozilla.com/D131275
This patch implements the IPC for propagating the preload response from the parent process' main thread to the content process' worker thread.
The following is the complicated propagation path.
FetchEventOpChild(Parent process main thread) =>
FetchEventOpParent(Parent process background thread) =>
FetchEventOpProxyParent(Parent process background thread) =>
FetchEventOpProxyChild(content process worker launch thread) =>
ServiceWorker(content process worker thread)
However, since preload response fetching is an asynchronous behavior, the preload response can be ready at any time point during the fetch event dispatching. This patch also handles different situations. Basically, it can be separated into the following stages.
1. Preload response is ready when the fetch event dispatching is in the parent process main thread, which means the fetch event is pending as a ServiceWorkerPrivateImpl::PendingFetchEvent. Details in PendingFetchEvent and FetchEventOpChild
2. Preload response is ready when the fetch event dispatching is in the parent process background thread, which means fetch event is still waiting for worker launching. Details in FetchEventOpParent and FetchEventOpProxyParent.
3. Preload response is ready when constructing the fetch event. Details in FetchEventOpProxyChild and ServiceWorkerOp::FetchEventOp.
Depends on D126244
Differential Revision: https://phabricator.services.mozilla.com/D122821
This patch tries to record the fetch event dispatching time, the response's synthesizing time, and interception resetting time.
Fetch event dispatching time is the time duration between interception starts, which is the time point of InterceptedHttpChannel::AsyncOpenInternal(), and the fetch handler starts. It includes the InterceptedHttpChannel setup time, ServiceWorker launch time, FetchEventOp propagation through IPC, a FetchEvent creation, initialization, and dispatching/scheduling on worker scope.
Response synthesizing time is the time duration between the fetch handler finishes, which is the resolving/rejecting promise of respondWith(), to the finish of pumping the synthesized response to InterceptedHttpChannel, which is the time point of calling InterceptedHttpChannel::OnStopRequest(). It includes the response propagation through IPC, response header and body synthesis, and pumping synthesized response to the channel.
Interception resetting time is the time duration between the fetch handler finishes and redirecting InterceptedHttpChannel to a normal HTTP channel.
Since the fetch handler is executed on the process where the service worker spawned, the timestamps related to the fetch handler need to be get on that process. So this patch adds the FetchHandlerStart and FetchHandlerFinish on IPCFetchEventRespondWithResult related types to propagate the timestamps to the parent process.
Depends on D118398
Differential Revision: https://phabricator.services.mozilla.com/D118399
This patch was generated by running:
```
perl -p -i \
-e 's/^(\s+)([a-zA-Z0-9.]+) = NS_ConvertUTF8toUTF16\((.*)\);/\1CopyUTF8toUTF16(\3, \2);/;' \
-e 's/^(\s+)([a-zA-Z0-9.]+) = NS_ConvertUTF16toUTF8\((.*)\);/\1CopyUTF16toUTF8(\3, \2);/;' \
$FILE
```
against every .cpp and .h in mozilla-central, and then fixing up the
inevitable errors that happen as a result of matching C++ expressions with
regexes. The errors fell into three categories:
1. Calling the convert functions with `std::string::c_str()`; these were
changed to simply pass the string instead, relying on implicit conversion
to `mozilla::Span`.
2. Calling the convert functions with raw pointers, which is not permitted
with the copy functions; these were changed to invoke `MakeStringSpan` first.
3. Other miscellaneous errors resulting from over-eager regexes and/or the
replacement not being type-aware. These changes were reverted.
Differential Revision: https://phabricator.services.mozilla.com/D88903
Before P1, GetCurrentThreadSerialEventTarget would have always returned the same data as NS_GetCurrentThread, making the comment incorrect Now it will properly return the running TaskQueue if any.
This change of name more clearly exposes what they are doing, as we aren't always dealing with threads directly; but a nsISerialEventTarget
Differential Revision: https://phabricator.services.mozilla.com/D80354