]> git.ipfire.org Git - thirdparty/haproxy.git/commit
MINOR: event_hdl: dynamically allocated event data members
authorAurelien DARRAGON <adarragon@haproxy.com>
Thu, 23 Mar 2023 18:09:15 +0000 (19:09 +0100)
committerChristopher Faulet <cfaulet@haproxy.com>
Fri, 21 Apr 2023 12:36:45 +0000 (14:36 +0200)
commitebf58e991abd40cd617786aab503869101a65e95
tree632b928fedd29f7f5b3be287a0380ecb52ca400a
parent147691fd83b8565a2e16bcaec188ddd3b6c423a7
MINOR: event_hdl: dynamically allocated event data members

Add the ability to provide a cleanup function for event data passed
via the publishing function.

One use case could be the need to provide valid pointers in the safe
section of the data struct.
Cleanup function will be automatically called with data (or copy of data)
as argument when all handlers consumed the event, which provides an easy
way to release some memory or decrement refcounts to ressources that were
provided through the data struct.
data in itself may not be freed by the cleanup function, it is handled
by the API.

This would allow passing large (allocated) data blocks through the data
struct while keeping data struct size under the EVENT_HDL_ASYNC_EVENT_DATA
size limit.

To do so, when publishing an event, where we would currently do:

        struct event_hdl_cb_data_new_family event_data;

        /* safe data, available from both sync and async contexts
 * may not use pointers to short-living resources
 */
        event_data.safe.my_custom_data = x;

        /* unsafe data, only available from sync contexts */
        event_data.unsafe.my_unsafe_data = y;

        /* once data is prepared, we can publish the event */
        event_hdl_publish(NULL,
                          EVENT_HDL_SUB_NEW_FAMILY_SUBTYPE_1,
                          EVENT_HDL_CB_DATA(&event_data));

We could do:

        struct event_hdl_cb_data_new_family event_data;

        /* safe data, available from both sync and async contexts
 * may not use pointers to short-living resources,
 * unless EVENT_HDL_CB_DATA_DM is used to ensure pointer
 * consistency (ie: refcount)
 */
        event_data.safe.my_custom_static_data = x;
event_data.safe.my_custom_dynamic_data = malloc(1);

        /* unsafe data, only available from sync contexts */
        event_data.unsafe.my_unsafe_data = y;

        /* once data is prepared, we can publish the event */
        event_hdl_publish(NULL,
                          EVENT_HDL_SUB_NEW_FAMILY_SUBTYPE_1,
                          EVENT_HDL_CB_DATA_DM(&event_data, data_new_family_cleanup));

With data_new_family_cleanup func which would look like this:

      void data_new_family_cleanup(const void *data)
      {
       const struct event_hdl_cb_data_new_family *event_data = ptr;

/* some data members require specific cleanup once the event
 * is consumed
 */
       free(event_data.safe.my_custom_dynamic_data);
/* don't ever free data! it is not ours */
      }

Not sure if this feature will become relevant in the future, so I prefer not
to mention it in the doc for now.

But given that the implementation is trivial and does not put a burden
on the existing API, it's a good thing to have it there, just in case.
include/haproxy/event_hdl-t.h
include/haproxy/event_hdl.h
src/event_hdl.c