Avoid possible dangling objects referenced by timer callback delegates. Fixes #2.
This commit is contained in:
parent
a80c8bd18c
commit
2acf44596a
|
@ -15,6 +15,7 @@ final class LoopTimeoutTimerDriver : EventDriverTimers {
|
||||||
import std.datetime : Clock;
|
import std.datetime : Clock;
|
||||||
import std.range : SortedRange, assumeSorted, take;
|
import std.range : SortedRange, assumeSorted, take;
|
||||||
import core.time : hnsecs, Duration;
|
import core.time : hnsecs, Duration;
|
||||||
|
import core.memory : GC;
|
||||||
|
|
||||||
private {
|
private {
|
||||||
static FreeList!(Mallocator, TimerSlot.sizeof) ms_allocator;
|
static FreeList!(Mallocator, TimerSlot.sizeof) ms_allocator;
|
||||||
|
@ -84,6 +85,7 @@ final class LoopTimeoutTimerDriver : EventDriverTimers {
|
||||||
TimerSlot* tm;
|
TimerSlot* tm;
|
||||||
try tm = ms_allocator.make!TimerSlot;
|
try tm = ms_allocator.make!TimerSlot;
|
||||||
catch (Exception e) return TimerID.invalid;
|
catch (Exception e) return TimerID.invalid;
|
||||||
|
GC.addRange(tm, TimerSlot.sizeof, typeid(TimerSlot));
|
||||||
assert(tm !is null);
|
assert(tm !is null);
|
||||||
tm.id = id;
|
tm.id = id;
|
||||||
tm.refCount = 1;
|
tm.refCount = 1;
|
||||||
|
@ -167,7 +169,12 @@ final class LoopTimeoutTimerDriver : EventDriverTimers {
|
||||||
if (!--tm.refCount) {
|
if (!--tm.refCount) {
|
||||||
if (tm.pending) stop(tm.id);
|
if (tm.pending) stop(tm.id);
|
||||||
m_timers.remove(descriptor);
|
m_timers.remove(descriptor);
|
||||||
() @trusted { scope (failure) assert(false); ms_allocator.dispose(tm); } ();
|
() @trusted {
|
||||||
|
scope (failure) assert(false);
|
||||||
|
ms_allocator.dispose(tm);
|
||||||
|
GC.removeRange(tm);
|
||||||
|
} ();
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue