LCOV - code coverage report
Current view: top level - xpcom/threads - nsThreadUtils.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 164 215 76.3 %
Date: 2017-07-14 16:53:18 Functions: 47 55 85.5 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
       2             : /* vim: set ts=8 sts=2 et sw=2 tw=80: */
       3             : /* This Source Code Form is subject to the terms of the Mozilla Public
       4             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       5             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
       6             : 
       7             : #include "nsThreadUtils.h"
       8             : #include "mozilla/Attributes.h"
       9             : #include "mozilla/Likely.h"
      10             : #include "mozilla/TimeStamp.h"
      11             : #include "LeakRefPtr.h"
      12             : 
      13             : #ifdef MOZILLA_INTERNAL_API
      14             : # include "nsThreadManager.h"
      15             : #else
      16             : # include "nsXPCOMCIDInternal.h"
      17             : # include "nsIThreadManager.h"
      18             : # include "nsServiceManagerUtils.h"
      19             : #endif
      20             : 
      21             : #ifdef XP_WIN
      22             : #include <windows.h>
      23             : #elif defined(XP_MACOSX)
      24             : #include <sys/resource.h>
      25             : #endif
      26             : 
      27             : #ifdef MOZ_CRASHREPORTER
      28             : #include "nsExceptionHandler.h"
      29             : #endif
      30             : 
      31             : using namespace mozilla;
      32             : 
      33             : #ifndef XPCOM_GLUE_AVOID_NSPR
      34             : 
      35         289 : NS_IMPL_ISUPPORTS(IdlePeriod, nsIIdlePeriod)
      36             : 
      37             : NS_IMETHODIMP
      38         144 : IdlePeriod::GetIdlePeriodHint(TimeStamp* aIdleDeadline)
      39             : {
      40         144 :   *aIdleDeadline = TimeStamp();
      41         144 :   return NS_OK;
      42             : }
      43             : 
      44       63668 : NS_IMPL_ISUPPORTS(Runnable, nsIRunnable, nsINamed)
      45             : 
      46             : NS_IMETHODIMP
      47           0 : Runnable::Run()
      48             : {
      49             :   // Do nothing
      50           0 :   return NS_OK;
      51             : }
      52             : 
      53             : NS_IMETHODIMP
      54        1106 : Runnable::GetName(nsACString& aName)
      55             : {
      56             : #ifdef RELEASE_OR_BETA
      57             :   aName.Truncate();
      58             : #else
      59        1106 :   if (mName) {
      60        1106 :     aName.AssignASCII(mName);
      61             :   } else {
      62           0 :     aName.Truncate();
      63             :   }
      64             : #endif
      65        1106 :   return NS_OK;
      66             : }
      67             : 
      68             : nsresult
      69        1947 : Runnable::SetName(const char* aName)
      70             : {
      71             : #ifndef RELEASE_OR_BETA
      72        1947 :   mName = aName;
      73             : #endif
      74        1947 :   return NS_OK;
      75             : }
      76             : 
      77       33380 : NS_IMPL_ISUPPORTS_INHERITED(CancelableRunnable, Runnable,
      78             :                             nsICancelableRunnable)
      79             : 
      80             : nsresult
      81           0 : CancelableRunnable::Cancel()
      82             : {
      83             :   // Do nothing
      84           0 :   return NS_OK;
      85             : }
      86             : 
      87         178 : NS_IMPL_ISUPPORTS_INHERITED(IdleRunnable, CancelableRunnable,
      88             :                             nsIIdleRunnable)
      89             : 
      90             : namespace mozilla {
      91             : namespace detail {
      92           0 : already_AddRefed<nsITimer> CreateTimer()
      93             : {
      94           0 :   nsCOMPtr<nsITimer> timer = do_CreateInstance(NS_TIMER_CONTRACTID);
      95           0 :   return timer.forget();
      96             : }
      97             : } // namespace detail
      98             : } // namespace mozilla
      99             : 
     100             : #endif  // XPCOM_GLUE_AVOID_NSPR
     101             : 
     102             : //-----------------------------------------------------------------------------
     103             : 
     104             : nsresult
     105          55 : NS_NewNamedThread(const nsACString& aName,
     106             :                   nsIThread** aResult,
     107             :                   nsIRunnable* aEvent,
     108             :                   uint32_t aStackSize)
     109             : {
     110         110 :   nsCOMPtr<nsIThread> thread;
     111             : #ifdef MOZILLA_INTERNAL_API
     112             :   nsresult rv =
     113          55 :     nsThreadManager::get().nsThreadManager::NewNamedThread(aName, aStackSize,
     114         110 :                                                            getter_AddRefs(thread));
     115             : #else
     116             :   nsresult rv;
     117             :   nsCOMPtr<nsIThreadManager> mgr =
     118             :     do_GetService(NS_THREADMANAGER_CONTRACTID, &rv);
     119             :   if (NS_WARN_IF(NS_FAILED(rv))) {
     120             :     return rv;
     121             :   }
     122             : 
     123             :   rv = mgr->NewNamedThread(aName, aStackSize, getter_AddRefs(thread));
     124             : #endif
     125          55 :   if (NS_WARN_IF(NS_FAILED(rv))) {
     126           0 :     return rv;
     127             :   }
     128             : 
     129          55 :   if (aEvent) {
     130          26 :     rv = thread->Dispatch(aEvent, NS_DISPATCH_NORMAL);
     131          26 :     if (NS_WARN_IF(NS_FAILED(rv))) {
     132           0 :       return rv;
     133             :     }
     134             :   }
     135             : 
     136          55 :   *aResult = nullptr;
     137          55 :   thread.swap(*aResult);
     138          55 :   return NS_OK;
     139             : }
     140             : 
     141             : nsresult
     142           0 : NS_NewThread(nsIThread** aResult, nsIRunnable* aEvent, uint32_t aStackSize)
     143             : {
     144           0 :   return NS_NewNamedThread(NS_LITERAL_CSTRING(""), aResult, aEvent, aStackSize);
     145             : }
     146             : 
     147             : nsresult
     148         719 : NS_GetCurrentThread(nsIThread** aResult)
     149             : {
     150             : #ifdef MOZILLA_INTERNAL_API
     151         719 :   return nsThreadManager::get().nsThreadManager::GetCurrentThread(aResult);
     152             : #else
     153             :   nsresult rv;
     154             :   nsCOMPtr<nsIThreadManager> mgr =
     155             :     do_GetService(NS_THREADMANAGER_CONTRACTID, &rv);
     156             :   if (NS_WARN_IF(NS_FAILED(rv))) {
     157             :     return rv;
     158             :   }
     159             :   return mgr->GetCurrentThread(aResult);
     160             : #endif
     161             : }
     162             : 
     163             : nsresult
     164         798 : NS_GetMainThread(nsIThread** aResult)
     165             : {
     166             : #ifdef MOZILLA_INTERNAL_API
     167         798 :   return nsThreadManager::get().nsThreadManager::GetMainThread(aResult);
     168             : #else
     169             :   nsresult rv;
     170             :   nsCOMPtr<nsIThreadManager> mgr =
     171             :     do_GetService(NS_THREADMANAGER_CONTRACTID, &rv);
     172             :   if (NS_WARN_IF(NS_FAILED(rv))) {
     173             :     return rv;
     174             :   }
     175             :   return mgr->GetMainThread(aResult);
     176             : #endif
     177             : }
     178             : 
     179             : nsresult
     180         286 : NS_DispatchToCurrentThread(already_AddRefed<nsIRunnable>&& aEvent)
     181             : {
     182             :   nsresult rv;
     183         572 :   nsCOMPtr<nsIRunnable> event(aEvent);
     184             : #ifdef MOZILLA_INTERNAL_API
     185         286 :   nsIEventTarget* thread = GetCurrentThreadEventTarget();
     186         286 :   if (!thread) {
     187           0 :     return NS_ERROR_UNEXPECTED;
     188             :   }
     189             : #else
     190             :   nsCOMPtr<nsIThread> thread;
     191             :   rv = NS_GetCurrentThread(getter_AddRefs(thread));
     192             :   if (NS_WARN_IF(NS_FAILED(rv))) {
     193             :     return rv;
     194             :   }
     195             : #endif
     196             :   // To keep us from leaking the runnable if dispatch method fails,
     197             :   // we grab the reference on failures and release it.
     198         286 :   nsIRunnable* temp = event.get();
     199         286 :   rv = thread->Dispatch(event.forget(), NS_DISPATCH_NORMAL);
     200         286 :   if (NS_WARN_IF(NS_FAILED(rv))) {
     201             :     // Dispatch() leaked the reference to the event, but due to caller's
     202             :     // assumptions, we shouldn't leak here. And given we are on the same
     203             :     // thread as the dispatch target, it's mostly safe to do it here.
     204           0 :     NS_RELEASE(temp);
     205             :   }
     206         286 :   return rv;
     207             : }
     208             : 
     209             : // It is common to call NS_DispatchToCurrentThread with a newly
     210             : // allocated runnable with a refcount of zero. To keep us from leaking
     211             : // the runnable if the dispatch method fails, we take a death grip.
     212             : nsresult
     213          19 : NS_DispatchToCurrentThread(nsIRunnable* aEvent)
     214             : {
     215          38 :   nsCOMPtr<nsIRunnable> event(aEvent);
     216          38 :   return NS_DispatchToCurrentThread(event.forget());
     217             : }
     218             : 
     219             : nsresult
     220         425 : NS_DispatchToMainThread(already_AddRefed<nsIRunnable>&& aEvent, uint32_t aDispatchFlags)
     221             : {
     222         425 :   LeakRefPtr<nsIRunnable> event(Move(aEvent));
     223         850 :   nsCOMPtr<nsIThread> thread;
     224         425 :   nsresult rv = NS_GetMainThread(getter_AddRefs(thread));
     225         425 :   if (NS_WARN_IF(NS_FAILED(rv))) {
     226           0 :     NS_ASSERTION(false, "Failed NS_DispatchToMainThread() in shutdown; leaking");
     227             :     // NOTE: if you stop leaking here, adjust Promise::MaybeReportRejected(),
     228             :     // which assumes a leak here, or split into leaks and no-leaks versions
     229           0 :     return rv;
     230             :   }
     231         425 :   return thread->Dispatch(event.take(), aDispatchFlags);
     232             : }
     233             : 
     234             : // In the case of failure with a newly allocated runnable with a
     235             : // refcount of zero, we intentionally leak the runnable, because it is
     236             : // likely that the runnable is being dispatched to the main thread
     237             : // because it owns main thread only objects, so it is not safe to
     238             : // release them here.
     239             : nsresult
     240         130 : NS_DispatchToMainThread(nsIRunnable* aEvent, uint32_t aDispatchFlags)
     241             : {
     242         260 :   nsCOMPtr<nsIRunnable> event(aEvent);
     243         260 :   return NS_DispatchToMainThread(event.forget(), aDispatchFlags);
     244             : }
     245             : 
     246             : nsresult
     247           2 : NS_DelayedDispatchToCurrentThread(already_AddRefed<nsIRunnable>&& aEvent, uint32_t aDelayMs)
     248             : {
     249           4 :   nsCOMPtr<nsIRunnable> event(aEvent);
     250             : #ifdef MOZILLA_INTERNAL_API
     251           2 :   nsIEventTarget* thread = GetCurrentThreadEventTarget();
     252           2 :   if (!thread) {
     253           0 :     return NS_ERROR_UNEXPECTED;
     254             :   }
     255             : #else
     256             :   nsresult rv;
     257             :   nsCOMPtr<nsIThread> thread;
     258             :   rv = NS_GetCurrentThread(getter_AddRefs(thread));
     259             :   if (NS_WARN_IF(NS_FAILED(rv))) {
     260             :     return rv;
     261             :   }
     262             : #endif
     263             : 
     264           2 :   return thread->DelayedDispatch(event.forget(), aDelayMs);
     265             : }
     266             : 
     267             : nsresult
     268          14 : NS_IdleDispatchToThread(already_AddRefed<nsIRunnable>&& aEvent,
     269             :                         nsIThread* aThread)
     270             : {
     271             :   nsresult rv;
     272          28 :   nsCOMPtr<nsIRunnable> event(aEvent);
     273          14 :   NS_ENSURE_TRUE(event, NS_ERROR_INVALID_ARG);
     274          14 :   if (!aThread) {
     275           0 :     return NS_ERROR_UNEXPECTED;
     276             :   }
     277             :   // To keep us from leaking the runnable if dispatch method fails,
     278             :   // we grab the reference on failures and release it.
     279          14 :   nsIRunnable* temp = event.get();
     280          14 :   rv = aThread->IdleDispatch(event.forget());
     281          14 :   if (NS_WARN_IF(NS_FAILED(rv))) {
     282             :     // Dispatch() leaked the reference to the event, but due to caller's
     283             :     // assumptions, we shouldn't leak here. And given we are on the same
     284             :     // thread as the dispatch target, it's mostly safe to do it here.
     285           0 :     NS_RELEASE(temp);
     286             :   }
     287             : 
     288          14 :   return rv;
     289             : }
     290             : 
     291             : nsresult
     292           4 : NS_IdleDispatchToCurrentThread(already_AddRefed<nsIRunnable>&& aEvent)
     293             : {
     294           4 :   return NS_IdleDispatchToThread(Move(aEvent),
     295           4 :                                  NS_GetCurrentThread());
     296             : }
     297             : 
     298             : class IdleRunnableWrapper : public IdleRunnable
     299             : {
     300             : public:
     301           6 :   explicit IdleRunnableWrapper(already_AddRefed<nsIRunnable>&& aEvent)
     302           6 :     : mRunnable(Move(aEvent))
     303             :   {
     304           6 :   }
     305             : 
     306           8 :   NS_IMETHOD Run() override
     307             :   {
     308           8 :     if (!mRunnable) {
     309           3 :       return NS_OK;
     310             :     }
     311           5 :     CancelTimer();
     312          10 :     nsCOMPtr<nsIRunnable> runnable = mRunnable.forget();
     313           5 :     return runnable->Run();
     314             :   }
     315             : 
     316             :   static void
     317           4 :   TimedOut(nsITimer* aTimer, void* aClosure)
     318             :   {
     319             :     RefPtr<IdleRunnableWrapper> runnable =
     320           8 :       static_cast<IdleRunnableWrapper*>(aClosure);
     321           4 :     runnable->Run();
     322           4 :   }
     323             : 
     324           6 :   void SetTimer(uint32_t aDelay, nsIEventTarget* aTarget) override
     325             :   {
     326           6 :     MOZ_ASSERT(aTarget);
     327           6 :     MOZ_ASSERT(!mTimer);
     328           6 :     mTimer = do_CreateInstance(NS_TIMER_CONTRACTID);
     329           6 :     if (mTimer) {
     330           6 :       mTimer->SetTarget(aTarget);
     331           6 :       mTimer->InitWithNamedFuncCallback(TimedOut,
     332             :                                         this,
     333             :                                         aDelay,
     334             :                                         nsITimer::TYPE_ONE_SHOT,
     335           6 :                                         "IdleRunnableWrapper::SetTimer");
     336             :     }
     337           6 :   }
     338             : 
     339           4 :   NS_IMETHOD GetName(nsACString& aName) override
     340             :   {
     341           4 :     aName.AssignLiteral("IdleRunnableWrapper");
     342           8 :     if (nsCOMPtr<nsINamed> named = do_QueryInterface(mRunnable)) {
     343           2 :       nsAutoCString name;
     344           1 :       named->GetName(name);
     345           1 :       if (!name.IsEmpty()) {
     346           1 :         aName.AppendLiteral(" for ");
     347           1 :         aName.Append(name);
     348             :       }
     349             :     }
     350           4 :     return NS_OK;
     351             :   }
     352             : 
     353             : private:
     354           8 :   ~IdleRunnableWrapper()
     355           8 :   {
     356           4 :     CancelTimer();
     357          12 :   }
     358             : 
     359           9 :   void CancelTimer()
     360             :   {
     361           9 :     if (mTimer) {
     362           9 :       mTimer->Cancel();
     363             :     }
     364           9 :   }
     365             : 
     366             :   nsCOMPtr<nsITimer> mTimer;
     367             :   nsCOMPtr<nsIRunnable> mRunnable;
     368             : };
     369             : 
     370             : extern nsresult
     371           9 : NS_IdleDispatchToThread(already_AddRefed<nsIRunnable>&& aEvent,
     372             :                         uint32_t aTimeout,
     373             :                         nsIThread* aThread)
     374             : {
     375          18 :   nsCOMPtr<nsIRunnable> event(Move(aEvent));
     376           9 :   NS_ENSURE_TRUE(event, NS_ERROR_INVALID_ARG);
     377             : 
     378             :   //XXX Using current thread for now as the nsIEventTarget.
     379           9 :   nsIEventTarget* target = mozilla::GetCurrentThreadEventTarget();
     380           9 :   if (!target) {
     381           0 :     return NS_ERROR_UNEXPECTED;
     382             :   }
     383             : 
     384          18 :   nsCOMPtr<nsIIdleRunnable> idleEvent = do_QueryInterface(event);
     385             : 
     386           9 :   if (!idleEvent) {
     387          12 :     idleEvent = new IdleRunnableWrapper(event.forget());
     388           6 :     event = do_QueryInterface(idleEvent);
     389           6 :     MOZ_DIAGNOSTIC_ASSERT(event);
     390             :   }
     391           9 :   idleEvent->SetTimer(aTimeout, target);
     392             : 
     393           9 :   return NS_IdleDispatchToThread(event.forget(), aThread);
     394             : }
     395             : 
     396             : extern nsresult
     397           9 : NS_IdleDispatchToCurrentThread(already_AddRefed<nsIRunnable>&& aEvent,
     398             :                                uint32_t aTimeout)
     399             : {
     400           9 :   return NS_IdleDispatchToThread(Move(aEvent), aTimeout,
     401           9 :                                  NS_GetCurrentThread());
     402             : }
     403             : 
     404             : #ifndef XPCOM_GLUE_AVOID_NSPR
     405             : nsresult
     406           0 : NS_ProcessPendingEvents(nsIThread* aThread, PRIntervalTime aTimeout)
     407             : {
     408           0 :   nsresult rv = NS_OK;
     409             : 
     410             : #ifdef MOZILLA_INTERNAL_API
     411           0 :   if (!aThread) {
     412           0 :     aThread = NS_GetCurrentThread();
     413           0 :     if (NS_WARN_IF(!aThread)) {
     414           0 :       return NS_ERROR_UNEXPECTED;
     415             :     }
     416             :   }
     417             : #else
     418             :   nsCOMPtr<nsIThread> current;
     419             :   if (!aThread) {
     420             :     rv = NS_GetCurrentThread(getter_AddRefs(current));
     421             :     if (NS_WARN_IF(NS_FAILED(rv))) {
     422             :       return rv;
     423             :     }
     424             :     aThread = current.get();
     425             :   }
     426             : #endif
     427             : 
     428           0 :   PRIntervalTime start = PR_IntervalNow();
     429             :   for (;;) {
     430             :     bool processedEvent;
     431           0 :     rv = aThread->ProcessNextEvent(false, &processedEvent);
     432           0 :     if (NS_FAILED(rv) || !processedEvent) {
     433           0 :       break;
     434             :     }
     435           0 :     if (PR_IntervalNow() - start > aTimeout) {
     436           0 :       break;
     437             :     }
     438           0 :   }
     439           0 :   return rv;
     440             : }
     441             : #endif // XPCOM_GLUE_AVOID_NSPR
     442             : 
     443             : inline bool
     444        1485 : hasPendingEvents(nsIThread* aThread)
     445             : {
     446             :   bool val;
     447        1485 :   return NS_SUCCEEDED(aThread->HasPendingEvents(&val)) && val;
     448             : }
     449             : 
     450             : bool
     451        1485 : NS_HasPendingEvents(nsIThread* aThread)
     452             : {
     453        1485 :   if (!aThread) {
     454             : #ifndef MOZILLA_INTERNAL_API
     455             :     nsCOMPtr<nsIThread> current;
     456             :     NS_GetCurrentThread(getter_AddRefs(current));
     457             :     return hasPendingEvents(current);
     458             : #else
     459           0 :     aThread = NS_GetCurrentThread();
     460           0 :     if (NS_WARN_IF(!aThread)) {
     461           0 :       return false;
     462             :     }
     463             : #endif
     464             :   }
     465        1485 :   return hasPendingEvents(aThread);
     466             : }
     467             : 
     468             : bool
     469        1742 : NS_ProcessNextEvent(nsIThread* aThread, bool aMayWait)
     470             : {
     471             : #ifdef MOZILLA_INTERNAL_API
     472        1742 :   if (!aThread) {
     473           0 :     aThread = NS_GetCurrentThread();
     474           0 :     if (NS_WARN_IF(!aThread)) {
     475           0 :       return false;
     476             :     }
     477             :   }
     478             : #else
     479             :   nsCOMPtr<nsIThread> current;
     480             :   if (!aThread) {
     481             :     NS_GetCurrentThread(getter_AddRefs(current));
     482             :     if (NS_WARN_IF(!current)) {
     483             :       return false;
     484             :     }
     485             :     aThread = current.get();
     486             :   }
     487             : #endif
     488             :   bool val;
     489        1742 :   return NS_SUCCEEDED(aThread->ProcessNextEvent(aMayWait, &val)) && val;
     490             : }
     491             : 
     492             : void
     493          76 : NS_SetCurrentThreadName(const char* aName)
     494             : {
     495          76 :   PR_SetCurrentThreadName(aName);
     496             : #ifdef MOZ_CRASHREPORTER
     497          76 :   CrashReporter::SetCurrentThreadName(aName);
     498             : #endif
     499          76 : }
     500             : 
     501             : #ifdef MOZILLA_INTERNAL_API
     502             : nsIThread*
     503         169 : NS_GetCurrentThread()
     504             : {
     505         169 :   return nsThreadManager::get().GetCurrentThread();
     506             : }
     507             : #endif
     508             : 
     509             : // nsThreadPoolNaming
     510             : nsCString
     511          26 : nsThreadPoolNaming::GetNextThreadName(const nsACString& aPoolName)
     512             : {
     513          26 :   nsCString name(aPoolName);
     514          26 :   name.AppendLiteral(" #");
     515          26 :   name.AppendInt(++mCounter, 10); // The counter is declared as atomic
     516          26 :   return name;
     517             : }
     518             : 
     519             : // nsAutoLowPriorityIO
     520           0 : nsAutoLowPriorityIO::nsAutoLowPriorityIO()
     521             : {
     522             : #if defined(XP_WIN)
     523             :   lowIOPrioritySet = SetThreadPriority(GetCurrentThread(),
     524             :                                        THREAD_MODE_BACKGROUND_BEGIN);
     525             : #elif defined(XP_MACOSX)
     526             :   oldPriority = getiopolicy_np(IOPOL_TYPE_DISK, IOPOL_SCOPE_THREAD);
     527             :   lowIOPrioritySet = oldPriority != -1 &&
     528             :                      setiopolicy_np(IOPOL_TYPE_DISK,
     529             :                                     IOPOL_SCOPE_THREAD,
     530             :                                     IOPOL_THROTTLE) != -1;
     531             : #else
     532           0 :   lowIOPrioritySet = false;
     533             : #endif
     534           0 : }
     535             : 
     536           0 : nsAutoLowPriorityIO::~nsAutoLowPriorityIO()
     537             : {
     538             : #if defined(XP_WIN)
     539             :   if (MOZ_LIKELY(lowIOPrioritySet)) {
     540             :     // On Windows the old thread priority is automatically restored
     541             :     SetThreadPriority(GetCurrentThread(), THREAD_MODE_BACKGROUND_END);
     542             :   }
     543             : #elif defined(XP_MACOSX)
     544             :   if (MOZ_LIKELY(lowIOPrioritySet)) {
     545             :     setiopolicy_np(IOPOL_TYPE_DISK, IOPOL_SCOPE_THREAD, oldPriority);
     546             :   }
     547             : #endif
     548           0 : }
     549             : 
     550             : namespace mozilla {
     551             : 
     552             : PRThread*
     553     1431015 : GetCurrentVirtualThread()
     554             : {
     555     1431015 :   return PR_GetCurrentThread();
     556             : }
     557             : 
     558             : PRThread*
     559           0 : GetCurrentPhysicalThread()
     560             : {
     561           0 :   return PR_GetCurrentThread();
     562             : }
     563             : 
     564             : nsIEventTarget*
     565         684 : GetCurrentThreadEventTarget()
     566             : {
     567        1368 :   nsCOMPtr<nsIThread> thread;
     568         684 :   nsresult rv = NS_GetCurrentThread(getter_AddRefs(thread));
     569         684 :   if (NS_FAILED(rv)) {
     570           0 :     return nullptr;
     571             :   }
     572             : 
     573         684 :   return thread->EventTarget();
     574             : }
     575             : 
     576             : nsIEventTarget*
     577          18 : GetMainThreadEventTarget()
     578             : {
     579          36 :   nsCOMPtr<nsIThread> thread;
     580          18 :   nsresult rv = NS_GetMainThread(getter_AddRefs(thread));
     581          18 :   if (NS_FAILED(rv)) {
     582           0 :     return nullptr;
     583             :   }
     584             : 
     585          18 :   return thread->EventTarget();
     586             : }
     587             : 
     588             : nsISerialEventTarget*
     589          12 : GetCurrentThreadSerialEventTarget()
     590             : {
     591          24 :   nsCOMPtr<nsIThread> thread;
     592          12 :   nsresult rv = NS_GetCurrentThread(getter_AddRefs(thread));
     593          12 :   if (NS_FAILED(rv)) {
     594           0 :     return nullptr;
     595             :   }
     596             : 
     597          12 :   return thread->SerialEventTarget();
     598             : }
     599             : 
     600             : nsISerialEventTarget*
     601          37 : GetMainThreadSerialEventTarget()
     602             : {
     603          74 :   nsCOMPtr<nsIThread> thread;
     604          37 :   nsresult rv = NS_GetMainThread(getter_AddRefs(thread));
     605          37 :   if (NS_FAILED(rv)) {
     606           0 :     return nullptr;
     607             :   }
     608             : 
     609          37 :   return thread->SerialEventTarget();
     610             : }
     611             : 
     612             : } // namespace mozilla
     613             : 
     614             : bool
     615       24959 : nsIEventTarget::IsOnCurrentThread()
     616             : {
     617       24959 :   if (mVirtualThread) {
     618       24956 :     return mVirtualThread == GetCurrentVirtualThread();
     619             :   }
     620           3 :   return IsOnCurrentThreadInfallible();
     621             : }

Generated by: LCOV version 1.13