Bug 1431755 - Part 1: Add a variant of NS_GetCurrentThread that does not auto-create an nsIThread. r?froydnj draft
authorByron Campen [:bwc] <docfaraday@gmail.com>
Fri, 19 Jan 2018 09:41:22 -0600
changeset 749003 728ce5811598a3b9bce5d9eb576d060184108007
parent 748899 fd995039d89708923b5673ecebc652967d40bd4e
child 749004 ad212f19b82a14cc8e426e09b62f09128792079d
child 749453 0b073e3e9af42c409a52ed69f1f79086248928de
child 750095 73850743ce997129d9a7e9930d57bd8466542954
child 750237 806376e676e46e8b34d44940968d82ef5af94933
push id97292
push userbcampen@mozilla.com
push dateTue, 30 Jan 2018 20:34:34 +0000
reviewersfroydnj
bugs1431755
milestone60.0a1
Bug 1431755 - Part 1: Add a variant of NS_GetCurrentThread that does not auto-create an nsIThread. r?froydnj MozReview-Commit-ID: 9naTxaANX4u
xpcom/threads/nsThreadManager.cpp
xpcom/threads/nsThreadManager.h
xpcom/threads/nsThreadUtils.cpp
xpcom/threads/nsThreadUtils.h
--- 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.
  */