diff --git a/src/inet/InetLayer.cpp b/src/inet/InetLayer.cpp index ca80bdc08cff5d..c5f67d455b18d1 100644 --- a/src/inet/InetLayer.cpp +++ b/src/inet/InetLayer.cpp @@ -101,8 +101,6 @@ void InetLayer::UpdateSnapshot(chip::System::Stats::Snapshot & aSnapshot) */ InetLayer::InetLayer() { - State = kState_NotInitialized; - #if CHIP_SYSTEM_CONFIG_USE_LWIP if (!sInetEventHandlerDelegate.IsInitialized()) sInetEventHandlerDelegate.Init(HandleInetLayerEvent); @@ -237,9 +235,7 @@ void InetLayer::DroppableEventDequeued(void) CHIP_ERROR InetLayer::Init(chip::System::Layer & aSystemLayer, void * aContext) { Inet::RegisterLayerErrorFormatter(); - - if (State != kState_NotInitialized) - return CHIP_ERROR_INCORRECT_STATE; + VerifyOrReturnError(mLayerState.SetInitializing(), CHIP_ERROR_INCORRECT_STATE); // Platform-specific initialization may elect to set this data // member. Ensure it is set to a sane default value before @@ -256,7 +252,7 @@ CHIP_ERROR InetLayer::Init(chip::System::Layer & aSystemLayer, void * aContext) static_cast(mSystemLayer)->AddEventHandlerDelegate(sInetEventHandlerDelegate); #endif // CHIP_SYSTEM_CONFIG_USE_LWIP - State = kState_Initialized; + mLayerState.SetInitialized(); return CHIP_NO_ERROR; } @@ -271,35 +267,34 @@ CHIP_ERROR InetLayer::Init(chip::System::Layer & aSystemLayer, void * aContext) */ CHIP_ERROR InetLayer::Shutdown() { + VerifyOrReturnError(mLayerState.SetShuttingDown(), CHIP_ERROR_INCORRECT_STATE); + CHIP_ERROR err = CHIP_NO_ERROR; - if (State == kState_Initialized) - { #if INET_CONFIG_ENABLE_TCP_ENDPOINT - // Abort all TCP endpoints owned by this instance. - TCPEndPoint::sPool.ForEachActiveObject([&](TCPEndPoint * lEndPoint) { - if ((lEndPoint != nullptr) && lEndPoint->IsCreatedByInetLayer(*this)) - { - lEndPoint->Abort(); - } - return true; - }); + // Abort all TCP endpoints owned by this instance. + TCPEndPoint::sPool.ForEachActiveObject([&](TCPEndPoint * lEndPoint) { + if ((lEndPoint != nullptr) && lEndPoint->IsCreatedByInetLayer(*this)) + { + lEndPoint->Abort(); + } + return true; + }); #endif // INET_CONFIG_ENABLE_TCP_ENDPOINT #if INET_CONFIG_ENABLE_UDP_ENDPOINT - // Close all UDP endpoints owned by this instance. - UDPEndPoint::sPool.ForEachActiveObject([&](UDPEndPoint * lEndPoint) { - if ((lEndPoint != nullptr) && lEndPoint->IsCreatedByInetLayer(*this)) - { - lEndPoint->Close(); - } - return true; - }); + // Close all UDP endpoints owned by this instance. + UDPEndPoint::sPool.ForEachActiveObject([&](UDPEndPoint * lEndPoint) { + if ((lEndPoint != nullptr) && lEndPoint->IsCreatedByInetLayer(*this)) + { + lEndPoint->Close(); + } + return true; + }); #endif // INET_CONFIG_ENABLE_UDP_ENDPOINT - } - - State = kState_NotInitialized; + mLayerState.SetShutdown(); + mLayerState.Reset(); // Return to uninitialized state to permit re-initialization. return err; } @@ -455,7 +450,7 @@ CHIP_ERROR InetLayer::NewTCPEndPoint(TCPEndPoint ** retEndPoint) *retEndPoint = nullptr; - VerifyOrReturnError(State == kState_Initialized, CHIP_ERROR_INCORRECT_STATE); + VerifyOrReturnError(mLayerState.IsInitialized(), CHIP_ERROR_INCORRECT_STATE); *retEndPoint = TCPEndPoint::sPool.TryCreate(); if (*retEndPoint == nullptr) @@ -495,7 +490,7 @@ CHIP_ERROR InetLayer::NewUDPEndPoint(UDPEndPoint ** retEndPoint) *retEndPoint = nullptr; - VerifyOrReturnError(State == kState_Initialized, CHIP_ERROR_INCORRECT_STATE); + VerifyOrReturnError(mLayerState.IsInitialized(), CHIP_ERROR_INCORRECT_STATE); *retEndPoint = UDPEndPoint::sPool.TryCreate(); if (*retEndPoint == nullptr) diff --git a/src/inet/InetLayer.h b/src/inet/InetLayer.h index d48f64c483eab1..052353b532d677 100644 --- a/src/inet/InetLayer.h +++ b/src/inet/InetLayer.h @@ -69,6 +69,7 @@ #include #include +#include #if INET_CONFIG_MAX_DROPPABLE_EVENTS @@ -124,16 +125,6 @@ class DLL_EXPORT InetLayer #endif // INET_CONFIG_ENABLE_UDP_ENDPOINT public: - /** - * The current state of the InetLayer object. - * - */ - volatile enum { - kState_NotInitialized = 0, /**< Not initialized state. */ - kState_Initialized = 1, /**< Initialized state. */ - kState_ShutdownInProgress = 2, /**< State where Shutdown has been triggered. */ - } State; /**< [READ-ONLY] Current state. */ - InetLayer(); CHIP_ERROR Init(chip::System::Layer & aSystemLayer, void * aContext); @@ -224,6 +215,7 @@ class DLL_EXPORT InetLayer #endif // INET_CONFIG_ENABLE_TCP_ENDPOINT && INET_TCP_IDLE_CHECK_INTERVAL > 0 private: + ObjectLifeCycle mLayerState; void * mContext; void * mPlatformData; chip::System::Layer * mSystemLayer; diff --git a/src/lib/support/ObjectLifeCycle.h b/src/lib/support/ObjectLifeCycle.h index f86f41b00e4d26..b2a8f2ff85558b 100644 --- a/src/lib/support/ObjectLifeCycle.h +++ b/src/lib/support/ObjectLifeCycle.h @@ -26,75 +26,55 @@ namespace chip { * Track the life cycle of an object. * *
- *                  ┌───────────────┐  Init  ┌─────────────┐  Shutdown  ┌──────────┐  Destroy  ┌───────────┐
- * Construction ───>│ Uninitialized ├───────>│ Initialized ├───────────>│ Shutdown ├──────────>│ Destroyed │
- *                  └──────────┬────┘        └─────────────┘            └─────┬────┘           └───────────┘
- *                      ^      │                               Reset          │
- *                      └──────┴<─────────────────────────────────────────────┘
+ *
+ *      Construction
+ *          ↓
+ *      Uninitialized ‹─┐
+ *          ↓           │
+ *      Initializing    │
+ *          ↓           │
+ *      Initialized     │
+ *          ↓           │
+ *      ShuttingDown    │
+ *          ↓           │
+ *      Shutdown ───────┘
+ *          ↓
+ *      Destroyed
+ *
  * 
*/ -struct ObjectLifeCycle +class ObjectLifeCycle { - /** - * @returns true if and only if the object is in the Initialized state. - */ - bool IsInitialized() const { return mState == State::Initialized; } - - /** - * Transition from Uninitialized to Initialized. - * - * Typical use is `VerifyOrReturnError(state.Init(), CHIP_ERROR_INCORRECT_STATE)`; this function returns `bool` rather than - * a `CHIP_ERROR` so that error source tracking will record the call point rather than this function itself. - * - * @return true if the state was Uninitialized and is now Initialized. - * @return false otherwise. - */ - bool Init() +public: + enum class State : uint8_t { - if (mState == State::Uninitialized) - { - mState = State::Initialized; - return true; - } - return false; - } + Uninitialized = 0, ///< Pre-initialized state. + Initializing = 1, ///< State during intialization. + Initialized = 2, ///< Initialized (active) state. + ShuttingDown = 3, ///< State during shutdown. + Shutdown = 4, ///< Post-shutdown state. + Destroyed = 5, ///< Post-destructor state. + }; + + ObjectLifeCycle() : mState(State::Uninitialized) {} + ~ObjectLifeCycle() { mState = State::Destroyed; } /** - * Transition from Initialized to Shutdown. - * - * Typical use is `VerifyOrReturnError(state.Shutdown(), CHIP_ERROR_INCORRECT_STATE)`; this function returns `bool` rather than - * a `CHIP_ERROR` so that error source tracking will record the call point rather than this function itself. - * - * @return true if the state was Initialized and is now Shutdown. - * @return false otherwise. + * @returns true if and only if the object is in the Initialized state. */ - bool Shutdown() - { - if (mState == State::Initialized) - { - mState = State::Shutdown; - return true; - } - return false; - } + bool IsInitialized() const { return mState == State::Initialized; } - /** - * Transition from Shutdown back to Uninitialized, or remain Uninitialized. - * - * Typical use is `VerifyOrReturnError(state.Reset(), CHIP_ERROR_INCORRECT_STATE)`; this function returns `bool` rather than - * a `CHIP_ERROR` so that error source tracking will record the call point rather than this function itself. + /* + * State transitions. * - * @return true if the state was Uninitialized or Shutdown and is now Uninitialized. - * @return false otherwise. + * Typical use is `VerifyOrReturnError(state.SetInitializing(), CHIP_ERROR_INCORRECT_STATE)`; these functions return `bool` + * rather than a `CHIP_ERROR` so that error source tracking will record the call point rather than this function itself. */ - bool Reset() - { - if (mState == State::Shutdown) - { - mState = State::Uninitialized; - } - return mState == State::Uninitialized; - } + bool SetInitializing() { return Transition(); } + bool SetInitialized() { return Transition(); } + bool SetShuttingDown() { return Transition(); } + bool SetShutdown() { return Transition(); } + bool Reset() { return Transition(); } /** * Transition from Uninitialized or Shutdown to Destroyed. @@ -115,21 +95,21 @@ struct ObjectLifeCycle return false; } - /** - * Return the current state as an integer. This is intended for troubleshooting or logging, since there is no code access to - * the meaning of the integer value. - */ - explicit operator int() const { return static_cast(mState); } + State GetState() const { return mState; } private: - enum class State : uint8_t + template + bool Transition() { - Uninitialized = 0, /**< Pre-initialized state; */ - Initialized = 1, /**< Initialized state. */ - Shutdown = 2, /**< Post-Shutdown state. */ - Destroyed = 3, /**< Post-destructor state. */ - }; - State mState = State::Uninitialized; + if (mState == FROM) + { + mState = TO; + return true; + } + return false; + } + + State mState; }; } // namespace chip diff --git a/src/system/SystemLayer.h b/src/system/SystemLayer.h index f2b19cf00cb422..32d0738695d768 100644 --- a/src/system/SystemLayer.h +++ b/src/system/SystemLayer.h @@ -32,7 +32,6 @@ #include #include -#include #include #include #include diff --git a/src/system/SystemLayerImplLibevent.cpp b/src/system/SystemLayerImplLibevent.cpp index bebd13833db758..2dc60a4d333b53 100644 --- a/src/system/SystemLayerImplLibevent.cpp +++ b/src/system/SystemLayerImplLibevent.cpp @@ -55,7 +55,7 @@ System::SocketEvents SocketEventsFromLibeventFlags(short eventFlags) CHIP_ERROR LayerImplLibevent::Init(System::Layer & systemLayer) { - VerifyOrReturnError(!mLayerState.IsInitialized(), CHIP_ERROR_INCORRECT_STATE); + VerifyOrReturnError(mLayerState.SetInitializing(), CHIP_ERROR_INCORRECT_STATE); RegisterPOSIXErrorFormatter(); @@ -83,7 +83,7 @@ CHIP_ERROR LayerImplLibevent::Init(System::Layer & systemLayer) Mutex::Init(mTimerListMutex); - VerifyOrReturnError(mLayerState.Init(), CHIP_ERROR_INCORRECT_STATE); + VerifyOrReturnError(mLayerState.SetInitialized(), CHIP_ERROR_INCORRECT_STATE); return CHIP_NO_ERROR; } @@ -111,7 +111,7 @@ void LayerImplLibevent::MdnsTimeoutCallbackHandler() CHIP_ERROR LayerImplLibevent::Shutdown() { - VerifyOrReturnError(mLayerState.Shutdown(), CHIP_ERROR_INCORRECT_STATE); + VerifyOrReturnError(mLayerState.SetShuttingDown(), CHIP_ERROR_INCORRECT_STATE); event_base_loopbreak(mEventBase); @@ -133,6 +133,7 @@ CHIP_ERROR LayerImplLibevent::Shutdown() mEventBase = nullptr; mSystemLayer = nullptr; + mLayerState.SetShutdown(); mLayerState.Reset(); // Return to uninitialized state to permit re-initialization. return CHIP_NO_ERROR; } diff --git a/src/system/SystemLayerImplLibevent.h b/src/system/SystemLayerImplLibevent.h index 7b53471f4ece0c..7db74b5c11d55b 100644 --- a/src/system/SystemLayerImplLibevent.h +++ b/src/system/SystemLayerImplLibevent.h @@ -44,7 +44,7 @@ class LayerImplLibevent : public LayerSocketsLoop { public: LayerImplLibevent() : mEventBase(nullptr), mMdnsTimeoutEvent(nullptr) {} - ~LayerImplLibevent() { mLayerState.Destroy(); } + ~LayerImplLibevent() = default; // Layer overrides. CHIP_ERROR Init() override; diff --git a/src/system/SystemLayerImplLwIP.cpp b/src/system/SystemLayerImplLwIP.cpp index 6c464176d92bce..10a145a2ac1358 100644 --- a/src/system/SystemLayerImplLwIP.cpp +++ b/src/system/SystemLayerImplLwIP.cpp @@ -34,19 +34,20 @@ LayerImplLwIP::LayerImplLwIP() : mHandlingTimerComplete(false), mEventDelegateLi CHIP_ERROR LayerImplLwIP::Init() { - VerifyOrReturnError(!mLayerState.IsInitialized(), CHIP_ERROR_INCORRECT_STATE); + VerifyOrReturnError(mLayerState.SetInitializing(), CHIP_ERROR_INCORRECT_STATE); RegisterLwIPErrorFormatter(); ReturnErrorOnFailure(mTimerList.Init()); - VerifyOrReturnError(mLayerState.Init(), CHIP_ERROR_INCORRECT_STATE); + VerifyOrReturnError(mLayerState.SetInitialized(), CHIP_ERROR_INCORRECT_STATE); return CHIP_NO_ERROR; } CHIP_ERROR LayerImplLwIP::Shutdown() { - VerifyOrReturnError(mLayerState.Shutdown(), CHIP_ERROR_INCORRECT_STATE); + VerifyOrReturnError(mLayerState.SetShuttingDown(), CHIP_ERROR_INCORRECT_STATE); + mLayerState.SetShutdown(); mLayerState.Reset(); // Return to uninitialized state to permit re-initialization. return CHIP_NO_ERROR; } diff --git a/src/system/SystemLayerImplLwIP.h b/src/system/SystemLayerImplLwIP.h index 3288130205f9c8..b2f4d31828248a 100644 --- a/src/system/SystemLayerImplLwIP.h +++ b/src/system/SystemLayerImplLwIP.h @@ -32,7 +32,7 @@ class LayerImplLwIP : public LayerLwIP { public: LayerImplLwIP(); - ~LayerImplLwIP() { mLayerState.Destroy(); } + ~LayerImplLwIP() = default; // Layer overrides. CHIP_ERROR Init() override; diff --git a/src/system/SystemLayerImplSelect.cpp b/src/system/SystemLayerImplSelect.cpp index b69f16d1a2537f..14d2c4ccd9320d 100644 --- a/src/system/SystemLayerImplSelect.cpp +++ b/src/system/SystemLayerImplSelect.cpp @@ -42,7 +42,7 @@ namespace System { CHIP_ERROR LayerImplSelect::Init() { - VerifyOrReturnError(!mLayerState.IsInitialized(), CHIP_ERROR_INCORRECT_STATE); + VerifyOrReturnError(mLayerState.SetInitializing(), CHIP_ERROR_INCORRECT_STATE); RegisterPOSIXErrorFormatter(); @@ -60,13 +60,13 @@ CHIP_ERROR LayerImplSelect::Init() // Create an event to allow an arbitrary thread to wake the thread in the select loop. ReturnErrorOnFailure(mWakeEvent.Open(*this)); - VerifyOrReturnError(mLayerState.Init(), CHIP_ERROR_INCORRECT_STATE); + VerifyOrReturnError(mLayerState.SetInitialized(), CHIP_ERROR_INCORRECT_STATE); return CHIP_NO_ERROR; } CHIP_ERROR LayerImplSelect::Shutdown() { - VerifyOrReturnError(mLayerState.Shutdown(), CHIP_ERROR_INCORRECT_STATE); + VerifyOrReturnError(mLayerState.SetShuttingDown(), CHIP_ERROR_INCORRECT_STATE); Timer * timer; while ((timer = mTimerList.PopEarliest()) != nullptr) @@ -84,6 +84,8 @@ CHIP_ERROR LayerImplSelect::Shutdown() timer->Release(); } mWakeEvent.Close(*this); + + mLayerState.SetShutdown(); mLayerState.Reset(); // Return to uninitialized state to permit re-initialization. return CHIP_NO_ERROR; } diff --git a/src/system/SystemLayerImplSelect.h b/src/system/SystemLayerImplSelect.h index 8b2c29c808a81d..e8b035f83fb73a 100644 --- a/src/system/SystemLayerImplSelect.h +++ b/src/system/SystemLayerImplSelect.h @@ -39,8 +39,8 @@ namespace System { class LayerImplSelect : public LayerSocketsLoop { public: - LayerImplSelect() = default; - ~LayerImplSelect() { mLayerState.Destroy(); } + LayerImplSelect() = default; + ~LayerImplSelect() = default; // Layer overrides. CHIP_ERROR Init() override;