[instance] introduce ActiveInstanceTracker for context-aware logging (#12869)

This commit introduces `ActiveInstanceTracker` as the first member
variable of the `Instance` class to manage the global `gActiveInstance`
pointer (when `OPENTHREAD_CONFIG_LOG_INSTANCE_AWARE_API_ENABLE` is
enabled).

By placing it as the very first member, we ensure its constructor
is called before any other member and its destructor is called after
all others. The `Instance` destructor body also explicitly sets
`gActiveInstance = this` at its start to "claim" the context during its
own destruction. This guarantees that logs emitted during both the
initialization and destruction of an `Instance` are always correctly
associated with that instance. Finally, the `ActiveInstanceTracker`
destructor sets `gActiveInstance` to `nullptr` at the very end to
prevent any potential use of a dangling pointer.
This commit is contained in:
Abtin Keshavarzian
2026-04-10 21:38:35 -05:00
committed by GitHub
parent 21181644aa
commit 581221eedb
2 changed files with 42 additions and 9 deletions
+6 -9
View File
@@ -78,7 +78,8 @@ LogLevel Instance::sGlobalLogLevel = static_cast<LogLevel>(OPENTHREAD_CONFIG_LOG
#endif
Instance::Instance(void)
: mTimerMilliScheduler(*this)
: mActiveInstanceTracker(*this)
, mTimerMilliScheduler(*this)
#if OPENTHREAD_CONFIG_PLATFORM_USEC_TIMER_ENABLE
, mTimerMicroScheduler(*this)
#endif
@@ -337,6 +338,10 @@ Instance::Instance(void)
#endif
}
#if OPENTHREAD_CONFIG_MULTIPLE_INSTANCE_ENABLE && OPENTHREAD_CONFIG_LOG_INSTANCE_AWARE_API_ENABLE
Instance::~Instance(void) { gActiveInstance = this; }
#endif
#if (OPENTHREAD_MTD || OPENTHREAD_FTD) && !OPENTHREAD_CONFIG_HEAP_EXTERNAL_ENABLE
Utils::Heap &Instance::GetHeap(void)
{
@@ -490,16 +495,8 @@ void Instance::Finalize(void)
IgnoreError(Get<Mac::SubMac>().Disable());
#if !OPENTHREAD_CONFIG_MULTIPLE_INSTANCE_ENABLE
/**
* Object was created on buffer, so instead of deleting
* the object we call destructor explicitly.
*/
this->~Instance();
#endif // !OPENTHREAD_CONFIG_MULTIPLE_INSTANCE_ENABLE
exit:
return;
}
+36
View File
@@ -484,7 +484,41 @@ public:
void AfterInit(void);
#endif
#if OPENTHREAD_CONFIG_MULTIPLE_INSTANCE_ENABLE && OPENTHREAD_CONFIG_LOG_INSTANCE_AWARE_API_ENABLE
/**
* Destructor
*/
~Instance(void);
#endif
private:
class ActiveInstanceTracker
{
public:
// This class is used to track and update the `gActiveInstance` pointer during the
// construction and destruction of an `Instance`.
//
// `mActiveInstanceTracker` is defined as the very first member variable in `Instance`.
// This ensures its constructor is called before any other member components are
// initialized, and its destructor is called after all other components are destroyed.
// This ensures `gActiveInstance` is correctly set during the entire lifecycle of
// the `Instance`, allowing member components to safely emit logs.
//
// The `Instance` destructor also explicitly sets `gActiveInstance` to the instance
// being destroyed at the beginning of its body. This ensures that during the
// entire destruction process, log messages are correctly associated with the
// instance being destroyed. Finally, when `mActiveInstanceTracker` itself is
// destroyed (at the end of the `Instance` destruction), `gActiveInstance` is
// set to `nullptr` to avoid any potential use of a dangling pointer.
#if OPENTHREAD_CONFIG_MULTIPLE_INSTANCE_ENABLE && OPENTHREAD_CONFIG_LOG_INSTANCE_AWARE_API_ENABLE
ActiveInstanceTracker(Instance &aInstance) { gActiveInstance = &aInstance; }
~ActiveInstanceTracker(void) { gActiveInstance = nullptr; }
#else
ActiveInstanceTracker(Instance &) {}
#endif
};
#if !OPENTHREAD_PLATFORM_NEXUS
Instance(void);
void AfterInit(void);
@@ -509,6 +543,8 @@ private:
// Tasklet and Timer Schedulers are first to ensure other
// objects/classes can use them from their constructors.
ActiveInstanceTracker mActiveInstanceTracker;
Tasklet::Scheduler mTaskletScheduler;
TimerMilli::Scheduler mTimerMilliScheduler;
#if OPENTHREAD_CONFIG_PLATFORM_USEC_TIMER_ENABLE