[callback] add InvokeAndClearIfSet() helper (#10064)

Will first clear the callback before invoking its handler so to
allow the callback to possibly set again from the handler
implementation.
This commit is contained in:
Abtin Keshavarzian
2024-04-26 11:39:58 -07:00
committed by GitHub
parent 7a773681d0
commit ca45026ba5
5 changed files with 46 additions and 28 deletions
+38
View File
@@ -206,6 +206,25 @@ public:
Invoke(static_cast<Args &&>(aArgs)...);
}
}
/**
* Invokes the callback handler if it is set and clears it.
*
* The method MUST be used when the handler function returns `void`.
*
* The callback is cleared first before invoking its handler to allow it to be set again from the handler
* implementation.
*
* @param[in] aArgs The args to pass to the callback handler.
*
*/
template <typename... Args> void InvokeAndClearIfSet(Args &&...aArgs)
{
Callback<HandlerType, kContextAsLastArg> callbackCopy = *this;
CallbackBase<HandlerType>::Clear();
callbackCopy.InvokeIfSet(static_cast<Args &&>(aArgs)...);
}
};
// Specialization for `kContextAsFirstArg`
@@ -236,6 +255,25 @@ public:
Invoke(static_cast<Args &&>(aArgs)...);
}
}
/**
* Invokes the callback handler if it is set and clears it.
*
* The method MUST be used when the handler function returns `void`.
*
* The callback is cleared first before invoking its handler to allow it to be set again from the handler
* implementation.
*
* @param[in] aArgs The args to pass to the callback handler.
*
*/
template <typename... Args> void InvokeAndClearIfSet(Args &&...aArgs)
{
Callback<HandlerType, kContextAsFirstArg> callbackCopy = *this;
CallbackBase<HandlerType>::Clear();
callbackCopy.InvokeIfSet(static_cast<Args &&>(aArgs)...);
}
};
} // namespace ot
+2 -7
View File
@@ -323,6 +323,7 @@ void DatasetManager::HandleMgmtSetResponse(Coap::Message *aMessage, const Ip6::M
SuccessOrExit(error = aError);
VerifyOrExit(Tlv::Find<StateTlv>(*aMessage, state) == kErrorNone && state != StateTlv::kPending,
error = kErrorParse);
if (state == StateTlv::kReject)
{
error = kErrorRejected;
@@ -333,13 +334,7 @@ exit:
mMgmtPending = false;
if (mMgmtSetCallback.IsSet())
{
Callback<otDatasetMgmtSetCallback> callbackCopy = mMgmtSetCallback;
mMgmtSetCallback.Clear();
callbackCopy.Invoke(error);
}
mMgmtSetCallback.InvokeAndClearIfSet(error);
mTimer.Start(kSendSetDelay);
}
+1 -7
View File
@@ -109,13 +109,7 @@ void AnycastLocator::HandleResponse(Coap::Message *aMessage, const Ip6::MessageI
address = &meshLocalAddress;
exit:
if (mCallback.IsSet())
{
Callback<LocatorCallback> callbackCopy = mCallback;
mCallback.Clear();
callbackCopy.Invoke(aError, address, rloc16);
}
mCallback.InvokeAndClearIfSet(aError, address, rloc16);
}
#if OPENTHREAD_CONFIG_TMF_ANYCAST_LOCATOR_SEND_RESPONSE
+1 -8
View File
@@ -253,14 +253,7 @@ void Mle::Stop(StopMode aMode)
exit:
mDetachGracefullyTimer.Stop();
if (mDetachGracefullyCallback.IsSet())
{
Callback<otDetachGracefullyCallback> callbackCopy = mDetachGracefullyCallback;
mDetachGracefullyCallback.Clear();
callbackCopy.Invoke();
}
mDetachGracefullyCallback.InvokeAndClearIfSet();
}
void Mle::ResetCounters(void)
+4 -6
View File
@@ -344,17 +344,15 @@ void MlrManager::HandleRegisterResponse(otMessage *aMessage, const otMessageInfo
{
OT_UNUSED_VARIABLE(aMessageInfo);
uint8_t status;
Error error;
AddressArray failedAddresses;
Callback<MlrCallback> callbackCopy = mRegisterCallback;
uint8_t status;
Error error;
AddressArray failedAddresses;
mRegisterPending = false;
mRegisterCallback.Clear();
error = ParseMlrResponse(aResult, AsCoapMessagePtr(aMessage), status, failedAddresses);
callbackCopy.InvokeIfSet(error, status, failedAddresses.GetArrayBuffer(), failedAddresses.GetLength());
mRegisterCallback.InvokeAndClearIfSet(error, status, failedAddresses.GetArrayBuffer(), failedAddresses.GetLength());
}
#endif // OPENTHREAD_FTD && OPENTHREAD_CONFIG_TMF_PROXY_MLR_ENABLE && OPENTHREAD_CONFIG_COMMISSIONER_ENABLE