mirror of
https://github.com/corda/corda.git
synced 2025-01-17 02:09:50 +00:00
optionally specify reentrancy when creating a System object
This allows multiple Avian VMs to share the same process space, provided they don't try to use functionality that involves global shared resources (e.g. signal handling).
This commit is contained in:
parent
9b2a02e92b
commit
763aada4b0
@ -176,7 +176,7 @@ inline void NO_RETURN sysAbort(System* s)
|
|||||||
|
|
||||||
// #endif // not NDEBUG
|
// #endif // not NDEBUG
|
||||||
|
|
||||||
AVIAN_EXPORT System* makeSystem();
|
AVIAN_EXPORT System* makeSystem(bool reentrant = false);
|
||||||
|
|
||||||
} // namespace vm
|
} // namespace vm
|
||||||
|
|
||||||
|
@ -92,7 +92,7 @@ const int signals[] = {VisitSignal, InterruptSignal, PipeSignal};
|
|||||||
const unsigned SignalCount = 3;
|
const unsigned SignalCount = 3;
|
||||||
|
|
||||||
class MySystem;
|
class MySystem;
|
||||||
MySystem* system;
|
MySystem* globalSystem;
|
||||||
|
|
||||||
void handleSignal(int signal, siginfo_t* info, void* context);
|
void handleSignal(int signal, siginfo_t* info, void* context);
|
||||||
|
|
||||||
@ -624,16 +624,18 @@ class MySystem : public System {
|
|||||||
System::Library* next_;
|
System::Library* next_;
|
||||||
};
|
};
|
||||||
|
|
||||||
MySystem() : threadVisitor(0), visitTarget(0)
|
MySystem(bool reentrant) : reentrant(reentrant), threadVisitor(0), visitTarget(0)
|
||||||
{
|
{
|
||||||
expect(this, system == 0);
|
if (not reentrant) {
|
||||||
system = this;
|
expect(this, globalSystem == 0);
|
||||||
|
globalSystem = this;
|
||||||
|
|
||||||
expect(this, registerHandler(InterruptSignalIndex));
|
expect(this, registerHandler(InterruptSignalIndex));
|
||||||
expect(this, registerHandler(VisitSignalIndex));
|
expect(this, registerHandler(VisitSignalIndex));
|
||||||
expect(this, registerHandler(PipeSignalIndex));
|
expect(this, registerHandler(PipeSignalIndex));
|
||||||
|
|
||||||
expect(this, make(&visitLock) == 0);
|
expect(this, make(&visitLock) == 0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns true on success, false on failure
|
// Returns true on success, false on failure
|
||||||
@ -708,6 +710,8 @@ class MySystem : public System {
|
|||||||
System::Thread* sTarget,
|
System::Thread* sTarget,
|
||||||
ThreadVisitor* visitor)
|
ThreadVisitor* visitor)
|
||||||
{
|
{
|
||||||
|
expect(this, not reentrant);
|
||||||
|
|
||||||
assertT(this, st != sTarget);
|
assertT(this, st != sTarget);
|
||||||
|
|
||||||
Thread* target = static_cast<Thread*>(sTarget);
|
Thread* target = static_cast<Thread*>(sTarget);
|
||||||
@ -767,7 +771,7 @@ class MySystem : public System {
|
|||||||
|
|
||||||
threadVisitor = 0;
|
threadVisitor = 0;
|
||||||
|
|
||||||
system->visitLock->notifyAll(t);
|
globalSystem->visitLock->notifyAll(t);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
#endif // not __APPLE__
|
#endif // not __APPLE__
|
||||||
@ -938,18 +942,21 @@ class MySystem : public System {
|
|||||||
|
|
||||||
virtual void dispose()
|
virtual void dispose()
|
||||||
{
|
{
|
||||||
visitLock->dispose();
|
if (not reentrant) {
|
||||||
|
visitLock->dispose();
|
||||||
|
|
||||||
expect(this, unregisterHandler(InterruptSignalIndex));
|
expect(this, unregisterHandler(InterruptSignalIndex));
|
||||||
expect(this, unregisterHandler(VisitSignalIndex));
|
expect(this, unregisterHandler(VisitSignalIndex));
|
||||||
expect(this, unregisterHandler(PipeSignalIndex));
|
expect(this, unregisterHandler(PipeSignalIndex));
|
||||||
system = 0;
|
globalSystem = 0;
|
||||||
|
}
|
||||||
|
|
||||||
::free(this);
|
::free(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct sigaction oldHandlers[SignalCount];
|
struct sigaction oldHandlers[SignalCount];
|
||||||
|
|
||||||
|
bool reentrant;
|
||||||
ThreadVisitor* threadVisitor;
|
ThreadVisitor* threadVisitor;
|
||||||
Thread* visitTarget;
|
Thread* visitTarget;
|
||||||
System::Monitor* visitLock;
|
System::Monitor* visitLock;
|
||||||
@ -965,13 +972,13 @@ void handleSignal(int signal, siginfo_t*, void* context)
|
|||||||
|
|
||||||
switch (signal) {
|
switch (signal) {
|
||||||
case VisitSignal: {
|
case VisitSignal: {
|
||||||
system->threadVisitor->visit(ip, stack, link);
|
globalSystem->threadVisitor->visit(ip, stack, link);
|
||||||
|
|
||||||
System::Thread* t = system->visitTarget;
|
System::Thread* t = globalSystem->visitTarget;
|
||||||
system->visitTarget = 0;
|
globalSystem->visitTarget = 0;
|
||||||
|
|
||||||
ACQUIRE_MONITOR(t, system->visitLock);
|
ACQUIRE_MONITOR(t, globalSystem->visitLock);
|
||||||
system->visitLock->notifyAll(t);
|
globalSystem->visitLock->notifyAll(t);
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case InterruptSignal:
|
case InterruptSignal:
|
||||||
@ -987,9 +994,9 @@ void handleSignal(int signal, siginfo_t*, void* context)
|
|||||||
|
|
||||||
namespace vm {
|
namespace vm {
|
||||||
|
|
||||||
AVIAN_EXPORT System* makeSystem()
|
AVIAN_EXPORT System* makeSystem(bool reentrant)
|
||||||
{
|
{
|
||||||
return new (malloc(sizeof(MySystem))) MySystem();
|
return new (malloc(sizeof(MySystem))) MySystem(reentrant);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace vm
|
} // namespace vm
|
||||||
|
@ -115,7 +115,7 @@ class MutexResource {
|
|||||||
};
|
};
|
||||||
|
|
||||||
class MySystem;
|
class MySystem;
|
||||||
MySystem* system;
|
MySystem* globalSystem;
|
||||||
|
|
||||||
DWORD WINAPI run(void* r)
|
DWORD WINAPI run(void* r)
|
||||||
{
|
{
|
||||||
@ -655,10 +655,12 @@ class MySystem : public System {
|
|||||||
System::Library* next_;
|
System::Library* next_;
|
||||||
};
|
};
|
||||||
|
|
||||||
MySystem()
|
MySystem(bool reentrant): reentrant(reentrant)
|
||||||
{
|
{
|
||||||
expect(this, system == 0);
|
if (not reentrant) {
|
||||||
system = this;
|
expect(this, globalSystem == 0);
|
||||||
|
globalSystem = this;
|
||||||
|
}
|
||||||
|
|
||||||
mutex = CreateMutex(0, false, 0);
|
mutex = CreateMutex(0, false, 0);
|
||||||
assertT(this, mutex);
|
assertT(this, mutex);
|
||||||
@ -1007,7 +1009,10 @@ class MySystem : public System {
|
|||||||
|
|
||||||
virtual void dispose()
|
virtual void dispose()
|
||||||
{
|
{
|
||||||
system = 0;
|
if (not reentrant) {
|
||||||
|
globalSystem = 0;
|
||||||
|
}
|
||||||
|
|
||||||
CloseHandle(mutex);
|
CloseHandle(mutex);
|
||||||
::free(this);
|
::free(this);
|
||||||
}
|
}
|
||||||
@ -1019,9 +1024,9 @@ class MySystem : public System {
|
|||||||
|
|
||||||
namespace vm {
|
namespace vm {
|
||||||
|
|
||||||
AVIAN_EXPORT System* makeSystem()
|
AVIAN_EXPORT System* makeSystem(bool reentrant)
|
||||||
{
|
{
|
||||||
return new (malloc(sizeof(MySystem))) MySystem();
|
return new (malloc(sizeof(MySystem))) MySystem(reentrant);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace vm
|
} // namespace vm
|
||||||
|
Loading…
Reference in New Issue
Block a user