| 395 | } |
| 396 | |
| 397 | bool Plugin::unload(color_ostream &con) |
| 398 | { |
| 399 | // get the mutex |
| 400 | access->lock(); |
| 401 | // if we are actually loaded |
| 402 | if (state == PS_LOADED) |
| 403 | { |
| 404 | if (Screen::hasActiveScreens(this)) |
| 405 | { |
| 406 | con.printerr("Cannot unload plugin {}: has active viewscreens\n", name); |
| 407 | access->unlock(); |
| 408 | return false; |
| 409 | } |
| 410 | EventManager::unregisterAll(this); |
| 411 | // notify the plugin about an attempt to shutdown |
| 412 | if (plugin_onstatechange && |
| 413 | plugin_onstatechange(con, SC_BEGIN_UNLOAD) != CR_OK) |
| 414 | { |
| 415 | con.printerr("Plugin {} has refused to be unloaded.\n", name); |
| 416 | access->unlock(); |
| 417 | return false; |
| 418 | } |
| 419 | // wait for all calls to finish |
| 420 | access->wait(); |
| 421 | state = PS_UNLOADING; |
| 422 | // only attempt to unload site or world data if the core is in a valid state |
| 423 | if (Core::getInstance().isValid()) |
| 424 | { |
| 425 | // enter suspend |
| 426 | access->unlock(); |
| 427 | { |
| 428 | CoreSuspender suspend; |
| 429 | access->lock(); |
| 430 | if (Core::getInstance().isMapLoaded() && plugin_save_site_data && World::IsSiteLoaded() && plugin_save_site_data(con) != CR_OK) |
| 431 | con.printerr("Plugin {} has failed to save site data.\n", name); |
| 432 | if (Core::getInstance().isWorldLoaded() && plugin_save_world_data && plugin_save_world_data(con) != CR_OK) |
| 433 | con.printerr("Plugin {} has failed to save world data.\n", name); |
| 434 | // holding the access lock while releasing the CoreSuspender creates a deadlock risk |
| 435 | access->unlock(); |
| 436 | } |
| 437 | access->lock(); |
| 438 | } |
| 439 | // notify plugin about shutdown, if it has a shutdown function |
| 440 | command_result cr = CR_OK; |
| 441 | if(plugin_shutdown) |
| 442 | cr = plugin_shutdown(con); |
| 443 | // cleanup... |
| 444 | plugin_is_enabled = 0; |
| 445 | plugin_onupdate = 0; |
| 446 | plugin_save_world_data = 0; |
| 447 | plugin_save_site_data = 0; |
| 448 | plugin_load_world_data = 0; |
| 449 | plugin_load_site_data = 0; |
| 450 | reset_lua(); |
| 451 | parent->unregisterCommands(this); |
| 452 | commands.clear(); |
| 453 | |
| 454 | bool closed_safely = (cr == CR_OK) && ClosePlugin(plugin_lib); |
no test coverage detected