Skip to content

Commit

Permalink
[Darwin] Get the ShutDown event to work
Browse files Browse the repository at this point in the history
  • Loading branch information
vivien-apple committed Feb 14, 2022
1 parent 75c7845 commit fe8188d
Show file tree
Hide file tree
Showing 5 changed files with 89 additions and 47 deletions.
60 changes: 60 additions & 0 deletions examples/platform/linux/AppMain.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@
#include <setup_payload/QRCodeSetupPayloadGenerator.h>
#include <setup_payload/SetupPayload.h>

#include <platform/DiagnosticDataProvider.h>

#if CHIP_DEVICE_CONFIG_ENABLE_BOTH_COMMISSIONER_AND_COMMISSIONEE
#include <ControllerShellCommands.h>
#include <controller/CHIPDeviceControllerFactory.h>
Expand All @@ -53,6 +55,8 @@
#include <CommonRpc.h>
#endif

#include <signal.h>

#include "AppMain.h"

using namespace chip;
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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();
Expand All @@ -546,4 +602,8 @@ void ChipLinuxAppMainLoop()
#if defined(ENABLE_CHIP_SHELL)
shellThread.join();
#endif

Server::GetInstance().Shutdown();

DeviceLayer::PlatformMgr().Shutdown();
}
23 changes: 22 additions & 1 deletion src/app/server/Server.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -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();
Expand Down
6 changes: 6 additions & 0 deletions src/app/server/Server.h
Original file line number Diff line number Diff line change
Expand Up @@ -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; }
Expand Down
11 changes: 1 addition & 10 deletions src/include/platform/internal/GenericPlatformManagerImpl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -132,17 +132,8 @@ CHIP_ERROR GenericPlatformManagerImpl<ImplClass>::_InitChipStack()
template <class ImplClass>
CHIP_ERROR GenericPlatformManagerImpl<ImplClass>::_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");
Expand Down
36 changes: 0 additions & 36 deletions src/platform/Linux/PlatformManagerImpl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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
Expand Down Expand Up @@ -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);
Expand Down

0 comments on commit fe8188d

Please sign in to comment.