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)
{
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)

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