xpcom/threads/nsEventQueue.h

branch
TOR_BUG_9701
changeset 15
b8a032363ba2
equal deleted inserted replaced
-1:000000000000 0:1ea962680771
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/. */
6
7 #ifndef nsEventQueue_h__
8 #define nsEventQueue_h__
9
10 #include <stdlib.h>
11 #include "mozilla/ReentrantMonitor.h"
12 #include "nsIRunnable.h"
13
14 // A threadsafe FIFO event queue...
15 class nsEventQueue
16 {
17 typedef mozilla::ReentrantMonitor ReentrantMonitor;
18
19 public:
20 nsEventQueue();
21 ~nsEventQueue();
22
23 // This method adds a new event to the pending event queue. The event object
24 // is AddRef'd if this method succeeds. This method returns true if the
25 // event was stored in the event queue, and it returns false if it could
26 // not allocate sufficient memory.
27 bool PutEvent(nsIRunnable *event);
28
29 // This method gets an event from the event queue. If mayWait is true, then
30 // the method will block the calling thread until an event is available. If
31 // the event is null, then the method returns immediately indicating whether
32 // or not an event is pending. When the resulting event is non-null, the
33 // caller is responsible for releasing the event object. This method does
34 // not alter the reference count of the resulting event.
35 bool GetEvent(bool mayWait, nsIRunnable **event);
36
37 // This method returns true if there is a pending event.
38 bool HasPendingEvent() {
39 return GetEvent(false, nullptr);
40 }
41
42 // This method returns the next pending event or null.
43 bool GetPendingEvent(nsIRunnable **runnable) {
44 return GetEvent(false, runnable);
45 }
46
47 // This method waits for and returns the next pending event.
48 bool WaitPendingEvent(nsIRunnable **runnable) {
49 return GetEvent(true, runnable);
50 }
51
52 // Expose the event queue's monitor for "power users"
53 ReentrantMonitor& GetReentrantMonitor() {
54 return mReentrantMonitor;
55 }
56
57 private:
58
59 bool IsEmpty() {
60 return !mHead || (mHead == mTail && mOffsetHead == mOffsetTail);
61 }
62
63 enum { EVENTS_PER_PAGE = 255 };
64
65 // Page objects are linked together to form a simple deque.
66
67 struct Page {
68 struct Page *mNext;
69 nsIRunnable *mEvents[EVENTS_PER_PAGE];
70 };
71
72 static_assert((sizeof(Page) & (sizeof(Page) - 1)) == 0,
73 "sizeof(Page) should be a power of two to avoid heap slop.");
74
75 static Page *NewPage() {
76 return static_cast<Page *>(calloc(1, sizeof(Page)));
77 }
78
79 static void FreePage(Page *p) {
80 free(p);
81 }
82
83 ReentrantMonitor mReentrantMonitor;
84
85 Page *mHead;
86 Page *mTail;
87
88 uint16_t mOffsetHead; // offset into mHead where next item is removed
89 uint16_t mOffsetTail; // offset into mTail where next item is added
90 };
91
92 #endif // nsEventQueue_h__

mercurial