From fe8188d3fc55d1656e908e5cd4618490d373c686 Mon Sep 17 00:00:00 2001 From: Vivien Nicolas Date: Mon, 14 Feb 2022 16:52:31 +0100 Subject: [PATCH] [Darwin] Get the ShutDown event to work --- examples/platform/linux/AppMain.cpp | 60 +++++++++++++++++++ src/app/server/Server.cpp | 23 ++++++- src/app/server/Server.h | 6 ++ .../internal/GenericPlatformManagerImpl.cpp | 11 +--- src/platform/Linux/PlatformManagerImpl.cpp | 36 ----------- 5 files changed, 89 insertions(+), 47 deletions(-) diff --git a/examples/platform/linux/AppMain.cpp b/examples/platform/linux/AppMain.cpp index ec081341465825..3108d367aa82be 100644 --- a/examples/platform/linux/AppMain.cpp +++ b/examples/platform/linux/AppMain.cpp @@ -35,6 +35,8 @@ #include #include +#include + #if CHIP_DEVICE_CONFIG_ENABLE_BOTH_COMMISSIONER_AND_COMMISSIONEE #include #include @@ -53,6 +55,8 @@ #include #endif +#include + #include "AppMain.h" using namespace chip; @@ -87,6 +91,56 @@ void EventHandler(const DeviceLayer::ChipDeviceEvent * event, intptr_t arg) ChipLogProgress(DeviceLayer, "Receive kCHIPoBLEConnectionEstablished"); } } + +void OnSignalHandler(int signum) +{ + ChipLogDetail(DeviceLayer, "Caught signal %d", signum); + + // The BootReason attribute SHALL indicate the reason for the Node’s most recent boot, the real usecase + // for this attribute is embedded system. In Linux simulation, we use different signals to tell the current + // running process to terminate with different reasons. + DiagnosticDataProvider::BootReasonType bootReason = DiagnosticDataProvider::BootReasonType::Unspecified; + switch (signum) + { + case SIGVTALRM: + bootReason = DiagnosticDataProvider::BootReasonType::PowerOnReboot; + break; + case SIGALRM: + bootReason = DiagnosticDataProvider::BootReasonType::BrownOutReset; + break; + case SIGILL: + bootReason = DiagnosticDataProvider::BootReasonType::SoftwareWatchdogReset; + break; + case SIGTRAP: + bootReason = DiagnosticDataProvider::BootReasonType::HardwareWatchdogReset; + break; + case SIGIO: + bootReason = DiagnosticDataProvider::BootReasonType::SoftwareUpdateCompleted; + break; + case SIGINT: + bootReason = DiagnosticDataProvider::BootReasonType::SoftwareReset; + break; + default: + ChipLogError(NotSpecified, "Unhandled signal: Should never happens"); + chipDie(); + break; + } + + Server::GetInstance().DispatchShutDownAndStopEventLoop(); +} + +void SetupSignalHandlers() +{ + // sigaction is not used here because Tsan interceptors seems to + // never dispatch the signals on darwin. + signal(SIGALRM, OnSignalHandler); + signal(SIGVTALRM, OnSignalHandler); + signal(SIGILL, OnSignalHandler); + signal(SIGTRAP, OnSignalHandler); + signal(SIGTERM, OnSignalHandler); + signal(SIGIO, OnSignalHandler); + signal(SIGINT, OnSignalHandler); +} } // namespace #if CHIP_DEVICE_CONFIG_ENABLE_WPA @@ -535,6 +589,8 @@ void ChipLinuxAppMainLoop() #endif // defined(ENABLE_CHIP_SHELL) #endif // CHIP_DEVICE_CONFIG_ENABLE_BOTH_COMMISSIONER_AND_COMMISSIONEE + SetupSignalHandlers(); + ApplicationInit(); DeviceLayer::PlatformMgr().RunEventLoop(); @@ -546,4 +602,8 @@ void ChipLinuxAppMainLoop() #if defined(ENABLE_CHIP_SHELL) shellThread.join(); #endif + + Server::GetInstance().Shutdown(); + + DeviceLayer::PlatformMgr().Shutdown(); } diff --git a/src/app/server/Server.cpp b/src/app/server/Server.cpp index 0fb94c8f1a90d5..80f68b3ad16b6a 100644 --- a/src/app/server/Server.cpp +++ b/src/app/server/Server.cpp @@ -66,6 +66,21 @@ constexpr bool isRendezvousBypassed() #endif } +void StopEventLoop(intptr_t arg) +{ + LogErrorOnFailure(chip::DeviceLayer::PlatformMgr().StopEventLoopTask()); +} + +void DispatchShutDownEvent(intptr_t arg) +{ + // The ShutDown event SHOULD be emitted by a Node prior to any orderly shutdown sequence. + chip::DeviceLayer::PlatformManagerDelegate * platformManagerDelegate = chip::DeviceLayer::PlatformMgr().GetDelegate(); + if (platformManagerDelegate != nullptr) + { + platformManagerDelegate->OnShutDown(); + } +} + } // namespace namespace chip { @@ -277,11 +292,17 @@ CHIP_ERROR Server::Init(AppDelegate * delegate, uint16_t secureServicePort, uint return err; } +void Server::DispatchShutDownAndStopEventLoop() +{ + chip::DeviceLayer::PlatformMgr().ScheduleWork(DispatchShutDownEvent); + chip::DeviceLayer::PlatformMgr().ScheduleWork(StopEventLoop); +} + void Server::Shutdown() { chip::Dnssd::ServiceAdvertiser::Instance().Shutdown(); chip::app::InteractionModelEngine::GetInstance()->Shutdown(); - mExchangeMgr.Shutdown(); + LogErrorOnFailure(mExchangeMgr.Shutdown()); mSessions.Shutdown(); mTransports.Close(); mCommissioningWindowManager.Shutdown(); diff --git a/src/app/server/Server.h b/src/app/server/Server.h index 5c633df9655e7e..5ea0a2c36a4f1c 100644 --- a/src/app/server/Server.h +++ b/src/app/server/Server.h @@ -87,6 +87,12 @@ class Server CommissioningWindowManager & GetCommissioningWindowManager() { return mCommissioningWindowManager; } + /** + * This function send the ShutDown event before stopping + * the event loop. + */ + void DispatchShutDownAndStopEventLoop(); + void Shutdown(); static Server & GetInstance() { return sServer; } diff --git a/src/include/platform/internal/GenericPlatformManagerImpl.cpp b/src/include/platform/internal/GenericPlatformManagerImpl.cpp index 6272f169ff0ab7..1f1f17172e059c 100644 --- a/src/include/platform/internal/GenericPlatformManagerImpl.cpp +++ b/src/include/platform/internal/GenericPlatformManagerImpl.cpp @@ -132,17 +132,8 @@ CHIP_ERROR GenericPlatformManagerImpl::_InitChipStack() template CHIP_ERROR GenericPlatformManagerImpl::_Shutdown() { - CHIP_ERROR err; - PlatformManagerDelegate * platformManagerDelegate = PlatformMgr().GetDelegate(); - - // The ShutDown event SHOULD be emitted by a Node prior to any orderly shutdown sequence. - if (platformManagerDelegate != nullptr) - { - platformManagerDelegate->OnShutDown(); - } - ChipLogError(DeviceLayer, "Inet Layer shutdown"); - err = UDPEndPointManager()->Shutdown(); + CHIP_ERROR err = UDPEndPointManager()->Shutdown(); #if CHIP_DEVICE_CONFIG_ENABLE_CHIPOBLE ChipLogError(DeviceLayer, "BLE shutdown"); diff --git a/src/platform/Linux/PlatformManagerImpl.cpp b/src/platform/Linux/PlatformManagerImpl.cpp index de7d1a343ec2e4..473653d4562c11 100644 --- a/src/platform/Linux/PlatformManagerImpl.cpp +++ b/src/platform/Linux/PlatformManagerImpl.cpp @@ -61,39 +61,10 @@ namespace { void SignalHandler(int signum) { - CHIP_ERROR err = CHIP_NO_ERROR; - ChipLogDetail(DeviceLayer, "Caught signal %d", signum); - // The BootReason attribute SHALL indicate the reason for the Node’s most recent boot, the real usecase - // for this attribute is embedded system. In Linux simulation, we use different signals to tell the current - // running process to terminate with different reasons. switch (signum) { - case SIGINT: - ConfigurationMgr().StoreBootReason(DiagnosticDataProvider::BootReasonType::SoftwareReset); - err = CHIP_ERROR_REBOOT_SIGNAL_RECEIVED; - break; - case SIGALRM: - ConfigurationMgr().StoreBootReason(DiagnosticDataProvider::BootReasonType::BrownOutReset); - err = CHIP_ERROR_REBOOT_SIGNAL_RECEIVED; - break; - case SIGVTALRM: - ConfigurationMgr().StoreBootReason(DiagnosticDataProvider::BootReasonType::PowerOnReboot); - err = CHIP_ERROR_REBOOT_SIGNAL_RECEIVED; - break; - case SIGTRAP: - ConfigurationMgr().StoreBootReason(DiagnosticDataProvider::BootReasonType::HardwareWatchdogReset); - err = CHIP_ERROR_REBOOT_SIGNAL_RECEIVED; - break; - case SIGILL: - ConfigurationMgr().StoreBootReason(DiagnosticDataProvider::BootReasonType::SoftwareWatchdogReset); - err = CHIP_ERROR_REBOOT_SIGNAL_RECEIVED; - break; - case SIGIO: - ConfigurationMgr().StoreBootReason(DiagnosticDataProvider::BootReasonType::SoftwareUpdateCompleted); - err = CHIP_ERROR_REBOOT_SIGNAL_RECEIVED; - break; case SIGUSR1: PlatformMgrImpl().HandleSoftwareFault(SoftwareDiagnostics::Events::SoftwareFault::Id); break; @@ -112,12 +83,6 @@ void SignalHandler(int signum) default: break; } - - if (err == CHIP_ERROR_REBOOT_SIGNAL_RECEIVED) - { - PlatformMgr().Shutdown(); - exit(EXIT_FAILURE); - } } #if CHIP_WITH_GIO @@ -213,7 +178,6 @@ CHIP_ERROR PlatformManagerImpl::_InitChipStack() memset(&action, 0, sizeof(action)); action.sa_handler = SignalHandler; - sigaction(SIGINT, &action, NULL); sigaction(SIGHUP, &action, NULL); sigaction(SIGTERM, &action, NULL); sigaction(SIGUSR1, &action, NULL);