summaryrefslogtreecommitdiff
path: root/netwerk
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
commit6fe78cec8acdcb2f134fcac4204965606ca44903 (patch)
treee5b84eb43bde465fe981fa279bdb417c6efce3c9 /netwerk
parent8cc2f6ba9bbec26dd24db04992b904ad3d424757 (diff)
downloaduxp-6fe78cec8acdcb2f134fcac4204965606ca44903.tar.gz
[network] Make CacheIOThread::ThreadFunc hold reference to thread.
Diffstat (limited to 'netwerk')
-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();
}