This fixes the issue described in comment 7 by doing a few changes to how threads are created, and members on nsThreadManager are managed.
* The thread list is moved to be a member of `nsThreadManager`, which is
already a statically allocated singleton.
* The flag for whether new thread creation is allowed is moved from being an
atomic to being guarded by the same mutex as the thread list, meaning that
it could be checked and a new thread could be added to the list atomically.
* Threads which require shutdown are initialized atomically from the point of
view of the thread manager, meaning that the check in ShutdownNonMainThreads
is guaranteed to catch all successfully started nsThread instances.
Differential Revision: https://phabricator.services.mozilla.com/D188623
This fixes the issue described in comment 7 by doing a few changes to how threads are created, and members on nsThreadManager are managed.
* The thread list is moved to be a member of `nsThreadManager`, which is
already a statically allocated singleton.
* The flag for whether new thread creation is allowed is moved from being an
atomic to being guarded by the same mutex as the thread list, meaning that
it could be checked and a new thread could be added to the list atomically.
* Threads which require shutdown are initialized atomically from the point of
view of the thread manager, meaning that the check in ShutdownNonMainThreads
is guaranteed to catch all successfully started nsThread instances.
Differential Revision: https://phabricator.services.mozilla.com/D188623
The only consumer of this feature has been removed, so we don't need it
anymore. It acts very differently than other runnables run on the main thread,
so removing it will simplify things.
Differential Revision: https://phabricator.services.mozilla.com/D164841
The only consumer of this feature has been removed, so we don't need it
anymore. It acts very differently than other runnables run on the main thread,
so removing it will simplify things.
Differential Revision: https://phabricator.services.mozilla.com/D164841
There is a code path that can make us not dispatch the `nsThreadShutdownAckEvent` at the end of `nsThread::ThreadFunc`. The only known and legitimate way to arrive here should be via StopWaitingAndLeakThread. We want to ensure that if we take this code path someone else already marked the shutdown context as complete.
Differential Revision: https://phabricator.services.mozilla.com/D148761
This change introduces a new interface, nsIThreadShutdown, which is used
to handle the relevant state for communicating thread shutdown state
between the joining and terminating threads. This type is now returned
from `nsIThread::AsyncShutdown` and can be used to register callbacks
for when thread shutdown is complete, as well as cancel shutdown
entirely, leading to the underlying PRThread never being joined using
PR_JoinThread. This leaking limitation may be avoidable if support for
detaching PRThreads is added to NSPR, or nsThread switches to a more
feature-complete threading API.
This patch also uses the new interface to rework nsThreadPool's Shutdown
and ShutdownWithTimeout methods to avoid poking at nsThread internals
and instead use the publicly facing methods. This allows us to start
async shutdown for all threads and spin the event loop until they all
complete, or a timeout timer fires.
Differential Revision: https://phabricator.services.mozilla.com/D136045
Because DelayedRunnables are fire-and-forget, there is no way for a targeted
EventTarget to clean them up on shutdown. Thus if a timer fires after
EventTarget shutdown it will fail to dispatch the timer event, and avoid
releasing the timer callback because it's not on the targeted thread. This
causes a leak as there is a ref-cycle between nsTimerImpl::mCallback and
DelayedRunnable::mTimer.
This patch adds nsIDelayedRunnableObserver for a target to observe which
DelayedRunnables are relying on their timer to run them. This allows the target
to schedule a shutdown task to cancel those timers and release the runnables on
the target thread.
Supported DelayedRunnable targets with this patch are TaskQueues,
eventqueue-based nsThreads and XPCOMThreadWrappers that wrap a supported
nsThread.
An assertion makes sure at runtime that future new uses of DelayedRunnable
target nsIDelayedRunnableObserver-supported event targets.
Differential Revision: https://phabricator.services.mozilla.com/D109781
Because DelayedRunnables are fire-and-forget, there is no way for a targeted
EventTarget to clean them up on shutdown. Thus if a timer fires after
EventTarget shutdown it will fail to dispatch the timer event, and avoid
releasing the timer callback because it's not on the targeted thread. This
causes a leak as there is a ref-cycle between nsTimerImpl::mCallback and
DelayedRunnable::mTimer.
This patch adds nsIDelayedRunnableObserver for a target to observe which
DelayedRunnables are relying on their timer to run them. This allows the target
to schedule a shutdown task to cancel those timers and release the runnables on
the target thread.
Supported DelayedRunnable targets with this patch are TaskQueues,
eventqueue-based nsThreads and XPCOMThreadWrappers that wrap a supported
nsThread.
An assertion makes sure at runtime that future new uses of DelayedRunnable
target nsIDelayedRunnableObserver-supported event targets.
Differential Revision: https://phabricator.services.mozilla.com/D109781
We extract the dealing of direct tasks from the TailDispatcher object and move into to the existing nsThread and TaskQueue classes.
TaskQueue is made to work with do_QueryInterface.
We continue accessing the direct tasks dispatcher via the TailDispatcher for now, which itself will forward the dealing of such tasks to the underlying thread.
Differential Revision: https://phabricator.services.mozilla.com/D79093