Bug 1431755 - Part 1: Add a variant of NS_GetCurrentThread that does not auto-create an nsIThread. r?froydnj
MozReview-Commit-ID: 9naTxaANX4u
--- a/xpcom/threads/nsThreadManager.cpp
+++ b/xpcom/threads/nsThreadManager.cpp
@@ -420,16 +420,22 @@ nsThreadManager::GetCurrentThread()
RefPtr<nsThread> thread = new nsThread(WrapNotNull(queue), nsThread::NOT_MAIN_THREAD, 0);
if (!thread || NS_FAILED(thread->InitCurrentThread())) {
return nullptr;
}
return thread.get(); // reference held in TLS
}
+bool
+nsThreadManager::IsNSThread() const
+{
+ return mInitialized && !!PR_GetThreadPrivate(mCurThreadIndex);
+}
+
NS_IMETHODIMP
nsThreadManager::NewThread(uint32_t aCreationFlags,
uint32_t aStackSize,
nsIThread** aResult)
{
return NewNamedThread(NS_LITERAL_CSTRING(""), aStackSize, aResult);
}
--- a/xpcom/threads/nsThreadManager.h
+++ b/xpcom/threads/nsThreadManager.h
@@ -34,19 +34,23 @@ public:
// must be called when the given thread is the current thread.
void RegisterCurrentThread(nsThread& aThread);
// Called by nsThread to inform the ThreadManager it is going away. This
// method must be called when the given thread is the current thread.
void UnregisterCurrentThread(nsThread& aThread);
// Returns the current thread. Returns null if OOM or if ThreadManager isn't
- // initialized.
+ // initialized. Creates the nsThread if one does not exist yet.
nsThread* GetCurrentThread();
+ // Returns true iff the currently running thread has an nsThread associated
+ // with it (ie; whether this is a thread that we can dispatch runnables to).
+ bool IsNSThread() const;
+
// CreateCurrentThread sets up an nsThread for the current thread. It uses the
// event queue and main thread flags passed in. It should only be called once
// for the current thread. After it returns, GetCurrentThread() will return
// the thread that was created. GetCurrentThread() will also create a thread
// (lazily), but it doesn't allow the queue or main-thread attributes to be
// specified.
nsThread* CreateCurrentThread(mozilla::SynchronizedEventQueue* aQueue,
nsThread::MainThreadFlag aMainThread);
--- a/xpcom/threads/nsThreadUtils.cpp
+++ b/xpcom/threads/nsThreadUtils.cpp
@@ -525,16 +525,26 @@ NS_SetCurrentThreadName(const char* aNam
}
#ifdef MOZILLA_INTERNAL_API
nsIThread*
NS_GetCurrentThread()
{
return nsThreadManager::get().GetCurrentThread();
}
+
+
+nsIThread*
+NS_GetCurrentThreadNoCreate()
+{
+ if (nsThreadManager::get().IsNSThread()) {
+ return NS_GetCurrentThread();
+ }
+ return nullptr;
+}
#endif
// nsThreadPoolNaming
nsCString
nsThreadPoolNaming::GetNextThreadName(const nsACString& aPoolName)
{
nsCString name(aPoolName);
name.AppendLiteral(" #");
--- a/xpcom/threads/nsThreadUtils.h
+++ b/xpcom/threads/nsThreadUtils.h
@@ -69,17 +69,17 @@ NS_NewNamedThread(const char (&aName)[LE
{
static_assert(LEN <= 16,
"Thread name must be no more than 16 characters");
return NS_NewNamedThread(nsDependentCString(aName, LEN - 1),
aResult, aInitialEvent, aStackSize);
}
/**
- * Get a reference to the current thread.
+ * Get a reference to the current thread, creating it if it does not exist yet.
*
* @param aResult
* The resulting nsIThread object.
*/
extern nsresult NS_GetCurrentThread(nsIThread** aResult);
/**
* Dispatch the given event to the current thread.
@@ -363,22 +363,29 @@ do_GetMainThread()
nsIThread* thread = nullptr;
NS_GetMainThread(&thread);
return already_AddRefed<nsIThread>(thread);
}
//-----------------------------------------------------------------------------
#ifdef MOZILLA_INTERNAL_API
-// Fast access to the current thread. Do not release the returned pointer! If
-// you want to use this pointer from some other thread, then you will need to
-// AddRef it. Otherwise, you should only consider this pointer valid from code
-// running on the current thread.
+// Fast access to the current thread. Will create an nsIThread if one does not
+// exist already! Do not release the returned pointer! If you want to use this
+// pointer from some other thread, then you will need to AddRef it. Otherwise,
+// you should only consider this pointer valid from code running on the current
+// thread.
extern nsIThread* NS_GetCurrentThread();
+// Exactly the same as NS_GetCurrentThread, except it will not create an
+// nsThread if one does not exist yet. This is useful in cases where you have
+// code that runs on threads that may or may not not be driven by an nsThread
+// event loop, and wish to avoid inadvertently creating a superfluous nsThread.
+extern nsIThread* NS_GetCurrentThreadNoCreate();
+
/**
* Set the name of the current thread. Prefer this function over
* PR_SetCurrentThreadName() if possible. The name will also be included in the
* crash report.
*
* @param aName
* Name of the thread. A C language null-terminated string.
*/