summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorValentin Gosu <valentin.gosu@gmail.com>2021-07-14 13:27:14 +0000
committerMoonchild <moonchild@palemoon.org>2021-07-14 13:27:14 +0000
commit90fcfaebf6771f5a18e84437ded336a36598d88d (patch)
treee5b84eb43bde465fe981fa279bdb417c6efce3c9
parent36caf5a0fbc64c7b60e906689daaa279b69070b4 (diff)
downloaduxp-90fcfaebf6771f5a18e84437ded336a36598d88d.tar.gz
[network] Make CacheIOThread::ThreadFunc hold reference to thread.
-rw-r--r--netwerk/cache2/CacheIOThread.cpp14
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();
}