From 8085f0a4ac70f2a5e50166b98926a9a48382f810 Mon Sep 17 00:00:00 2001 From: Abtin Keshavarzian Date: Thu, 12 May 2022 09:59:14 -0700 Subject: [PATCH] [locator] add `GetProvider` base to provide `Get()` on `Message` (#7679) This commit introduces a base class `GetProvider` which provides `Get()` methods using `GetInstance()` (which is expected to be provided by the derived class in a CRTP style inheritance). The class `GetProvider` is used as base class of `InstanceLocator`. This model allows us to provide `Get()` methods on types that may not be directly an `InstanceLocator`. For example, this commit uses this model on `Message` class. `Message` always retains the `MessagePool` which can be used to get to the `Instance` that owns the `Message`. Note that it is not straight-forward to to have `Message` directly inherit from `InstanceLocator` (due to way `Message` is built from `Buffer` and uses `Metadata` header and that `InstanceLocator` behaves differently under single vs multi instance configs). --- src/core/common/instance.hpp | 5 +++ src/core/common/locator.hpp | 47 ++++++++++++++++++++--------- src/core/common/locator_getters.hpp | 22 +++----------- src/core/common/message.hpp | 15 ++++++++- 4 files changed, 56 insertions(+), 33 deletions(-) diff --git a/src/core/common/instance.hpp b/src/core/common/instance.hpp index 386755fa4..caba4dd37 100644 --- a/src/core/common/instance.hpp +++ b/src/core/common/instance.hpp @@ -430,6 +430,11 @@ DefineCoreType(otBufferInfo, Instance::BufferInfo); // Specializations of the `Get()` method. +template <> inline Instance &Instance::Get(void) +{ + return *this; +} + template <> inline Radio &Instance::Get(void) { return mRadio; diff --git a/src/core/common/locator.hpp b/src/core/common/locator.hpp index 927e1d880..7ed3625ca 100644 --- a/src/core/common/locator.hpp +++ b/src/core/common/locator.hpp @@ -58,6 +58,38 @@ extern uint64_t gInstanceRaw[]; * */ +/** + * This template class implements `Get()` method for different `Type` objects belonging to the OpenThread + * instance. + * + * Users of this class MUST follow CRTP-style inheritance, i.e., the class `Class` itself should publicly inherit + * from `GetProvider`. + * + * @tparam InstanceGetProvider The template sub-lass used in CRTP style inheritance. + * `InstanceGetProvider` MUST provide a method with the following signature: + * `Instance &GetInstance(void) const` + * + */ +template class GetProvider +{ +public: + /** + * This template method returns a reference to a given `Type` object belonging to the OpenThread instance. + * + * For example, `Get()` returns a reference to the `MeshForwarder` object of the instance. + * + * Note that any `Type` for which the `Get` is defined MUST be uniquely accessible from the OpenThread + * `Instance` through the member variable property hierarchy. + * + * @returns A reference to the `Type` object of the instance. + * + */ + template inline Type &Get(void) const; // Implemented in `locator_getters.hpp`. + +protected: + GetProvider(void) = default; +}; + /** * This class implements a locator for an OpenThread Instance object. * @@ -69,7 +101,7 @@ extern uint64_t gInstanceRaw[]; * single-instance case, this class becomes an empty base class. * */ -class InstanceLocator +class InstanceLocator : public GetProvider { friend class InstanceLocatorInit; @@ -86,19 +118,6 @@ public: Instance &GetInstance(void) const { return *reinterpret_cast(&gInstanceRaw); } #endif - /** - * This template method returns a reference to a given `Type` object belonging to the OpenThread instance. - * - * For example, `Get()` returns a reference to the `MeshForwarder` object of the instance. - * - * Note that any `Type` for which the `Get` is defined MUST be uniquely accessible from the OpenThread - * `Instance` through the member variable property hierarchy. - * - * @returns A reference to the `Type` object of the instance. - * - */ - template inline Type &Get(void) const; // Implemented in `locator_getters.hpp`. - protected: /** * This constructor initializes the object. diff --git a/src/core/common/locator_getters.hpp b/src/core/common/locator_getters.hpp index dc87b40c5..e1c68855c 100644 --- a/src/core/common/locator_getters.hpp +++ b/src/core/common/locator_getters.hpp @@ -42,25 +42,11 @@ namespace ot { -/** - * This method returns a reference to the parent OpenThread Instance. - * - * This definition is a specialization of template `Get` for `Get()`, - * - * @returns A reference to `Instance` object. - * - */ -template <> inline Instance &InstanceLocator::Get(void) const +template +template +inline Type &GetProvider::Get(void) const { - return GetInstance(); -} - -template inline Type &InstanceLocator::Get(void) const -{ - // This method uses the `Instance` template method `Get` - // to get to the given `Type` from the single OpenThread - // instance. - return GetInstance().Get(); + return static_cast(this)->GetInstance().template Get(); } } // namespace ot diff --git a/src/core/common/message.hpp b/src/core/common/message.hpp index 2d359cedb..ea0424c32 100644 --- a/src/core/common/message.hpp +++ b/src/core/common/message.hpp @@ -258,7 +258,7 @@ static_assert(sizeof(Buffer) >= kBufferSize, "Buffer size if not valid"); * This class represents a message. * */ -class Message : public otMessage, public Buffer +class Message : public otMessage, public Buffer, public GetProvider { friend class Checksum; friend class Crypto::HmacSha256; @@ -410,6 +410,14 @@ public: static const otMessageSettings kDefault; }; + /** + * This method returns a reference to the OpenThread Instance which owns the `Message`. + * + * @returns A reference to the `Instance`. + * + */ + Instance &GetInstance(void) const; + /** * This method frees this message buffer. * @@ -1663,6 +1671,11 @@ private: #endif }; +inline Instance &Message::GetInstance(void) const +{ + return GetMessagePool()->GetInstance(); +} + /** * @} *