From 67cc70af1413bbf2034a9d8a84cfaf6b48f43263 Mon Sep 17 00:00:00 2001 From: Adrian Muzyka Date: Thu, 18 Apr 2024 17:34:35 +0200 Subject: [PATCH] Hibernate Abort improvements - fixed logging and return in case of late abortion - quicker for multi process plugins --- Source/WPEFramework/PluginServer.cpp | 22 ++++++++++++---------- Source/core/ProcessInfo.h | 22 +++++++++++++++++++--- Tests/unit/core/test_processinfo.cpp | 15 +++++++++++++-- 3 files changed, 44 insertions(+), 15 deletions(-) diff --git a/Source/WPEFramework/PluginServer.cpp b/Source/WPEFramework/PluginServer.cpp index 2ed4c1403c..5c954417ef 100644 --- a/Source/WPEFramework/PluginServer.cpp +++ b/Source/WPEFramework/PluginServer.cpp @@ -344,8 +344,8 @@ namespace PluginHost { Unlock(); result = Core::ERROR_ILLEGAL_STATE; } else if (currentState == IShell::state::HIBERNATED) { - Unlock(); result = Wakeup(3000); + Unlock(); } else if ((currentState == IShell::state::DEACTIVATED) || (currentState == IShell::state::PRECONDITION)) { // Load the interfaces, If we did not load them yet... @@ -531,9 +531,7 @@ namespace PluginHost { if(currentState == IShell::state::HIBERNATED) { - Unlock(); uint32_t wakeupResult = Wakeup(3000); - Lock(); if(wakeupResult != Core::ERROR_NONE) { //Force Activated state @@ -746,7 +744,13 @@ namespace PluginHost { result = Core::ERROR_NONE; #endif if (result == Core::ERROR_NONE) { - SYSLOG(Logging::Startup, (_T("Hibernated plugin [%s]:[%s]"), ClassName().c_str(), Callsign().c_str())); + if (State() == IShell::state::HIBERNATED) { + SYSLOG(Logging::Startup, ("Hibernated plugin [%s]:[%s]", ClassName().c_str(), Callsign().c_str())); + } else { + // wakeup occured right after hibernation finished + SYSLOG(Logging::Startup, ("Hibernation aborted of plugin [%s]:[%s]", ClassName().c_str(), Callsign().c_str())); + result = Core::ERROR_ABORTED; + } } else if (State() == IShell::state::HIBERNATED) { State(IShell::ACTIVATED); @@ -763,8 +767,6 @@ namespace PluginHost { uint32_t Server::Service::Wakeup(const uint32_t timeout VARIABLE_IS_NOT_USED) { Core::hresult result = Core::ERROR_NONE; - Lock(); - IShell::state currentState(State()); if (currentState != IShell::state::HIBERNATED) { @@ -798,7 +800,6 @@ namespace PluginHost { local->Release(); } } - Unlock(); return (result); } @@ -863,12 +864,13 @@ namespace PluginHost { Core::ProcessInfo::Iterator children(parentPID); if (children.Count() > 0) { - - while (children.Next()) { + // make sure to wakeup PIDs in opposite order to hibernation + // to quickly go over not hibernated PIDs and abort currently processed + children.Reset(false); + while (children.Previous()) { // Wakeup children of this process // There is no recovery path while doing Wakeup, don't care about errors WakeupChildren(children.Current().Id(), timeout); - TRACE(Activity, (_T("Wakeup of plugin [%s] child process [%u]"), Callsign().c_str(), children.Current().Id())); result = WakeupProcess(timeout, children.Current().Id(), _administrator.Configuration().HibernateLocator().c_str(), _T(""), &_hibernateStorage); } diff --git a/Source/core/ProcessInfo.h b/Source/core/ProcessInfo.h index f926654ba4..88ad4d52ed 100644 --- a/Source/core/ProcessInfo.h +++ b/Source/core/ProcessInfo.h @@ -157,10 +157,15 @@ namespace Core { { return ((_index != 0) && (_index <= _pids.size())); } - inline void Reset() + inline void Reset(bool start = true) { - _index = 0; - _current = _pids.begin(); + if (start) { + _index = 0; + _current = _pids.begin(); + } else { + _index = _pids.size() + 1; + _current = _pids.end(); + } } bool Next() { @@ -173,6 +178,17 @@ namespace Core { } return (_index <= _pids.size()); } + bool Previous() + { + if (_index > 0) { + _index--; + + if (_index > 1) { + _current--; + } + } + return (_index > 0); + } inline ProcessInfo Current() const { ASSERT(IsValid() == true); diff --git a/Tests/unit/core/test_processinfo.cpp b/Tests/unit/core/test_processinfo.cpp index 588e826f89..b376d8b677 100644 --- a/Tests/unit/core/test_processinfo.cpp +++ b/Tests/unit/core/test_processinfo.cpp @@ -39,11 +39,22 @@ TEST(Core_ProcessInfo, simpleSet) std::cout << "Size Resident :" << (processInfo.Resident() >> 10) << " KB" << std::endl; std::cout << "Size Shared :" << (processInfo.Shared() >> 10) << " KB" << std::endl; - Core::ProcessInfo::Iterator childIterator = processInfo.Children(); + Core::ProcessInfo::Iterator childIterator = Core::ProcessInfo(0).Children(); - std::cout << "Children (" << childIterator.Count() << ") " << std::endl; + childIterator.Reset(false); + std::list pids; + std::cout << "Children of PID 0 (" << childIterator.Count() << ") in revers order" << std::endl; + while (childIterator.Previous()) { + Core::ProcessInfo childProcessInfo = childIterator.Current(); + std::cout << "\tName : " << childProcessInfo.Name() << " (" << childProcessInfo.Id() << "): " << childProcessInfo.Resident() << std::endl; + pids.push_front(childProcessInfo.Id()); + } + + std::cout << "Children of PID 0 (" << childIterator.Count() << ") " << std::endl; while (childIterator.Next()) { Core::ProcessInfo childProcessInfo = childIterator.Current(); std::cout << "\tName : " << childProcessInfo.Name() << " (" << childProcessInfo.Id() << "): " << childProcessInfo.Resident() << std::endl; + EXPECT_EQ(childProcessInfo.Id(),pids.front()); + pids.pop_front(); } }