Bug 1513615 - part 1 - tweak nsTimerEvent allocation; r=glandium

Unlike many of our uses of `new`, nsTimerEvent has its own definition of
`operator new`, to ensure instances are allocated through
TimerEventAllocator.  And allocating with TimerEventAllocator can fail.
Later changes, however, want to assume that constructing an nsTimerEvent
can't fail, which is difficult to guarantee with the current structure.

To make that guarantee, we need to make explicit what calling `new`
does: there's an "allocate memory" step and a "construct the object"
step.  The first part can fail, and that's what we care about here.
Once we have a chunk of memory, we can construct the object as normal,
secure in the knowledge that calling (placement) `new` is now guaranteed
to succeed.
This commit is contained in:
Nathan Froyd 2019-01-08 19:31:40 -05:00
Родитель fbf8ff4b88
Коммит b9a6220890
1 изменённых файлов: 4 добавлений и 2 удалений

Просмотреть файл

@ -17,6 +17,7 @@
#include "mozilla/ArenaAllocator.h"
#include "mozilla/ArrayUtils.h"
#include "mozilla/BinarySearch.h"
#include "mozilla/OperatorNewExtensions.h"
#include <math.h>
@ -714,10 +715,11 @@ already_AddRefed<nsTimerImpl> TimerThread::PostTimerEvent(
// event, so we can avoid firing a timer that was re-initialized after being
// canceled.
RefPtr<nsTimerEvent> event = new nsTimerEvent;
if (!event) {
void* p = nsTimerEvent::operator new(sizeof(nsTimerEvent));
if (!p) {
return timer.forget();
}
RefPtr<nsTimerEvent> event = ::new (KnownNotNull, p) nsTimerEvent();
if (MOZ_LOG_TEST(GetTimerLog(), LogLevel::Debug)) {
event->mInitTime = TimeStamp::Now();