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:
Jonas 'Sortie' Termansen 2012-02-10 13:27:11 +01:00
parent f6f0d24b5c
commit 9bcfdad174
5 changed files with 33 additions and 1 deletions

View File

@ -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;
}
}

View File

@ -38,6 +38,7 @@ namespace Sortix
public:
void Register();
void Signal();
void Unregister(Thread* thread);
private:
Thread* waiting;

View File

@ -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; }

View File

@ -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();

View File

@ -60,6 +60,8 @@ namespace Sortix
public:
size_t id;
Process* process;
pid_t pidbackup;
bool terminated;
Thread* prevsibling;
Thread* nextsibling;