Added protection against running terminated threads.
A bool is set when a thread is terminated, which may help detect it. A cached version of the thread's pid is also kept around. And lastly, the thread is unsubscribed from events upon destruction.
This commit is contained in:
parent
f6f0d24b5c
commit
9bcfdad174
|
@ -61,7 +61,24 @@ namespace Sortix
|
|||
waiting->event = NULL;
|
||||
Syscall::ScheduleResumption(waiting);
|
||||
waiting = waiting->eventnextwaiting;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: Okay, I realize this is O(N), refactor this to a linked list.
|
||||
void Event::Unregister(Thread* thread)
|
||||
{
|
||||
if ( thread->event != this ) { return; }
|
||||
thread->event = NULL;
|
||||
if ( waiting == thread ) { waiting = thread->eventnextwaiting; return; }
|
||||
for ( Thread* tmp = waiting; tmp; tmp = tmp->eventnextwaiting )
|
||||
{
|
||||
if ( tmp->eventnextwaiting == thread )
|
||||
{
|
||||
tmp->eventnextwaiting = thread->eventnextwaiting;
|
||||
break;
|
||||
}
|
||||
}
|
||||
thread->eventnextwaiting = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -38,6 +38,7 @@ namespace Sortix
|
|||
public:
|
||||
void Register();
|
||||
void Signal();
|
||||
void Unregister(Thread* thread);
|
||||
|
||||
private:
|
||||
Thread* waiting;
|
||||
|
|
|
@ -134,6 +134,7 @@ namespace Sortix
|
|||
|
||||
Thread* nextthread = PopNextThread();
|
||||
if ( !nextthread ) { Panic("had no thread to switch to"); }
|
||||
if ( nextthread->terminated ) { PanicF("Running a terminated thread 0x%p", nextthread); }
|
||||
|
||||
LogContextSwitch(currentthread, nextthread);
|
||||
if ( nextthread == currentthread ) { return; }
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
#include "platform.h"
|
||||
#include <libmaxsi/error.h>
|
||||
#include <libmaxsi/memory.h>
|
||||
#include "event.h"
|
||||
#include "process.h"
|
||||
#include "thread.h"
|
||||
#include "scheduler.h"
|
||||
|
@ -54,6 +55,8 @@ namespace Sortix
|
|||
scfunc = NULL;
|
||||
currentsignal = NULL;
|
||||
sighandler = NULL;
|
||||
pidbackup = -1;
|
||||
terminated = false;
|
||||
ResetCallbacks();
|
||||
}
|
||||
|
||||
|
@ -76,6 +79,8 @@ namespace Sortix
|
|||
schedulerlistnext = NULL;
|
||||
scfunc = NULL;
|
||||
sighandler = forkfrom->sighandler;
|
||||
pidbackup = -1;
|
||||
terminated = false;
|
||||
ResetCallbacks();
|
||||
}
|
||||
|
||||
|
@ -89,6 +94,8 @@ namespace Sortix
|
|||
ASSERT(CurrentProcess() == process);
|
||||
ASSERT(nextsleepingthread == NULL);
|
||||
|
||||
if ( event ) { event->Unregister(this); }
|
||||
|
||||
// Delete information about signals being processed.
|
||||
while ( currentsignal )
|
||||
{
|
||||
|
@ -98,6 +105,8 @@ namespace Sortix
|
|||
}
|
||||
|
||||
Memory::UnmapRangeUser(stackpos, stacksize);
|
||||
|
||||
terminated = true;
|
||||
}
|
||||
|
||||
Thread* Thread::Fork()
|
||||
|
@ -180,6 +189,8 @@ namespace Sortix
|
|||
if ( ready ) { return; }
|
||||
ready = true;
|
||||
|
||||
this->pidbackup = process->pid;
|
||||
|
||||
if ( Time::MicrosecondsSinceBoot() < sleepuntil )
|
||||
{
|
||||
uintmax_t howlong = sleepuntil - Time::MicrosecondsSinceBoot();
|
||||
|
|
|
@ -60,6 +60,8 @@ namespace Sortix
|
|||
public:
|
||||
size_t id;
|
||||
Process* process;
|
||||
pid_t pidbackup;
|
||||
bool terminated;
|
||||
Thread* prevsibling;
|
||||
Thread* nextsibling;
|
||||
|
||||
|
|
Loading…
Reference in New Issue