Merge pull request #58 from vibe-d/nogc_assert
Use a custom nogc_assert in cleanup code.
This commit is contained in:
commit
bcf178ef98
|
@ -4,6 +4,7 @@ module eventcore.drivers.posix.events;
|
||||||
import eventcore.driver;
|
import eventcore.driver;
|
||||||
import eventcore.drivers.posix.driver;
|
import eventcore.drivers.posix.driver;
|
||||||
import eventcore.internal.consumablequeue : ConsumableQueue;
|
import eventcore.internal.consumablequeue : ConsumableQueue;
|
||||||
|
import eventcore.internal.utils : nogc_assert;
|
||||||
|
|
||||||
version (linux) {
|
version (linux) {
|
||||||
nothrow @nogc extern (C) int eventfd(uint initval, int flags);
|
nothrow @nogc extern (C) int eventfd(uint initval, int flags);
|
||||||
|
@ -199,13 +200,13 @@ final class PosixEventDriverEvents(Loop : PosixEventLoop, Sockets : EventDriverS
|
||||||
|
|
||||||
final override bool releaseRef(EventID descriptor)
|
final override bool releaseRef(EventID descriptor)
|
||||||
{
|
{
|
||||||
assert(getRC(descriptor) > 0, "Releasing reference to unreferenced event FD.");
|
nogc_assert(getRC(descriptor) > 0, "Releasing reference to unreferenced event FD.");
|
||||||
if (--getRC(descriptor) == 0) {
|
if (--getRC(descriptor) == 0) {
|
||||||
if (!isInternal(descriptor))
|
if (!isInternal(descriptor))
|
||||||
m_loop.m_waiterCount -= getSlot(descriptor).waiters.length;
|
m_loop.m_waiterCount -= getSlot(descriptor).waiters.length;
|
||||||
() @trusted nothrow {
|
() @trusted nothrow {
|
||||||
try .destroy(getSlot(descriptor).waiters);
|
try .destroy(getSlot(descriptor).waiters);
|
||||||
catch (Exception e) assert(false, e.msg);
|
catch (Exception e) nogc_assert(false, e.msg);
|
||||||
} ();
|
} ();
|
||||||
version (linux) {
|
version (linux) {
|
||||||
m_loop.unregisterFD(descriptor, EventMask.read);
|
m_loop.unregisterFD(descriptor, EventMask.read);
|
||||||
|
@ -216,7 +217,7 @@ final class PosixEventDriverEvents(Loop : PosixEventLoop, Sockets : EventDriverS
|
||||||
try {
|
try {
|
||||||
synchronized (m_eventsMutex)
|
synchronized (m_eventsMutex)
|
||||||
m_events.remove(rs);
|
m_events.remove(rs);
|
||||||
} catch (Exception e) assert(false, e.msg);
|
} catch (Exception e) nogc_assert(false, e.msg);
|
||||||
}
|
}
|
||||||
m_loop.clearFD(descriptor);
|
m_loop.clearFD(descriptor);
|
||||||
version (Posix) close(cast(int)descriptor);
|
version (Posix) close(cast(int)descriptor);
|
||||||
|
@ -228,7 +229,7 @@ final class PosixEventDriverEvents(Loop : PosixEventLoop, Sockets : EventDriverS
|
||||||
|
|
||||||
private EventSlot* getSlot(EventID id)
|
private EventSlot* getSlot(EventID id)
|
||||||
{
|
{
|
||||||
assert(id < m_loop.m_fds.length, "Invalid event ID.");
|
nogc_assert(id < m_loop.m_fds.length, "Invalid event ID.");
|
||||||
return () @trusted { return &m_loop.m_fds[id].event(); } ();
|
return () @trusted { return &m_loop.m_fds[id].event(); } ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,6 +3,7 @@ module eventcore.drivers.posix.signals;
|
||||||
|
|
||||||
import eventcore.driver;
|
import eventcore.driver;
|
||||||
import eventcore.drivers.posix.driver;
|
import eventcore.drivers.posix.driver;
|
||||||
|
import eventcore.internal.utils : nogc_assert;
|
||||||
|
|
||||||
import std.algorithm.comparison : among;
|
import std.algorithm.comparison : among;
|
||||||
|
|
||||||
|
@ -56,7 +57,7 @@ final class SignalFDEventDriverSignals(Loop : PosixEventLoop) : EventDriverSigna
|
||||||
override bool releaseRef(SignalListenID descriptor)
|
override bool releaseRef(SignalListenID descriptor)
|
||||||
{
|
{
|
||||||
FD fd = cast(FD)descriptor;
|
FD fd = cast(FD)descriptor;
|
||||||
assert(m_loop.m_fds[fd].common.refCount > 0, "Releasing reference to unreferenced event FD.");
|
nogc_assert(m_loop.m_fds[fd].common.refCount > 0, "Releasing reference to unreferenced event FD.");
|
||||||
if (--m_loop.m_fds[fd].common.refCount == 1) { // NOTE: 1 because setNotifyCallback adds a second reference
|
if (--m_loop.m_fds[fd].common.refCount == 1) { // NOTE: 1 because setNotifyCallback adds a second reference
|
||||||
m_loop.unregisterFD(fd, EventMask.read);
|
m_loop.unregisterFD(fd, EventMask.read);
|
||||||
m_loop.clearFD(fd);
|
m_loop.clearFD(fd);
|
||||||
|
|
|
@ -804,7 +804,7 @@ final class PosixEventDriverSockets(Loop : PosixEventLoop) : EventDriverSockets
|
||||||
{
|
{
|
||||||
import taggedalgebraic : hasType;
|
import taggedalgebraic : hasType;
|
||||||
auto slot = () @trusted { return &m_loop.m_fds[fd]; } ();
|
auto slot = () @trusted { return &m_loop.m_fds[fd]; } ();
|
||||||
assert(slot.common.refCount > 0, "Releasing reference to unreferenced socket FD.");
|
nogc_assert(slot.common.refCount > 0, "Releasing reference to unreferenced socket FD.");
|
||||||
// listening sockets have an incremented the reference count because of setNotifyCallback
|
// listening sockets have an incremented the reference count because of setNotifyCallback
|
||||||
int base_refcount = slot.specific.hasType!StreamListenSocketSlot ? 1 : 0;
|
int base_refcount = slot.specific.hasType!StreamListenSocketSlot ? 1 : 0;
|
||||||
if (--slot.common.refCount == base_refcount) {
|
if (--slot.common.refCount == base_refcount) {
|
||||||
|
|
|
@ -3,6 +3,7 @@ module eventcore.drivers.posix.watchers;
|
||||||
|
|
||||||
import eventcore.driver;
|
import eventcore.driver;
|
||||||
import eventcore.drivers.posix.driver;
|
import eventcore.drivers.posix.driver;
|
||||||
|
import eventcore.internal.utils : nogc_assert;
|
||||||
|
|
||||||
|
|
||||||
final class InotifyEventDriverWatchers(Events : EventDriverEvents) : EventDriverWatchers
|
final class InotifyEventDriverWatchers(Events : EventDriverEvents) : EventDriverWatchers
|
||||||
|
@ -64,7 +65,7 @@ final class InotifyEventDriverWatchers(Events : EventDriverEvents) : EventDriver
|
||||||
final override bool releaseRef(WatcherID descriptor)
|
final override bool releaseRef(WatcherID descriptor)
|
||||||
{
|
{
|
||||||
FD fd = cast(FD)descriptor;
|
FD fd = cast(FD)descriptor;
|
||||||
assert(m_loop.m_fds[fd].common.refCount > 0, "Releasing reference to unreferenced event FD.");
|
nogc_assert(m_loop.m_fds[fd].common.refCount > 0, "Releasing reference to unreferenced event FD.");
|
||||||
if (--m_loop.m_fds[fd].common.refCount == 1) { // NOTE: 1 because setNotifyCallback increments the reference count
|
if (--m_loop.m_fds[fd].common.refCount == 1) { // NOTE: 1 because setNotifyCallback increments the reference count
|
||||||
m_loop.unregisterFD(fd, EventMask.read);
|
m_loop.unregisterFD(fd, EventMask.read);
|
||||||
m_loop.clearFD(fd);
|
m_loop.clearFD(fd);
|
||||||
|
@ -281,10 +282,10 @@ final class PollEventDriverWatchers(Events : EventDriverEvents) : EventDriverWat
|
||||||
|
|
||||||
final override bool releaseRef(WatcherID descriptor)
|
final override bool releaseRef(WatcherID descriptor)
|
||||||
{
|
{
|
||||||
assert(descriptor != WatcherID.invalid);
|
nogc_assert(descriptor != WatcherID.invalid, "Invalid directory watcher ID released");
|
||||||
auto evt = cast(EventID)descriptor;
|
auto evt = cast(EventID)descriptor;
|
||||||
auto pt = evt in m_pollers;
|
auto pt = evt in m_pollers;
|
||||||
assert(pt !is null);
|
nogc_assert(pt !is null, "Directory watcher polling thread does not exist");
|
||||||
if (!m_events.releaseRef(evt)) {
|
if (!m_events.releaseRef(evt)) {
|
||||||
pt.dispose();
|
pt.dispose();
|
||||||
m_pollers.remove(evt);
|
m_pollers.remove(evt);
|
||||||
|
|
|
@ -5,6 +5,7 @@ module eventcore.drivers.timer;
|
||||||
|
|
||||||
import eventcore.driver;
|
import eventcore.driver;
|
||||||
import eventcore.internal.dlist;
|
import eventcore.internal.dlist;
|
||||||
|
import eventcore.internal.utils : nogc_assert;
|
||||||
|
|
||||||
|
|
||||||
final class LoopTimeoutTimerDriver : EventDriverTimers {
|
final class LoopTimeoutTimerDriver : EventDriverTimers {
|
||||||
|
@ -143,8 +144,8 @@ final class LoopTimeoutTimerDriver : EventDriverTimers {
|
||||||
|
|
||||||
final override bool releaseRef(TimerID descriptor)
|
final override bool releaseRef(TimerID descriptor)
|
||||||
{
|
{
|
||||||
assert(descriptor != TimerID.init, "Invalid timer ID.");
|
nogc_assert(descriptor != TimerID.init, "Invalid timer ID.");
|
||||||
assert(descriptor in m_timers, "Unknown timer ID.");
|
nogc_assert((descriptor in m_timers) !is null, "Unknown timer ID.");
|
||||||
if (descriptor !in m_timers) return true;
|
if (descriptor !in m_timers) return true;
|
||||||
|
|
||||||
auto tm = m_timers[descriptor];
|
auto tm = m_timers[descriptor];
|
||||||
|
|
|
@ -5,6 +5,7 @@ version (Windows):
|
||||||
import eventcore.driver;
|
import eventcore.driver;
|
||||||
import eventcore.drivers.timer;
|
import eventcore.drivers.timer;
|
||||||
import eventcore.internal.consumablequeue;
|
import eventcore.internal.consumablequeue;
|
||||||
|
import eventcore.internal.utils : nogc_assert;
|
||||||
import eventcore.internal.win32;
|
import eventcore.internal.win32;
|
||||||
import core.time : Duration;
|
import core.time : Duration;
|
||||||
import taggedalgebraic;
|
import taggedalgebraic;
|
||||||
|
@ -180,7 +181,7 @@ final class WinAPIEventDriverCore : EventDriverCore {
|
||||||
|
|
||||||
package void freeSlot(HANDLE h)
|
package void freeSlot(HANDLE h)
|
||||||
{
|
{
|
||||||
assert(h in m_handles, "Handle not in use - cannot free.");
|
nogc_assert((h in m_handles) !is null, "Handle not in use - cannot free.");
|
||||||
m_handles.remove(h);
|
m_handles.remove(h);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -214,7 +215,7 @@ private struct HandleSlot {
|
||||||
|
|
||||||
bool releaseRef(scope void delegate() @safe nothrow on_free)
|
bool releaseRef(scope void delegate() @safe nothrow on_free)
|
||||||
{
|
{
|
||||||
assert(refCount > 0);
|
nogc_assert(refCount > 0, "Releasing unreferenced slot.");
|
||||||
if (--refCount == 0) {
|
if (--refCount == 0) {
|
||||||
on_free();
|
on_free();
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -6,6 +6,7 @@ import eventcore.driver;
|
||||||
import eventcore.drivers.winapi.core;
|
import eventcore.drivers.winapi.core;
|
||||||
import eventcore.internal.win32;
|
import eventcore.internal.win32;
|
||||||
import eventcore.internal.consumablequeue;
|
import eventcore.internal.consumablequeue;
|
||||||
|
import eventcore.internal.utils : nogc_assert;
|
||||||
|
|
||||||
|
|
||||||
final class WinAPIEventDriverEvents : EventDriverEvents {
|
final class WinAPIEventDriverEvents : EventDriverEvents {
|
||||||
|
@ -108,7 +109,7 @@ final class WinAPIEventDriverEvents : EventDriverEvents {
|
||||||
override bool releaseRef(EventID descriptor)
|
override bool releaseRef(EventID descriptor)
|
||||||
{
|
{
|
||||||
auto pe = descriptor in m_events;
|
auto pe = descriptor in m_events;
|
||||||
assert(pe.refCount > 0);
|
nogc_assert(pe.refCount > 0, "Releasing unreference event.");
|
||||||
if (--pe.refCount == 0) {
|
if (--pe.refCount == 0) {
|
||||||
// make sure to not leak any waiter references for pending waits
|
// make sure to not leak any waiter references for pending waits
|
||||||
foreach (i; 0 .. pe.waiters.length)
|
foreach (i; 0 .. pe.waiters.length)
|
||||||
|
|
|
@ -5,7 +5,7 @@ version (Windows):
|
||||||
import eventcore.driver;
|
import eventcore.driver;
|
||||||
import eventcore.drivers.winapi.core;
|
import eventcore.drivers.winapi.core;
|
||||||
import eventcore.internal.win32;
|
import eventcore.internal.win32;
|
||||||
import eventcore.internal.utils : AlgebraicChoppedVector, print;
|
import eventcore.internal.utils : AlgebraicChoppedVector, print, nogc_assert;
|
||||||
import std.socket : Address;
|
import std.socket : Address;
|
||||||
|
|
||||||
private enum WM_USER_SOCKET = WM_USER + 1;
|
private enum WM_USER_SOCKET = WM_USER + 1;
|
||||||
|
@ -697,7 +697,7 @@ final class WinAPIEventDriverSockets : EventDriverSockets {
|
||||||
override bool releaseRef(SocketFD fd)
|
override bool releaseRef(SocketFD fd)
|
||||||
{
|
{
|
||||||
import taggedalgebraic : hasType;
|
import taggedalgebraic : hasType;
|
||||||
assert(m_sockets[fd].common.refCount > 0, "Releasing reference to unreferenced socket FD.");
|
nogc_assert(m_sockets[fd].common.refCount > 0, "Releasing reference to unreferenced socket FD.");
|
||||||
if (--m_sockets[fd].common.refCount == 0) {
|
if (--m_sockets[fd].common.refCount == 0) {
|
||||||
final switch (m_sockets[fd].specific.kind) with (SocketVector.FieldType) {
|
final switch (m_sockets[fd].specific.kind) with (SocketVector.FieldType) {
|
||||||
case Kind.none: break;
|
case Kind.none: break;
|
||||||
|
|
|
@ -15,6 +15,28 @@ void print(ARGS...)(string str, ARGS args)
|
||||||
r.put('\n');
|
r.put('\n');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private extern(C) Throwable.TraceInfo _d_traceContext(void* ptr = null);
|
||||||
|
|
||||||
|
void nogc_assert(bool cond, string message, string file = __FILE__, int line = __LINE__)
|
||||||
|
@trusted nothrow {
|
||||||
|
import core.stdc.stdlib : abort;
|
||||||
|
import std.stdio : stderr;
|
||||||
|
|
||||||
|
if (!cond) {
|
||||||
|
scope (exit) {
|
||||||
|
abort();
|
||||||
|
assert(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
stderr.writefln("Assertion failure @%s(%s): %s", file, line, message);
|
||||||
|
stderr.writeln("------------------------");
|
||||||
|
if (auto info = _d_traceContext(null)) {
|
||||||
|
foreach (s; info)
|
||||||
|
stderr.writeln(s);
|
||||||
|
} else stderr.writeln("no stack trace available");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
struct StdoutRange {
|
struct StdoutRange {
|
||||||
@safe: @nogc: nothrow:
|
@safe: @nogc: nothrow:
|
||||||
import core.stdc.stdio;
|
import core.stdc.stdio;
|
||||||
|
@ -124,7 +146,7 @@ struct ChoppedVector(T, size_t CHUNK_SIZE = 16*64*1024/nextPOT(T.sizeof)) {
|
||||||
}
|
}
|
||||||
|
|
||||||
while (m_chunkCount <= chunkidx) {
|
while (m_chunkCount <= chunkidx) {
|
||||||
() @trusted {
|
() @trusted {
|
||||||
auto ptr = cast(ChunkPtr)calloc(chunkSize, T.sizeof);
|
auto ptr = cast(ChunkPtr)calloc(chunkSize, T.sizeof);
|
||||||
assert(ptr !is null, "Failed to allocate chunk!");
|
assert(ptr !is null, "Failed to allocate chunk!");
|
||||||
// FIXME: initialize with T.init instead of 0
|
// FIXME: initialize with T.init instead of 0
|
||||||
|
|
Loading…
Reference in a new issue