Fix a deadlock problem between suspend in (un)load, and onupdate.

develop
Alexander Gavrilov 2012-08-26 13:24:37 +04:00
parent 7f1e4b46bc
commit 3402a3cd5d
2 changed files with 20 additions and 8 deletions

@ -186,14 +186,17 @@ Plugin::~Plugin()
bool Plugin::load(color_ostream &con) 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 // enter suspend
CoreSuspender suspend; CoreSuspender suspend;
@ -202,6 +205,7 @@ bool Plugin::load(color_ostream &con)
if(!plug) if(!plug)
{ {
con.printerr("Can't load plugin %s\n", filename.c_str()); con.printerr("Can't load plugin %s\n", filename.c_str());
RefAutolock lock(access);
state = PS_BROKEN; state = PS_BROKEN;
return false; 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()); con.printerr("Plugin %s has no name or version.\n", filename.c_str());
ClosePlugin(plug); ClosePlugin(plug);
RefAutolock lock(access);
state = PS_BROKEN; state = PS_BROKEN;
return false; 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" con.printerr("Plugin %s was not built for this version of DFHack.\n"
"Plugin: %s, DFHack: %s\n", *plug_name, *plug_version, DFHACK_VERSION); "Plugin: %s, DFHack: %s\n", *plug_name, *plug_version, DFHACK_VERSION);
ClosePlugin(plug); ClosePlugin(plug);
RefAutolock lock(access);
state = PS_BROKEN; state = PS_BROKEN;
return false; return false;
} }
RefAutolock lock(access);
plugin_init = (command_result (*)(color_ostream &, std::vector <PluginCommand> &)) LookupPlugin(plug, "plugin_init"); plugin_init = (command_result (*)(color_ostream &, std::vector <PluginCommand> &)) LookupPlugin(plug, "plugin_init");
if(!plugin_init) if(!plugin_init)
{ {
@ -273,8 +280,11 @@ bool Plugin::unload(color_ostream &con)
} }
// wait for all calls to finish // wait for all calls to finish
access->wait(); access->wait();
state = PS_UNLOADING;
access->unlock();
// enter suspend // enter suspend
CoreSuspender suspend; CoreSuspender suspend;
access->lock();
// notify plugin about shutdown, if it has a shutdown function // notify plugin about shutdown, if it has a shutdown function
command_result cr = CR_OK; command_result cr = CR_OK;
if(plugin_shutdown) if(plugin_shutdown)

@ -128,7 +128,9 @@ namespace DFHack
{ {
PS_UNLOADED, PS_UNLOADED,
PS_LOADED, PS_LOADED,
PS_BROKEN PS_BROKEN,
PS_LOADING,
PS_UNLOADING
}; };
friend class PluginManager; friend class PluginManager;
friend class RPCService; friend class RPCService;