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:
parent
8c4b147605
commit
c3272f7d1f
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue