summaryrefslogtreecommitdiff
path: root/library
diff options
context:
space:
mode:
authorAlexander Gavrilov2012-08-26 13:24:37 +0400
committerAlexander Gavrilov2012-08-26 14:43:14 +0400
commit3402a3cd5d473d26c115145e19f4113db51e8435 (patch)
treeda9c6f3d86823a6469a46b71fc276483d1a8748a /library
parent7f1e4b46bc102014533c015f09a20eef38aab13c (diff)
downloaddfhack-3402a3cd5d473d26c115145e19f4113db51e8435.tar.gz
dfhack-3402a3cd5d473d26c115145e19f4113db51e8435.tar.bz2
dfhack-3402a3cd5d473d26c115145e19f4113db51e8435.tar.xz
Fix a deadlock problem between suspend in (un)load, and onupdate.
Diffstat (limited to 'library')
-rw-r--r--library/PluginManager.cpp24
-rw-r--r--library/include/PluginManager.h4
2 files changed, 20 insertions, 8 deletions
diff --git a/library/PluginManager.cpp b/library/PluginManager.cpp
index d8b9ff27..ceb644e6 100644
--- a/library/PluginManager.cpp
+++ b/library/PluginManager.cpp
@@ -186,14 +186,17 @@ Plugin::~Plugin()
bool Plugin::load(color_ostream &con)
{
- RefAutolock lock(access);
- if(state == PS_BROKEN)
- {
- return false;
- }
- else if(state == PS_LOADED)
{
- return true;
+ RefAutolock lock(access);
+ if(state == PS_LOADED)
+ {
+ return true;
+ }
+ else if(state != PS_UNLOADED)
+ {
+ return false;
+ }
+ state = PS_LOADING;
}
// enter suspend
CoreSuspender suspend;
@@ -202,6 +205,7 @@ bool Plugin::load(color_ostream &con)
if(!plug)
{
con.printerr("Can't load plugin %s\n", filename.c_str());
+ RefAutolock lock(access);
state = PS_BROKEN;
return false;
}
@@ -211,6 +215,7 @@ bool Plugin::load(color_ostream &con)
{
con.printerr("Plugin %s has no name or version.\n", filename.c_str());
ClosePlugin(plug);
+ RefAutolock lock(access);
state = PS_BROKEN;
return false;
}
@@ -219,9 +224,11 @@ bool Plugin::load(color_ostream &con)
con.printerr("Plugin %s was not built for this version of DFHack.\n"
"Plugin: %s, DFHack: %s\n", *plug_name, *plug_version, DFHACK_VERSION);
ClosePlugin(plug);
+ RefAutolock lock(access);
state = PS_BROKEN;
return false;
}
+ RefAutolock lock(access);
plugin_init = (command_result (*)(color_ostream &, std::vector <PluginCommand> &)) LookupPlugin(plug, "plugin_init");
if(!plugin_init)
{
@@ -273,8 +280,11 @@ bool Plugin::unload(color_ostream &con)
}
// wait for all calls to finish
access->wait();
+ state = PS_UNLOADING;
+ access->unlock();
// enter suspend
CoreSuspender suspend;
+ access->lock();
// notify plugin about shutdown, if it has a shutdown function
command_result cr = CR_OK;
if(plugin_shutdown)
diff --git a/library/include/PluginManager.h b/library/include/PluginManager.h
index 25b05ad4..38f0e2e5 100644
--- a/library/include/PluginManager.h
+++ b/library/include/PluginManager.h
@@ -128,7 +128,9 @@ namespace DFHack
{
PS_UNLOADED,
PS_LOADED,
- PS_BROKEN
+ PS_BROKEN,
+ PS_LOADING,
+ PS_UNLOADING
};
friend class PluginManager;
friend class RPCService;