coap_resource.c: Make dynamic resource handling thread safe

Let libcoap do the necessary multi-thread locking during resource
generation, lookup and deletion.

Supported using a new handler set up by coap_register_dynamic_resource_handler().
This commit is contained in:
Jon Shallow authored and Jon Shallow committed 2025-07-08 13:37:57 +01:00
1 parent 33b3f02006
commit f62c836ece
11 files changed
+397 -169

No files matched your search

+28
View File
@@ -106,6 +106,16 @@ typedef void (*coap_pong_handler_t)(coap_session_t *session,
const coap_pdu_t *received,
const coap_mid_t mid);
/**
* Definition of resource dynamic creation handler function
*
* @param session The CoAP session.
* @param request The request PDU.
*
* @return A pointer to the new resource or @c NULL on error.
*/
typedef coap_resource_t *(*coap_resource_dynamic_create_t)(coap_session_t *session,
const coap_pdu_t *request);
/**
* Registers a new message handler that is called whenever a response is
* received.
@@ -148,6 +158,24 @@ void coap_register_ping_handler(coap_context_t *context,
void coap_register_pong_handler(coap_context_t *context,
coap_pong_handler_t handler);
/**
* Sets up a handler for calling when an unknown resource is requested.
* The @p create_handler is expected to create the required resource to handle
* the request which is then used to call the appropriate method handler.
*
* Doing this stops multiple threads asking for the same unknown resource and
* means that a resource unknown handler does not need to be thread safe.
*
* @param context The context to add this support to.
* @param create_handler Called to create a new resource.
* @param dynamic_max Maximum number of currently created dynamic resources. If
* 0, unlimited.
*
*/
void coap_register_dynamic_resource_handler(coap_context_t *context,
coap_resource_dynamic_create_t create_handler,
uint32_t dynamic_max);
/**
* Registers the option number @p number with the given context object @p context.
*
+3
View File
@@ -215,6 +215,9 @@ struct coap_context_t {
uint8_t testing_cids; /**< Change client's source port every testing_cids */
#endif /* COAP_CLIENT_SUPPORT */
uint32_t block_mode; /**< Zero or more COAP_BLOCK_ or'd options */
coap_resource_dynamic_create_t dyn_create_handler; /**< Dynamc resource create handler */
uint32_t dynamic_cur; /* Current number of dynamic resources */
uint32_t dynamic_max; /* Max number of dynamic resources or 0 is unlimited */
};
/**
+22
View File
@@ -60,7 +60,9 @@ struct coap_resource_t {
unsigned int is_proxy_uri:1; /**< resource created for proxy URI handler */
unsigned int is_reverse_proxy:1; /**< resource created for reverse proxy URI handler */
unsigned int list_being_traversed:1; /**< resource subscriber list being traversed */
unsigned int is_dynamic:1; /**< create unknown resource dynamically */
uint32_t ref; /**< Resource reference count */
/**
* Used to store handlers for the seven coap methods @c GET, @c POST, @c PUT,
* @c DELETE, @c FETCH, @c PATCH and @c IPATCH.
@@ -147,6 +149,26 @@ int coap_delete_resource_lkd(coap_context_t *context, coap_resource_t *resource)
*/
void coap_delete_all_resources(coap_context_t *context);
/**
* Increment reference counter on a resource.
*
* Note: This function must be called in the locked state.
*
* @param resource The CoAP resource.
*/
void coap_resource_reference_lkd(coap_resource_t *resource);
/**
* Decrement reference counter on a resource.
* Note that the resource storage may be deleted as a result and should not be
* used after this call.
*
* Note: This function must be called in the locked state.
*
* @param resource The CoAP resource.
*/
void coap_resource_release_lkd(coap_resource_t *resource);
#define RESOURCES_ADD(r, obj) \
HASH_ADD(hh, (r), uri_path->s[0], (obj)->uri_path->length, (obj))