зеркало из https://github.com/mozilla/gecko-dev.git
Bug 996132: Make allocations in the event queue infallible. r=bsmedberg
This commit is contained in:
Родитель
5c5c731fae
Коммит
7af104c03a
|
@ -80,13 +80,12 @@ nsEventQueue::GetEvent(bool mayWait, nsIRunnable **result)
|
|||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
void
|
||||
nsEventQueue::PutEvent(nsIRunnable *runnable)
|
||||
{
|
||||
// Avoid calling AddRef+Release while holding our monitor.
|
||||
nsRefPtr<nsIRunnable> event(runnable);
|
||||
bool rv = true;
|
||||
{
|
||||
|
||||
if (ChaosMode::isActive()) {
|
||||
// With probability 0.5, yield so other threads have a chance to
|
||||
// dispatch events to this queue first.
|
||||
|
@ -99,29 +98,22 @@ nsEventQueue::PutEvent(nsIRunnable *runnable)
|
|||
|
||||
if (!mHead) {
|
||||
mHead = NewPage();
|
||||
if (!mHead) {
|
||||
rv = false;
|
||||
} else {
|
||||
MOZ_ASSERT(mHead);
|
||||
|
||||
mTail = mHead;
|
||||
mOffsetHead = 0;
|
||||
mOffsetTail = 0;
|
||||
}
|
||||
} else if (mOffsetTail == EVENTS_PER_PAGE) {
|
||||
Page *page = NewPage();
|
||||
if (!page) {
|
||||
rv = false;
|
||||
} else {
|
||||
MOZ_ASSERT(page);
|
||||
|
||||
mTail->mNext = page;
|
||||
mTail = page;
|
||||
mOffsetTail = 0;
|
||||
}
|
||||
}
|
||||
if (rv) {
|
||||
|
||||
event.swap(mTail->mEvents[mOffsetTail]);
|
||||
++mOffsetTail;
|
||||
LOG(("EVENTQ(%p): notify\n", this));
|
||||
mon.NotifyAll();
|
||||
}
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
|
|
@ -20,11 +20,10 @@ public:
|
|||
nsEventQueue();
|
||||
~nsEventQueue();
|
||||
|
||||
// This method adds a new event to the pending event queue. The event object
|
||||
// is AddRef'd if this method succeeds. This method returns true if the
|
||||
// event was stored in the event queue, and it returns false if it could
|
||||
// not allocate sufficient memory.
|
||||
bool PutEvent(nsIRunnable *event);
|
||||
// This method adds a new event to the pending event queue. The queue holds
|
||||
// a strong reference to the event after this method returns. This method
|
||||
// cannot fail.
|
||||
void PutEvent(nsIRunnable *event);
|
||||
|
||||
// This method gets an event from the event queue. If mayWait is true, then
|
||||
// the method will block the calling thread until an event is available. If
|
||||
|
@ -44,11 +43,6 @@ public:
|
|||
return GetEvent(false, runnable);
|
||||
}
|
||||
|
||||
// This method waits for and returns the next pending event.
|
||||
bool WaitPendingEvent(nsIRunnable **runnable) {
|
||||
return GetEvent(true, runnable);
|
||||
}
|
||||
|
||||
// Expose the event queue's monitor for "power users"
|
||||
ReentrantMonitor& GetReentrantMonitor() {
|
||||
return mReentrantMonitor;
|
||||
|
@ -73,7 +67,7 @@ private:
|
|||
"sizeof(Page) should be a power of two to avoid heap slop.");
|
||||
|
||||
static Page *NewPage() {
|
||||
return static_cast<Page *>(calloc(1, sizeof(Page)));
|
||||
return static_cast<Page *>(moz_xcalloc(1, sizeof(Page)));
|
||||
}
|
||||
|
||||
static void FreePage(Page *p) {
|
||||
|
|
|
@ -432,8 +432,7 @@ nsThread::PutEvent(nsIRunnable *event, nsNestedEventTarget *target)
|
|||
NS_WARNING("An event was posted to a thread that will never run it (rejected)");
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
}
|
||||
if (!queue->PutEvent(event))
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
queue->PutEvent(event);
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIThreadObserver> obs = GetObserver();
|
||||
|
|
|
@ -97,8 +97,8 @@ protected:
|
|||
return mQueue.GetEvent(mayWait, event);
|
||||
}
|
||||
|
||||
bool PutEvent(nsIRunnable *event) {
|
||||
return mQueue.PutEvent(event);
|
||||
void PutEvent(nsIRunnable *event) {
|
||||
mQueue.PutEvent(event);
|
||||
}
|
||||
|
||||
bool HasPendingEvent() {
|
||||
|
|
Загрузка…
Ссылка в новой задаче