1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim:set ts=2 sw=2 sts=2 et cindent: */
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/. */
10 #include "mozilla/Mutex.h"
11 #include "nsIThreadInternal.h"
12 #include "nsISupportsPriority.h"
13 #include "nsEventQueue.h"
14 #include "nsThreadUtils.h"
16 #include "nsTObserverArray.h"
17 #include "mozilla/Attributes.h"
20 class nsThread MOZ_FINAL
: public nsIThreadInternal
,
21 public nsISupportsPriority
24 NS_DECL_THREADSAFE_ISUPPORTS
25 NS_DECL_NSIEVENTTARGET
27 NS_DECL_NSITHREADINTERNAL
28 NS_DECL_NSISUPPORTSPRIORITY
35 nsThread(MainThreadFlag aMainThread
, uint32_t aStackSize
);
37 // Initialize this as a wrapper for a new PRThread.
40 // Initialize this as a wrapper for the current PRThread.
41 nsresult
InitCurrentThread();
43 // The PRThread corresponding to this thread.
44 PRThread
*GetPRThread() { return mThread
; }
46 // If this flag is true, then the nsThread was created using
47 // nsIThreadManager::NewThread.
48 bool ShutdownRequired() { return mShutdownRequired
; }
50 // Clear the observer list.
51 void ClearObservers() { mEventObservers
.Clear(); }
54 SetMainThreadObserver(nsIThreadObserver
* aObserver
);
57 static nsIThreadObserver
* sMainThreadObserver
;
59 friend class nsThreadShutdownEvent
;
63 bool ShuttingDown() { return mShutdownContext
!= nullptr; }
65 static void ThreadFunc(void *arg
);
68 already_AddRefed
<nsIThreadObserver
> GetObserver() {
69 nsIThreadObserver
*obs
;
70 nsThread::GetObserver(&obs
);
71 return already_AddRefed
<nsIThreadObserver
>(obs
);
74 // Wrappers for event queue methods:
75 bool GetEvent(bool mayWait
, nsIRunnable
**event
) {
76 return mEvents
.GetEvent(mayWait
, event
);
78 nsresult
PutEvent(nsIRunnable
*event
);
80 // This lock protects access to mObserver, mEvents and mEventsAreDoomed.
81 // All of those fields are only modified on the thread itself (never from
82 // another thread). This means that we can avoid holding the lock while
83 // using mObserver and mEvents on the thread itself. When calling PutEvent
84 // on mEvents, we have to hold the lock to synchronize with PopEventQueue.
87 nsCOMPtr
<nsIThreadObserver
> mObserver
;
89 // Only accessed on the target thread.
90 nsAutoTObserverArray
<nsCOMPtr
<nsIThreadObserver
>, 2> mEventObservers
;
96 uint32_t mRunningEvent
; // counter
99 struct nsThreadShutdownContext
*mShutdownContext
;
101 bool mShutdownRequired
;
102 // Set to true when events posted to this thread will never run.
103 bool mEventsAreDoomed
;
104 MainThreadFlag mIsMainThread
;
107 //-----------------------------------------------------------------------------
109 class nsThreadSyncDispatch
: public nsRunnable
{
111 nsThreadSyncDispatch(nsIThread
*origin
, nsIRunnable
*task
)
112 : mOrigin(origin
), mSyncTask(task
), mResult(NS_ERROR_NOT_INITIALIZED
) {
116 return mSyncTask
!= nullptr;
126 nsCOMPtr
<nsIThread
> mOrigin
;
127 nsCOMPtr
<nsIRunnable
> mSyncTask
;
131 #endif // nsThread_h__