diff options
| author | Petr Mrázek | 2012-03-15 15:40:35 +0100 |
|---|---|---|
| committer | Petr Mrázek | 2012-03-15 15:40:35 +0100 |
| commit | e5efbc589525d34c5205065514f82a054a92a128 (patch) | |
| tree | 5fedc21c55a60db7b0d7261f21b0a9a424a405be /library/Core.cpp | |
| parent | 1ac8025025a2368d7a6b0e1b74ab7babd8c932bc (diff) | |
| parent | 4eb481177737fe47cda80808dc4a62bd864a15e0 (diff) | |
| download | dfhack-e5efbc589525d34c5205065514f82a054a92a128.tar.gz dfhack-e5efbc589525d34c5205065514f82a054a92a128.tar.bz2 dfhack-e5efbc589525d34c5205065514f82a054a92a128.tar.xz | |
Merge https://github.com/angavrilov/dfhack
Diffstat (limited to 'library/Core.cpp')
| -rw-r--r-- | library/Core.cpp | 95 |
1 files changed, 67 insertions, 28 deletions
diff --git a/library/Core.cpp b/library/Core.cpp index c374e9f1..2e67fcb3 100644 --- a/library/Core.cpp +++ b/library/Core.cpp @@ -104,6 +104,20 @@ struct Core::Cond 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) { string *cur = NULL; @@ -576,6 +590,8 @@ void fIOthread(void * iodata) Core::Core() { + d = new Private(); + // init the console. This must be always the first step! plug_mgr = 0; vif = 0; @@ -585,10 +601,6 @@ Core::Core() started = false; 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 hotkey_set = false; HotkeyMutex = 0; @@ -687,10 +699,7 @@ bool Core::Init() df::global::InitGlobals(); // create mutex for syncing with interactive tasks - StackMutex = new mutex(); - AccessMutex = new mutex(); misc_data_mutex=new mutex(); - core_cond = new Core::Cond(); cerr << "Initializing Plugins.\n"; // create plugin manager plug_mgr = new PluginManager(this); @@ -783,22 +792,49 @@ void *Core::GetData( std::string key ) 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 - StackMutex->lock(); - suspended_tools.push(nc); - StackMutex->unlock(); + Core::Cond *nc = new Core::Cond(); + + { + lock_guard<mutex> lock2(d->StackMutex); + + d->suspended_tools.push(nc); + } + // wait until Core::Update() wakes up the tool - AccessMutex->lock(); - nc->Lock(AccessMutex); - AccessMutex->unlock(); + { + lock_guard<mutex> lock(d->AccessMutex); + + nc->Lock(&d->AccessMutex); + + assert(d->df_suspend_depth == 0); + d->df_suspend_thread = tid; + d->df_suspend_depth = 1; + } } void Core::Resume() { - AccessMutex->lock(); - core_cond->Unlock(); - AccessMutex->unlock(); + auto tid = this_thread::get_id(); + lock_guard<mutex> lock(d->AccessMutex); + + assert(d->df_suspend_depth > 0 && d->df_suspend_thread == tid); + + if (--d->df_suspend_depth == 0) + d->core_cond.Unlock(); } int Core::TileUpdate() @@ -853,21 +889,24 @@ int Core::Update() // wake waiting tools // do not allow more tools to join in while we process stuff here - StackMutex->lock(); - while (!suspended_tools.empty()) + lock_guard<mutex> lock_stack(d->StackMutex); + + while (!d->suspended_tools.empty()) { - Core::Cond * nc = suspended_tools.top(); - suspended_tools.pop(); - AccessMutex->lock(); - // wake tool - nc->Unlock(); - // wait for tool to wake us - core_cond->Lock(AccessMutex); - AccessMutex->unlock(); + Core::Cond * nc = d->suspended_tools.top(); + d->suspended_tools.pop(); + + lock_guard<mutex> lock(d->AccessMutex); + // wake tool + nc->Unlock(); + // wait for tool to wake us + d->core_cond.Lock(&d->AccessMutex); + // verify + assert(d->df_suspend_depth == 0); // destroy condition delete nc; } - StackMutex->unlock(); + return 0; }; |
