Skip to content

Commit 763aada

Browse files
committed
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).
1 parent 9b2a02e commit 763aada

File tree

3 files changed

+42
-30
lines changed

3 files changed

+42
-30
lines changed

include/avian/system/system.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -176,7 +176,7 @@ inline void NO_RETURN sysAbort(System* s)
176176

177177
// #endif // not NDEBUG
178178

179-
AVIAN_EXPORT System* makeSystem();
179+
AVIAN_EXPORT System* makeSystem(bool reentrant = false);
180180

181181
} // namespace vm
182182

src/system/posix.cpp

+29-22
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ const int signals[] = {VisitSignal, InterruptSignal, PipeSignal};
9292
const unsigned SignalCount = 3;
9393

9494
class MySystem;
95-
MySystem* system;
95+
MySystem* globalSystem;
9696

9797
void handleSignal(int signal, siginfo_t* info, void* context);
9898

@@ -624,16 +624,18 @@ class MySystem : public System {
624624
System::Library* next_;
625625
};
626626

627-
MySystem() : threadVisitor(0), visitTarget(0)
627+
MySystem(bool reentrant) : reentrant(reentrant), threadVisitor(0), visitTarget(0)
628628
{
629-
expect(this, system == 0);
630-
system = this;
629+
if (not reentrant) {
630+
expect(this, globalSystem == 0);
631+
globalSystem = this;
631632

632-
expect(this, registerHandler(InterruptSignalIndex));
633-
expect(this, registerHandler(VisitSignalIndex));
634-
expect(this, registerHandler(PipeSignalIndex));
635-
636-
expect(this, make(&visitLock) == 0);
633+
expect(this, registerHandler(InterruptSignalIndex));
634+
expect(this, registerHandler(VisitSignalIndex));
635+
expect(this, registerHandler(PipeSignalIndex));
636+
637+
expect(this, make(&visitLock) == 0);
638+
}
637639
}
638640

639641
// Returns true on success, false on failure
@@ -708,6 +710,8 @@ class MySystem : public System {
708710
System::Thread* sTarget,
709711
ThreadVisitor* visitor)
710712
{
713+
expect(this, not reentrant);
714+
711715
assertT(this, st != sTarget);
712716

713717
Thread* target = static_cast<Thread*>(sTarget);
@@ -767,7 +771,7 @@ class MySystem : public System {
767771

768772
threadVisitor = 0;
769773

770-
system->visitLock->notifyAll(t);
774+
globalSystem->visitLock->notifyAll(t);
771775

772776
return result;
773777
#endif // not __APPLE__
@@ -938,18 +942,21 @@ class MySystem : public System {
938942

939943
virtual void dispose()
940944
{
941-
visitLock->dispose();
945+
if (not reentrant) {
946+
visitLock->dispose();
942947

943-
expect(this, unregisterHandler(InterruptSignalIndex));
944-
expect(this, unregisterHandler(VisitSignalIndex));
945-
expect(this, unregisterHandler(PipeSignalIndex));
946-
system = 0;
948+
expect(this, unregisterHandler(InterruptSignalIndex));
949+
expect(this, unregisterHandler(VisitSignalIndex));
950+
expect(this, unregisterHandler(PipeSignalIndex));
951+
globalSystem = 0;
952+
}
947953

948954
::free(this);
949955
}
950956

951957
struct sigaction oldHandlers[SignalCount];
952958

959+
bool reentrant;
953960
ThreadVisitor* threadVisitor;
954961
Thread* visitTarget;
955962
System::Monitor* visitLock;
@@ -965,13 +972,13 @@ void handleSignal(int signal, siginfo_t*, void* context)
965972

966973
switch (signal) {
967974
case VisitSignal: {
968-
system->threadVisitor->visit(ip, stack, link);
975+
globalSystem->threadVisitor->visit(ip, stack, link);
969976

970-
System::Thread* t = system->visitTarget;
971-
system->visitTarget = 0;
977+
System::Thread* t = globalSystem->visitTarget;
978+
globalSystem->visitTarget = 0;
972979

973-
ACQUIRE_MONITOR(t, system->visitLock);
974-
system->visitLock->notifyAll(t);
980+
ACQUIRE_MONITOR(t, globalSystem->visitLock);
981+
globalSystem->visitLock->notifyAll(t);
975982
} break;
976983

977984
case InterruptSignal:
@@ -987,9 +994,9 @@ void handleSignal(int signal, siginfo_t*, void* context)
987994

988995
namespace vm {
989996

990-
AVIAN_EXPORT System* makeSystem()
997+
AVIAN_EXPORT System* makeSystem(bool reentrant)
991998
{
992-
return new (malloc(sizeof(MySystem))) MySystem();
999+
return new (malloc(sizeof(MySystem))) MySystem(reentrant);
9931000
}
9941001

9951002
} // namespace vm

src/system/windows.cpp

+12-7
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,7 @@ class MutexResource {
115115
};
116116

117117
class MySystem;
118-
MySystem* system;
118+
MySystem* globalSystem;
119119

120120
DWORD WINAPI run(void* r)
121121
{
@@ -655,10 +655,12 @@ class MySystem : public System {
655655
System::Library* next_;
656656
};
657657

658-
MySystem()
658+
MySystem(bool reentrant): reentrant(reentrant)
659659
{
660-
expect(this, system == 0);
661-
system = this;
660+
if (not reentrant) {
661+
expect(this, globalSystem == 0);
662+
globalSystem = this;
663+
}
662664

663665
mutex = CreateMutex(0, false, 0);
664666
assertT(this, mutex);
@@ -1007,7 +1009,10 @@ class MySystem : public System {
10071009

10081010
virtual void dispose()
10091011
{
1010-
system = 0;
1012+
if (not reentrant) {
1013+
globalSystem = 0;
1014+
}
1015+
10111016
CloseHandle(mutex);
10121017
::free(this);
10131018
}
@@ -1019,9 +1024,9 @@ class MySystem : public System {
10191024

10201025
namespace vm {
10211026

1022-
AVIAN_EXPORT System* makeSystem()
1027+
AVIAN_EXPORT System* makeSystem(bool reentrant)
10231028
{
1024-
return new (malloc(sizeof(MySystem))) MySystem();
1029+
return new (malloc(sizeof(MySystem))) MySystem(reentrant);
10251030
}
10261031

10271032
} // namespace vm

0 commit comments

Comments
 (0)