diff options
author | Valentin Gosu <valentin.gosu@gmail.com> | 2021-07-14 13:27:14 +0000 |
---|---|---|
committer | Moonchild <moonchild@palemoon.org> | 2021-07-14 13:27:14 +0000 |
commit | 90fcfaebf6771f5a18e84437ded336a36598d88d (patch) | |
tree | e5b84eb43bde465fe981fa279bdb417c6efce3c9 | |
parent | 36caf5a0fbc64c7b60e906689daaa279b69070b4 (diff) | |
download | uxp-90fcfaebf6771f5a18e84437ded336a36598d88d.tar.gz |
[network] Make CacheIOThread::ThreadFunc hold reference to thread.
-rw-r--r-- | netwerk/cache2/CacheIOThread.cpp | 14 |
1 files changed, 13 insertions, 1 deletions
diff --git a/netwerk/cache2/CacheIOThread.cpp b/netwerk/cache2/CacheIOThread.cpp index c686c0f8d0..fe0a4ddb05 100644 --- a/netwerk/cache2/CacheIOThread.cpp +++ b/netwerk/cache2/CacheIOThread.cpp @@ -215,12 +215,22 @@ nsresult CacheIOThread::Init() mBlockingIOWatcher = MakeUnique<detail::BlockingIOWatcher>(); } + // Increase the reference count while spawning a new thread. + // If PR_CreateThread succeeds, we will forget this reference and the thread + // will be responsible to release it when it completes. + RefPtr<CacheIOThread> self = this; + mThread = PR_CreateThread(PR_USER_THREAD, ThreadFunc, this, PR_PRIORITY_NORMAL, PR_GLOBAL_THREAD, PR_JOINABLE_THREAD, 128 * 1024); if (!mThread) { return NS_ERROR_FAILURE; } + + // IMPORTANT: The thread now owns this reference, so it's important that we + // leak it here, otherwise we'll end up with a bad refcount. + // See the dont_AddRef in ThreadFunc(). + Unused << self.forget().take(); return NS_OK; } @@ -382,7 +392,9 @@ void CacheIOThread::ThreadFunc(void* aClosure) { PR_SetCurrentThreadName("Cache2 I/O"); mozilla::IOInterposer::RegisterCurrentThread(); - CacheIOThread* thread = static_cast<CacheIOThread*>(aClosure); + // We hold on to this reference for the duration of the thread. + RefPtr<CacheIOThread> thread = + dont_AddRef(static_cast<CacheIOThread*>(aClosure)); thread->ThreadFunc(); mozilla::IOInterposer::UnregisterCurrentThread(); } |