Use a custom nogc_assert in cleanup code.

Unfortunately the built-in assert GC allocates an exception, which means that if called directly or indirectly form a finalizer, the assertion will not become visible and instead an InvalidMemoryOperationError is thrown.

This implements a custom nogc_assert() function that directly prints the assertion message and uses abort() to end the process.
This commit is contained in:
Sönke Ludwig 2018-03-11 12:08:09 +01:00
parent acc35e1107
commit df78af96bb
9 changed files with 45 additions and 17 deletions

View file

@ -3,6 +3,7 @@ module eventcore.drivers.posix.watchers;
import eventcore.driver;
import eventcore.drivers.posix.driver;
import eventcore.internal.utils : nogc_assert;
final class InotifyEventDriverWatchers(Events : EventDriverEvents) : EventDriverWatchers
@ -64,7 +65,7 @@ final class InotifyEventDriverWatchers(Events : EventDriverEvents) : EventDriver
final override bool releaseRef(WatcherID 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
m_loop.unregisterFD(fd, EventMask.read);
m_loop.clearFD(fd);
@ -281,10 +282,10 @@ final class PollEventDriverWatchers(Events : EventDriverEvents) : EventDriverWat
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 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)) {
pt.dispose();
m_pollers.remove(evt);