Avoid possible dangling objects referenced by timer callback delegates. Fixes #2.

This commit is contained in:
Sönke Ludwig 2016-12-18 19:39:17 +01:00
parent a80c8bd18c
commit 2acf44596a

View file

@ -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;
} }