From f542690802a9a4a31b56471ca2457e8dac73b60c Mon Sep 17 00:00:00 2001 From: Julius Pfrommer Date: Wed, 7 Sep 2022 23:28:14 +0200 Subject: [PATCH] feat(el): Add removeDelayedCallback --- arch/eventloop_posix.c | 17 +++++++++++++++++ include/open62541/plugin/eventloop.h | 12 +++++++++--- 2 files changed, 26 insertions(+), 3 deletions(-) diff --git a/arch/eventloop_posix.c b/arch/eventloop_posix.c index aa21a580c6b..a2f102ffb64 100644 --- a/arch/eventloop_posix.c +++ b/arch/eventloop_posix.c @@ -70,6 +70,22 @@ UA_EventLoopPOSIX_addDelayedCallback(UA_EventLoop *public_el, UA_UNLOCK(&el->elMutex); } +static void +UA_EventLoopPOSIX_removeDelayedCallback(UA_EventLoop *public_el, + UA_DelayedCallback *dc) { + UA_EventLoopPOSIX *el = (UA_EventLoopPOSIX*)public_el; + UA_LOCK(&el->elMutex); + UA_DelayedCallback **prev = &el->delayedCallbacks; + while(*prev) { + if(*prev == dc) { + *prev = (*prev)->next; + return; + } + prev = &(*prev)->next; + } + UA_UNLOCK(&el->elMutex); +} + /* Process and then free registered delayed callbacks */ static void processDelayed(UA_EventLoopPOSIX *el) { @@ -423,6 +439,7 @@ UA_EventLoop_new_POSIX(const UA_Logger *logger) { el->eventLoop.modifyCyclicCallback = UA_EventLoopPOSIX_modifyCyclicCallback; el->eventLoop.removeCyclicCallback = UA_EventLoopPOSIX_removeCyclicCallback; el->eventLoop.addDelayedCallback = UA_EventLoopPOSIX_addDelayedCallback; + el->eventLoop.removeDelayedCallback = UA_EventLoopPOSIX_removeDelayedCallback; el->eventLoop.registerEventSource = (UA_StatusCode (*)(UA_EventLoop*, UA_EventSource*)) diff --git a/include/open62541/plugin/eventloop.h b/include/open62541/plugin/eventloop.h index 400eebae2ed..dc60166d60e 100644 --- a/include/open62541/plugin/eventloop.h +++ b/include/open62541/plugin/eventloop.h @@ -152,12 +152,18 @@ struct UA_EventLoop { /* Delayed Callbacks * ~~~~~~~~~~~~~~~~~ - * The registered delayed callbacks are executed once in each cycle of the - * EventLoop (between the cyclic callbacks and polling for events with a - * timeout). The memory for the delayed callback is freed after the + * Delayed callbacks are executed once by the EventLoop and then + * deregistered automatically. A typical use case is to delay a resource + * cleanup to a point where it is known that the resource has no remaining + * users "upwards in the call stack". + * + * The execution happens in the cycle of the EventLoop between the handling + * of timed cyclic callbacks and polling for (network) events. The memory + * for the delayed callback is NOT automatically freed after the * execution. */ void (*addDelayedCallback)(UA_EventLoop *el, UA_DelayedCallback *dc); + void (*removeDelayedCallback)(UA_EventLoop *el, UA_DelayedCallback *dc); /* EventSources * ~~~~~~~~~~~~