|
|
@ -104,6 +104,20 @@ struct Core::Cond
|
|
|
|
bool predicate;
|
|
|
|
bool predicate;
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
struct Core::Private
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
tthread::mutex AccessMutex;
|
|
|
|
|
|
|
|
tthread::mutex StackMutex;
|
|
|
|
|
|
|
|
std::stack<Core::Cond*> suspended_tools;
|
|
|
|
|
|
|
|
Core::Cond core_cond;
|
|
|
|
|
|
|
|
thread::id df_suspend_thread;
|
|
|
|
|
|
|
|
int df_suspend_depth;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Private() {
|
|
|
|
|
|
|
|
df_suspend_depth = 0;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
void cheap_tokenise(string const& input, vector<string> &output)
|
|
|
|
void cheap_tokenise(string const& input, vector<string> &output)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
string *cur = NULL;
|
|
|
|
string *cur = NULL;
|
|
|
@ -576,6 +590,8 @@ void fIOthread(void * iodata)
|
|
|
|
|
|
|
|
|
|
|
|
Core::Core()
|
|
|
|
Core::Core()
|
|
|
|
{
|
|
|
|
{
|
|
|
|
|
|
|
|
d = new Private();
|
|
|
|
|
|
|
|
|
|
|
|
// init the console. This must be always the first step!
|
|
|
|
// init the console. This must be always the first step!
|
|
|
|
plug_mgr = 0;
|
|
|
|
plug_mgr = 0;
|
|
|
|
vif = 0;
|
|
|
|
vif = 0;
|
|
|
@ -585,10 +601,6 @@ Core::Core()
|
|
|
|
started = false;
|
|
|
|
started = false;
|
|
|
|
memset(&(s_mods), 0, sizeof(s_mods));
|
|
|
|
memset(&(s_mods), 0, sizeof(s_mods));
|
|
|
|
|
|
|
|
|
|
|
|
// create mutex for syncing with interactive tasks
|
|
|
|
|
|
|
|
AccessMutex = 0;
|
|
|
|
|
|
|
|
StackMutex = 0;
|
|
|
|
|
|
|
|
core_cond = 0;
|
|
|
|
|
|
|
|
// set up hotkey capture
|
|
|
|
// set up hotkey capture
|
|
|
|
hotkey_set = false;
|
|
|
|
hotkey_set = false;
|
|
|
|
HotkeyMutex = 0;
|
|
|
|
HotkeyMutex = 0;
|
|
|
@ -687,10 +699,7 @@ bool Core::Init()
|
|
|
|
df::global::InitGlobals();
|
|
|
|
df::global::InitGlobals();
|
|
|
|
|
|
|
|
|
|
|
|
// create mutex for syncing with interactive tasks
|
|
|
|
// create mutex for syncing with interactive tasks
|
|
|
|
StackMutex = new mutex();
|
|
|
|
|
|
|
|
AccessMutex = new mutex();
|
|
|
|
|
|
|
|
misc_data_mutex=new mutex();
|
|
|
|
misc_data_mutex=new mutex();
|
|
|
|
core_cond = new Core::Cond();
|
|
|
|
|
|
|
|
cerr << "Initializing Plugins.\n";
|
|
|
|
cerr << "Initializing Plugins.\n";
|
|
|
|
// create plugin manager
|
|
|
|
// create plugin manager
|
|
|
|
plug_mgr = new PluginManager(this);
|
|
|
|
plug_mgr = new PluginManager(this);
|
|
|
@ -783,22 +792,49 @@ void *Core::GetData( std::string key )
|
|
|
|
|
|
|
|
|
|
|
|
void Core::Suspend()
|
|
|
|
void Core::Suspend()
|
|
|
|
{
|
|
|
|
{
|
|
|
|
Core::Cond * nc = new Core::Cond();
|
|
|
|
auto tid = this_thread::get_id();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// If recursive, just increment the count
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
lock_guard<mutex> lock(d->AccessMutex);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (d->df_suspend_depth > 0 && d->df_suspend_thread == tid)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
d->df_suspend_depth++;
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// put the condition on a stack
|
|
|
|
// put the condition on a stack
|
|
|
|
StackMutex->lock();
|
|
|
|
Core::Cond *nc = new Core::Cond();
|
|
|
|
suspended_tools.push(nc);
|
|
|
|
|
|
|
|
StackMutex->unlock();
|
|
|
|
{
|
|
|
|
|
|
|
|
lock_guard<mutex> lock2(d->StackMutex);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
d->suspended_tools.push(nc);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// wait until Core::Update() wakes up the tool
|
|
|
|
// wait until Core::Update() wakes up the tool
|
|
|
|
AccessMutex->lock();
|
|
|
|
{
|
|
|
|
nc->Lock(AccessMutex);
|
|
|
|
lock_guard<mutex> lock(d->AccessMutex);
|
|
|
|
AccessMutex->unlock();
|
|
|
|
|
|
|
|
|
|
|
|
nc->Lock(&d->AccessMutex);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
assert(d->df_suspend_depth == 0);
|
|
|
|
|
|
|
|
d->df_suspend_thread = tid;
|
|
|
|
|
|
|
|
d->df_suspend_depth = 1;
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void Core::Resume()
|
|
|
|
void Core::Resume()
|
|
|
|
{
|
|
|
|
{
|
|
|
|
AccessMutex->lock();
|
|
|
|
auto tid = this_thread::get_id();
|
|
|
|
core_cond->Unlock();
|
|
|
|
lock_guard<mutex> lock(d->AccessMutex);
|
|
|
|
AccessMutex->unlock();
|
|
|
|
|
|
|
|
|
|
|
|
assert(d->df_suspend_depth > 0 && d->df_suspend_thread == tid);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (--d->df_suspend_depth == 0)
|
|
|
|
|
|
|
|
d->core_cond.Unlock();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
int Core::TileUpdate()
|
|
|
|
int Core::TileUpdate()
|
|
|
@ -853,21 +889,24 @@ int Core::Update()
|
|
|
|
|
|
|
|
|
|
|
|
// wake waiting tools
|
|
|
|
// wake waiting tools
|
|
|
|
// do not allow more tools to join in while we process stuff here
|
|
|
|
// do not allow more tools to join in while we process stuff here
|
|
|
|
StackMutex->lock();
|
|
|
|
lock_guard<mutex> lock_stack(d->StackMutex);
|
|
|
|
while (!suspended_tools.empty())
|
|
|
|
|
|
|
|
|
|
|
|
while (!d->suspended_tools.empty())
|
|
|
|
{
|
|
|
|
{
|
|
|
|
Core::Cond * nc = suspended_tools.top();
|
|
|
|
Core::Cond * nc = d->suspended_tools.top();
|
|
|
|
suspended_tools.pop();
|
|
|
|
d->suspended_tools.pop();
|
|
|
|
AccessMutex->lock();
|
|
|
|
|
|
|
|
// wake tool
|
|
|
|
lock_guard<mutex> lock(d->AccessMutex);
|
|
|
|
nc->Unlock();
|
|
|
|
// wake tool
|
|
|
|
// wait for tool to wake us
|
|
|
|
nc->Unlock();
|
|
|
|
core_cond->Lock(AccessMutex);
|
|
|
|
// wait for tool to wake us
|
|
|
|
AccessMutex->unlock();
|
|
|
|
d->core_cond.Lock(&d->AccessMutex);
|
|
|
|
|
|
|
|
// verify
|
|
|
|
|
|
|
|
assert(d->df_suspend_depth == 0);
|
|
|
|
// destroy condition
|
|
|
|
// destroy condition
|
|
|
|
delete nc;
|
|
|
|
delete nc;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
StackMutex->unlock();
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
return 0;
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|