| 1441 | } |
| 1442 | |
| 1443 | bool CPluginManager::UnloadPlugin(IPlugin *plugin) |
| 1444 | { |
| 1445 | CPlugin *pPlugin = (CPlugin *)plugin; |
| 1446 | |
| 1447 | // Should not be recursively removing. |
| 1448 | assert(m_plugins.contains(pPlugin)); |
| 1449 | |
| 1450 | // If we're already in the unload queue, just wait. |
| 1451 | if (pPlugin->State() == PluginState::WaitingToUnload || |
| 1452 | pPlugin->State() == PluginState::WaitingToUnloadAndReload) |
| 1453 | { |
| 1454 | return false; |
| 1455 | } |
| 1456 | |
| 1457 | // It is not safe to unload any plugin while another is on the callstack. |
| 1458 | bool any_active = false; |
| 1459 | for (PluginIter iter(m_plugins); !iter.done(); iter.next()) { |
| 1460 | if (IPluginContext *context = (*iter)->GetBaseContext()) { |
| 1461 | if (context->IsInExec()) { |
| 1462 | any_active = true; |
| 1463 | break; |
| 1464 | } |
| 1465 | } |
| 1466 | } |
| 1467 | |
| 1468 | if (any_active) { |
| 1469 | pPlugin->SetWaitingToUnload(); |
| 1470 | ScheduleTaskForNextFrame([this, pPlugin]() -> void { |
| 1471 | UnloadPluginImpl(pPlugin); |
| 1472 | }); |
| 1473 | return false; |
| 1474 | } |
| 1475 | |
| 1476 | // No need to schedule an unload, we can unload immediately. |
| 1477 | UnloadPluginImpl(pPlugin); |
| 1478 | return true; |
| 1479 | } |
| 1480 | |
| 1481 | void CPluginManager::Purge(CPlugin *plugin) |
| 1482 | { |
no test coverage detected