task cleanup and add some volatiles which i reasoned were necessary

This commit is contained in:
zeromus 2016-08-23 23:32:44 +00:00
parent 07e3612e4d
commit 166365ab0d
1 changed files with 25 additions and 21 deletions

View File

@ -1,5 +1,5 @@
/* /*
Copyright (C) 2009-2015 DeSmuME team Copyright (C) 2009-2016 DeSmuME team
This file is free software: you can redistribute it and/or modify This file is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
@ -16,6 +16,7 @@
*/ */
#include <stdio.h> #include <stdio.h>
#include <assert.h>
#include "types.h" #include "types.h"
#include "task.h" #include "task.h"
@ -71,11 +72,10 @@ public:
slock_t *mutex; slock_t *mutex;
scond_t *workCond; scond_t *workCond;
bool workFlag, finishFlag; volatile bool workFlag, finishFlag, exitFlag;
TWork workFunc; volatile TWork workFunc;
void *workFuncParam; void * volatile workFuncParam;
void *ret; void * volatile ret;
bool exitThread;
bool started; bool started;
}; };
@ -102,21 +102,20 @@ void Task::Impl::taskProc()
slock_unlock(mutex); slock_unlock(mutex);
if(exitThread) if(exitFlag)
break; break;
} }
} }
static void* killTask(void* task) static void* killTask(void* task)
{ {
((Task::Impl*)task)->exitThread = true; ((Task::Impl*)task)->exitFlag = true;
return 0; return NULL;
} }
Task::Impl::Impl() Task::Impl::Impl()
: started(false) : started(false)
{ {
} }
Task::Impl::~Impl() Task::Impl::~Impl()
@ -129,16 +128,20 @@ void Task::Impl::initialize()
thread = NULL; thread = NULL;
workFunc = NULL; workFunc = NULL;
workCond = NULL; workCond = NULL;
workFlag = finishFlag = false;
workFunc = NULL; workFunc = NULL;
workFuncParam = NULL; workFuncParam = NULL;
workFlag = finishFlag = exitFlag = false;
ret = NULL; ret = NULL;
exitThread = false;
started = false; started = false;
} }
void Task::Impl::start(bool spinlock) void Task::Impl::start(bool spinlock)
{ {
//check user error
assert(!started);
if(started) shutdown();
initialize(); initialize();
mutex = slock_new(); mutex = slock_new();
workCond = scond_new(); workCond = scond_new();
@ -155,20 +158,26 @@ void Task::Impl::shutdown()
{ {
if(!started) return; if(!started) return;
finish(); // Ensure that any previous tasks are finished before calling killTask(). //nobody should shutdown while a task is still running;
//it would imply that we're in some kind of shutdown pricess, and datastructures might be getting freed while someone is still working on it
//nonetheless, _troublingly_, it seems like we do that now, so for now let's try to let that work finish instead of blowing up when it isn't finished
//assert(!workFunc);
finish();
//a new task which sets the kill flag
execute(killTask,this); execute(killTask,this);
finish(); finish();
started = false; started = false;
sthread_join(thread); sthread_join(thread);
slock_free(mutex);
scond_free(workCond); scond_free(workCond);
slock_free(mutex);
} }
void* Task::Impl::finish() void* Task::Impl::finish()
{ {
//no work running; nothing to do (it's kind of lame that we call this under the circumstances) //no work running; nothing to do
if(!workFunc) if(!workFunc)
return NULL; return NULL;
@ -197,15 +206,10 @@ void Task::Impl::execute(const TWork &work, void *param)
slock_unlock(this->mutex); slock_unlock(this->mutex);
} }
void Task::start(bool spinlock) { impl->start(spinlock); } void Task::start(bool spinlock) { impl->start(spinlock); }
void Task::shutdown() { impl->shutdown(); } void Task::shutdown() { impl->shutdown(); }
Task::Task() : impl(new Task::Impl()) {} Task::Task() : impl(new Task::Impl()) {}
Task::~Task() Task::~Task() { delete impl; }
{
delete impl;
}
void Task::execute(const TWork &work, void* param) { impl->execute(work,param); } void Task::execute(const TWork &work, void* param) { impl->execute(work,param); }
void* Task::finish() { return impl->finish(); } void* Task::finish() { return impl->finish(); }