[AllClusters] If opened multiple times and something fails in Init, closing the app with Ctrl^C makes it crashes (#35844)
* [InteractionModelEngine] Add some checks to Shutdown to prevent crashing if someone calls Shutdown before Init
* [CommissioningWindowManager] Ensure Shutdown does nothing if Init has not been called
diff --git a/src/app/InteractionModelEngine.cpp b/src/app/InteractionModelEngine.cpp
index b122333..59888fe 100644
--- a/src/app/InteractionModelEngine.cpp
+++ b/src/app/InteractionModelEngine.cpp
@@ -89,6 +89,7 @@
VerifyOrReturnError(apExchangeMgr != nullptr, CHIP_ERROR_INVALID_ARGUMENT);
VerifyOrReturnError(reportScheduler != nullptr, CHIP_ERROR_INVALID_ARGUMENT);
+ mState = State::kInitializing;
mpExchangeMgr = apExchangeMgr;
mpFabricTable = apFabricTable;
mpCASESessionMgr = apCASESessionMgr;
@@ -111,11 +112,14 @@
ChipLogError(InteractionModel, "WARNING └────────────────────────────────────────────────────");
#endif
+ mState = State::kInitialized;
return CHIP_NO_ERROR;
}
void InteractionModelEngine::Shutdown()
{
+ VerifyOrReturn(State::kUninitialized != mState);
+
mpExchangeMgr->GetSessionManager()->SystemLayer()->CancelTimer(ResumeSubscriptionsTimerCallback, this);
// TODO: individual object clears the entire command handler interface registry.
@@ -187,6 +191,8 @@
//
// mpFabricTable = nullptr;
// mpExchangeMgr = nullptr;
+
+ mState = State::kUninitialized;
}
uint32_t InteractionModelEngine::GetNumActiveReadHandlers() const
diff --git a/src/app/InteractionModelEngine.h b/src/app/InteractionModelEngine.h
index ba0a099..b52b4eb 100644
--- a/src/app/InteractionModelEngine.h
+++ b/src/app/InteractionModelEngine.h
@@ -713,6 +713,14 @@
DataModel::Provider * mDataModelProvider = nullptr;
Messaging::ExchangeContext * mCurrentExchange = nullptr;
+ enum class State : uint8_t
+ {
+ kUninitialized, // The object has not been initialized.
+ kInitializing, // Initial setup is in progress (e.g. setting up mpExchangeMgr).
+ kInitialized // The object has been fully initialized and is ready for use.
+ };
+ State mState = State::kUninitialized;
+
// Changes the current exchange context of a InteractionModelEngine to a given context
class CurrentExchangeValueScope
{
diff --git a/src/app/server/CommissioningWindowManager.cpp b/src/app/server/CommissioningWindowManager.cpp
index 110a729..2a8611b 100644
--- a/src/app/server/CommissioningWindowManager.cpp
+++ b/src/app/server/CommissioningWindowManager.cpp
@@ -111,6 +111,8 @@
void CommissioningWindowManager::Shutdown()
{
+ VerifyOrReturn(nullptr != mServer);
+
StopAdvertisement(/* aShuttingDown = */ true);
ResetState();