Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions include/ut_control_plane.h
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ typedef struct
typedef void ut_controlPlane_instance_t; /*!< Handle to a control plane instance */

/** @brief Callback function type for handling control plane messages. */
/*Responsibility: The callback/client is responsible for freeing the instance */
Copy link
Contributor

@Ulrond Ulrond Sep 24, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we need to make it clear, that the memory is internal and will be freed.. If due to the clients implementation they want to offline process the data, then they must copy it for that purpose.

/**
 * @typedef ut_control_callback_t
 * @brief Function pointer type for control plane message callbacks.
 *
 * The callback is invoked synchronously when a registered message key is
 * received. Its primary purpose is to notify the caller that the key has been
 * triggered. The accompanying data is provided for informational use and
 * transient decision-making within the callback.
 *
 * The data associated with the `instance` parameter is only valid for the
 * duration of the callback execution. In most cases, it is not expected to be
 * copied, as it is intended for on-the-spot processing. However, if the caller
 * requires the data for further use outside the callback, they may copy it
 * into their own storage before returning.
 *
 * Memory management of the `instance` is handled internally. The caller must
 * not free it, and must not use it after the callback has returned.
 *
 * @param key - Null-terminated string representing the message key that
 *              triggered the callback.
 * @param instance - Pointer to a key-value pair (`ut_kvp_instance_t`) instance
 *                   containing the message data. Valid only during the callback.
 * @param userData - User-provided pointer passed during callback registration.
 */
typedef void (*ut_control_callback_t)(
    char *key,
    ut_kvp_instance_t *instance,
    void *userData
);

But I would question why they should be doing that.

/**
* @brief Registers a synchronous callback function for a specific message key.
*
* The callback is invoked immediately when the specified key is received.
* The data provided to the callback is only valid for the duration of the
* callback execution. If the user wishes to retain or process the data
* after the callback returns, they must copy it to their own storage.
*
* The memory associated with the callback data is automatically released
* once the callback returns. It is NOT the responsibility of the caller
* to free this memory. However, it is the responsibility of the caller
* to ensure they do not access or use the callback data after the
* callback has returned.
*
* @param pInstance - Handle to the control plane instance.
* @param key - Null-terminated string representing the message key to trigger the callback.
* @param callbackFunction - Callback function to be invoked synchronously when the key is received.
* @param userData - User-provided handle passed back to the callback.
* @returns Status of the registration operation (`ut_control_plane_status_t`).
* @retval UT_CONTROL_PLANE_STATUS_OK - Success.
* @retval UT_CONTROL_PLANE_STATUS_INVALID_HANDLE - Invalid control plane instance handle.
* @retval UT_CONTROL_PLANE_STATUS_INVALID_PARAM - Invalid parameter passed.
* @retval UT_CONTROL_PLANE_STATUS_CALLBACK_LIST_FULL - Callback list is full.
*/
ut_control_plane_status_t UT_ControlPlane_RegisterCallbackOnMessage(
    ut_controlPlane_instance_t *pInstance,
    char *key,
    ut_control_callback_t callbackFunction,
    void *userData
);
``

typedef void (*ut_control_callback_t)( char *key, ut_kvp_instance_t *instance, void *userData );

/**
Expand Down
3 changes: 2 additions & 1 deletion src/ut_control_plane.c
Original file line number Diff line number Diff line change
Expand Up @@ -166,9 +166,10 @@ static void call_callback_on_match(cp_message_t *mssg, ut_cp_instance_internal_t
{
// call callback
entry.pCallback(entry.key, pkvpInstance, entry.userData);
// pKvpInstance should not be used after this point as it is destroyed in the callback
// responsibility of the callback/client to destroy the instance
}
}
ut_kvp_destroyInstance(pkvpInstance);
return;
}

Expand Down
2 changes: 2 additions & 0 deletions tests/src/ut_test_control_plane.c
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,7 @@ void testYAMLCallback(char *key, ut_kvp_instance_t *instance, void* userData)

//UT_ASSERT_STRING_EQUAL(kvpData, data);
gMessageRecievedYAML = true;
ut_kvp_destroyInstance(instance); // free the instance here as it is created in the control plane
}

void testJSONCallback(char *key, ut_kvp_instance_t *instance, void* userData)
Expand All @@ -215,6 +216,7 @@ void testJSONCallback(char *key, ut_kvp_instance_t *instance, void* userData)

//UT_ASSERT_STRING_EQUAL(kvpData, data);
gMessageRecievedJSON = true;
ut_kvp_destroyInstance(instance); // free the instance here as it is created in the control plane
}

static void UT_ControlPlane_Sigint_Handler(int sig)
Expand Down