From edc4e3927e7f21c9fb7d145d084fddf42fe61efd Mon Sep 17 00:00:00 2001 From: Randell Jesup Date: Wed, 16 Apr 2014 16:39:16 -0400 Subject: [PATCH] Bug 997286: Make NS_NewNamedThread safe if the event tries to commit suicide r=bsmedberg --- content/media/AudioStream.cpp | 3 ++- xpcom/glue/nsThreadUtils.h | 10 +++++++--- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/content/media/AudioStream.cpp b/content/media/AudioStream.cpp index 8cc60c8862c2..541ebc5005fd 100644 --- a/content/media/AudioStream.cpp +++ b/content/media/AudioStream.cpp @@ -412,7 +412,8 @@ AudioStream::Init(int32_t aNumChannels, int32_t aRate, // When this is done, it will start callbacks from Cubeb. Those will // cause us to move from INITIALIZED to RUNNING. Until then, we // can't access any cubeb functions. - AudioInitTask *init = new AudioInitTask(this, aLatencyRequest, params); + // Use a RefPtr to avoid leaks if Dispatch fails + RefPtr init = new AudioInitTask(this, aLatencyRequest, params); init->Dispatch(); return NS_OK; } diff --git a/xpcom/glue/nsThreadUtils.h b/xpcom/glue/nsThreadUtils.h index c567de3a4666..bff00d471077 100644 --- a/xpcom/glue/nsThreadUtils.h +++ b/xpcom/glue/nsThreadUtils.h @@ -70,15 +70,19 @@ NS_NewNamedThread(const char (&name)[LEN], nsIRunnable *initialEvent = nullptr, uint32_t stackSize = nsIThreadManager::DEFAULT_STACK_SIZE) { - nsresult rv = NS_NewThread(result, nullptr, stackSize); + // Hold a ref while dispatching the initial event to match NS_NewThread() + nsCOMPtr thread; + nsresult rv = NS_NewThread(getter_AddRefs(thread), nullptr, stackSize); if (NS_WARN_IF(NS_FAILED(rv))) return rv; - NS_SetThreadName(*result, name); + NS_SetThreadName(thread, name); if (initialEvent) { - rv = (*result)->Dispatch(initialEvent, NS_DISPATCH_NORMAL); + rv = thread->Dispatch(initialEvent, NS_DISPATCH_NORMAL); NS_WARN_IF_FALSE(NS_SUCCEEDED(rv), "Initial event dispatch failed"); } + *result = nullptr; + thread.swap(*result); return rv; }