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/. */
7 #include "nsEventQueue.h"
10 #include "nsThreadUtils.h"
12 #include "mozilla/ChaosMode.h"
14 using namespace mozilla
;
17 static PRLogModuleInfo
*
20 static PRLogModuleInfo
* sLog
;
22 sLog
= PR_NewLogModule("nsEventQueue");
30 #define LOG(args) PR_LOG(GetLog(), PR_LOG_DEBUG, args)
32 nsEventQueue::nsEventQueue()
33 : mReentrantMonitor("nsEventQueue.mReentrantMonitor")
41 nsEventQueue::~nsEventQueue()
43 // It'd be nice to be able to assert that no one else is holding the monitor,
44 // but NSPR doesn't really expose APIs for it.
45 NS_ASSERTION(IsEmpty(),
46 "Non-empty event queue being destroyed; events being leaked.");
54 nsEventQueue::GetEvent(bool aMayWait
, nsIRunnable
** aResult
)
57 ReentrantMonitorAutoEnter
mon(mReentrantMonitor
);
66 LOG(("EVENTQ(%p): wait begin\n", this));
68 LOG(("EVENTQ(%p): wait end\n", this));
72 *aResult
= mHead
->mEvents
[mOffsetHead
++];
74 // Check if mHead points to empty Page
75 if (mOffsetHead
== EVENTS_PER_PAGE
) {
88 nsEventQueue::PutEvent(nsIRunnable
* aRunnable
)
90 // Avoid calling AddRef+Release while holding our monitor.
91 nsRefPtr
<nsIRunnable
> event(aRunnable
);
93 if (ChaosMode::isActive()) {
94 // With probability 0.5, yield so other threads have a chance to
95 // dispatch events to this queue first.
96 if (ChaosMode::randomUint32LessThan(2)) {
97 PR_Sleep(PR_INTERVAL_NO_WAIT
);
101 ReentrantMonitorAutoEnter
mon(mReentrantMonitor
);
110 } else if (mOffsetTail
== EVENTS_PER_PAGE
) {
111 Page
* page
= NewPage();
119 event
.swap(mTail
->mEvents
[mOffsetTail
]);
121 LOG(("EVENTQ(%p): notify\n", this));