Fix assertion in SpinLock when called from a signal handler.

Since the signal handler can be called in any thread of the application, it may happen so in a non-D thread where Thread.getThis() returns null. This change works around this and also removes the need to call SpinLock.setup on thread startup.
This commit is contained in:
Sönke Ludwig 2018-10-30 12:27:01 +01:00
parent 8c4b147605
commit c3272f7d1f
2 changed files with 14 additions and 19 deletions

View file

@ -1350,9 +1350,6 @@ shared static this()
import std.concurrency;
scheduler = new VibedScheduler;
import vibe.core.sync : SpinLock;
SpinLock.setup();
}
shared static ~this()
@ -1377,10 +1374,6 @@ static this()
synchronized (st_threadsMutex)
if (!st_threads.any!(c => c.thread is thisthr))
st_threads ~= ThreadContext(thisthr);
import vibe.core.sync : SpinLock;
SpinLock.setup();
}
static ~this()
@ -1463,7 +1456,10 @@ private extern(C) void onSignal(int signal)
nothrow {
logInfo("Received signal %d. Shutting down.", signal);
atomicStore(st_term, true);
try st_threadsSignal.emit(); catch (Throwable) {}
try st_threadsSignal.emit();
catch (Throwable th) {
logDebug("Failed to notify for event loop exit: %s", th.msg);
}
}
private extern(C) void onBrokenPipe(int signal)

View file

@ -1217,21 +1217,20 @@ package shared(Monitor!(T, M)) createMonitor(T, M)(M mutex)
package struct SpinLock {
private shared int locked;
static int threadID = 0;
static void setup()
{
import core.thread : Thread;
threadID = cast(int)cast(void*)Thread.getThis();
}
debug static int threadID;
@safe nothrow @nogc shared:
bool tryLock()
@trusted {
assert(threadID != 0, "SpinLock.setup() was not called.");
assert(atomicLoad(locked) != threadID, "Recursive lock attempt.");
return cas(&locked, 0, threadID);
debug {
import core.thread : Thread;
if (threadID == 0) threadID = cast(int)cast(void*)Thread.getThis();
if (threadID == 0) threadID = -1; // workaround for non-D threads
assert(atomicLoad(locked) != threadID, "Recursive lock attempt.");
int tid = threadID;
} else int tid = 1;
return cas(&locked, 0, tid);
}
void lock()
@ -1241,7 +1240,7 @@ package struct SpinLock {
void unlock()
@trusted {
assert(atomicLoad(locked) == threadID, "Unlocking spin lock that is not owned by the current thread.");
debug assert(atomicLoad(locked) == threadID, "Unlocking spin lock that is not owned by the current thread.");
atomicStore(locked, 0);
}
}