mirror of
https://github.com/espressif/esp-idf.git
synced 2024-10-05 20:47:46 -04:00
ESP Event: multiple registrations to one event
* It's possible now to register the same handler several times to one specific event, using a dynamic handle object.
This commit is contained in:
parent
7f4309d0f1
commit
9b4815e3c8
@ -33,6 +33,24 @@ esp_err_t esp_event_handler_register(esp_event_base_t event_base, int32_t event_
|
||||
event_handler, event_handler_arg);
|
||||
}
|
||||
|
||||
esp_err_t esp_event_handler_instance_register(esp_event_base_t event_base,
|
||||
int32_t event_id,
|
||||
esp_event_handler_t event_handler,
|
||||
void *event_handler_arg,
|
||||
esp_event_handler_instance_t *context)
|
||||
{
|
||||
if (s_default_loop == NULL) {
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
|
||||
return esp_event_handler_instance_register_with(s_default_loop,
|
||||
event_base,
|
||||
event_id,
|
||||
event_handler,
|
||||
event_handler_arg,
|
||||
context);
|
||||
}
|
||||
|
||||
esp_err_t esp_event_handler_unregister(esp_event_base_t event_base, int32_t event_id,
|
||||
esp_event_handler_t event_handler)
|
||||
{
|
||||
@ -44,6 +62,17 @@ esp_err_t esp_event_handler_unregister(esp_event_base_t event_base, int32_t even
|
||||
event_handler);
|
||||
}
|
||||
|
||||
esp_err_t esp_event_handler_instance_unregister(esp_event_base_t event_base,
|
||||
int32_t event_id,
|
||||
esp_event_handler_instance_t context)
|
||||
{
|
||||
if (s_default_loop == NULL) {
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
|
||||
return esp_event_handler_instance_unregister_with(s_default_loop, event_base, event_id, context);
|
||||
}
|
||||
|
||||
esp_err_t esp_event_post(esp_event_base_t event_base, int32_t event_id,
|
||||
void* event_data, size_t event_data_size, TickType_t ticks_to_wait)
|
||||
{
|
||||
|
@ -66,7 +66,7 @@ static int esp_event_dump_prepare(void)
|
||||
esp_event_loop_node_t *loop_node_it;
|
||||
esp_event_base_node_t* base_node_it;
|
||||
esp_event_id_node_t* id_node_it;
|
||||
esp_event_handler_instance_t* handler_it;
|
||||
esp_event_handler_node_t* handler_it;
|
||||
|
||||
// Count the number of items to be printed. This is needed to compute how much memory to reserve.
|
||||
int loops = 0, handlers = 0;
|
||||
@ -122,9 +122,9 @@ static void esp_event_loop_run_task(void* args)
|
||||
vTaskSuspend(NULL);
|
||||
}
|
||||
|
||||
static void handler_execute(esp_event_loop_instance_t* loop, esp_event_handler_instance_t *handler, esp_event_post_instance_t post)
|
||||
static void handler_execute(esp_event_loop_instance_t* loop, esp_event_handler_node_t *handler, esp_event_post_instance_t post)
|
||||
{
|
||||
ESP_LOGD(TAG, "running post %s:%d with handler %p on loop %p", post.base, post.id, handler->handler, loop);
|
||||
ESP_LOGD(TAG, "running post %s:%d with handler %p and context %p on loop %p", post.base, post.id, handler->handler_ctx->handler, &handler->handler_ctx, loop);
|
||||
|
||||
#ifdef CONFIG_ESP_EVENT_LOOP_PROFILING
|
||||
int64_t start, diff;
|
||||
@ -142,9 +142,9 @@ static void handler_execute(esp_event_loop_instance_t* loop, esp_event_handler_i
|
||||
}
|
||||
}
|
||||
|
||||
(*(handler->handler))(handler->arg, post.base, post.id, data_ptr);
|
||||
(*(handler->handler_ctx->handler))(handler->handler_ctx->arg, post.base, post.id, data_ptr);
|
||||
#else
|
||||
(*(handler->handler))(handler->arg, post.base, post.id, post.data);
|
||||
(*(handler->handler_ctx->handler))(handler->handler_ctx->arg, post.base, post.id, post.data);
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_ESP_EVENT_LOOP_PROFILING
|
||||
@ -159,29 +159,38 @@ static void handler_execute(esp_event_loop_instance_t* loop, esp_event_handler_i
|
||||
#endif
|
||||
}
|
||||
|
||||
static esp_err_t handler_instances_add(esp_event_handler_instances_t* handlers, esp_event_handler_t handler, void* handler_arg)
|
||||
static esp_err_t handler_instances_add(esp_event_handler_nodes_t* handlers, esp_event_handler_t event_handler, void* event_handler_arg, esp_event_handler_instance_context_t **handler_ctx, bool legacy)
|
||||
{
|
||||
esp_event_handler_instance_t* handler_instance = calloc(1, sizeof(*handler_instance));
|
||||
esp_event_handler_node_t *handler_instance = calloc(1, sizeof(*handler_instance));
|
||||
|
||||
if (!handler_instance) {
|
||||
if (!handler_instance) return ESP_ERR_NO_MEM;
|
||||
|
||||
esp_event_handler_instance_context_t *context = calloc(1, sizeof(*context));
|
||||
|
||||
if (!context) {
|
||||
free(handler_instance);
|
||||
return ESP_ERR_NO_MEM;
|
||||
}
|
||||
|
||||
handler_instance->handler = handler;
|
||||
handler_instance->arg = handler_arg;
|
||||
context->handler = event_handler;
|
||||
context->arg = event_handler_arg;
|
||||
handler_instance->handler_ctx = context;
|
||||
|
||||
if (SLIST_EMPTY(handlers)) {
|
||||
SLIST_INSERT_HEAD(handlers, handler_instance, next);
|
||||
}
|
||||
else {
|
||||
esp_event_handler_instance_t *it = NULL, *last = NULL;
|
||||
esp_event_handler_node_t *it = NULL, *last = NULL;
|
||||
|
||||
SLIST_FOREACH(it, handlers, next) {
|
||||
if (handler == it->handler) {
|
||||
it->arg = handler_arg;
|
||||
ESP_LOGW(TAG, "handler already registered, overwriting");
|
||||
free(handler_instance);
|
||||
return ESP_OK;
|
||||
if (legacy) {
|
||||
if(event_handler == it->handler_ctx->handler) {
|
||||
it->handler_ctx->arg = event_handler_arg;
|
||||
ESP_LOGW(TAG, "handler already registered, overwriting");
|
||||
free(handler_instance);
|
||||
free(context);
|
||||
return ESP_OK;
|
||||
}
|
||||
}
|
||||
last = it;
|
||||
}
|
||||
@ -189,13 +198,24 @@ static esp_err_t handler_instances_add(esp_event_handler_instances_t* handlers,
|
||||
SLIST_INSERT_AFTER(last, handler_instance, next);
|
||||
}
|
||||
|
||||
// If the caller didn't provide the handler instance context, don't set it.
|
||||
// It will be removed once the event loop is deleted.
|
||||
if (handler_ctx) {
|
||||
*handler_ctx = context;
|
||||
}
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
static esp_err_t base_node_add_handler(esp_event_base_node_t* base_node, int32_t id, esp_event_handler_t handler, void* handler_arg)
|
||||
static esp_err_t base_node_add_handler(esp_event_base_node_t* base_node,
|
||||
int32_t id,
|
||||
esp_event_handler_t event_handler,
|
||||
void *event_handler_arg,
|
||||
esp_event_handler_instance_context_t **handler_ctx,
|
||||
bool legacy)
|
||||
{
|
||||
if (id == ESP_EVENT_ANY_ID) {
|
||||
return handler_instances_add(&(base_node->handlers), handler, handler_arg);
|
||||
return handler_instances_add(&(base_node->handlers), event_handler, event_handler_arg, handler_ctx, legacy);
|
||||
}
|
||||
else {
|
||||
esp_err_t err = ESP_OK;
|
||||
@ -220,7 +240,7 @@ static esp_err_t base_node_add_handler(esp_event_base_node_t* base_node, int32_t
|
||||
|
||||
SLIST_INIT(&(id_node->handlers));
|
||||
|
||||
err = handler_instances_add(&(id_node->handlers), handler, handler_arg);
|
||||
err = handler_instances_add(&(id_node->handlers), event_handler, event_handler_arg, handler_ctx, legacy);
|
||||
|
||||
if (err == ESP_OK) {
|
||||
if (!last_id_node) {
|
||||
@ -236,15 +256,21 @@ static esp_err_t base_node_add_handler(esp_event_base_node_t* base_node, int32_t
|
||||
return err;
|
||||
}
|
||||
else {
|
||||
return handler_instances_add(&(id_node->handlers), handler, handler_arg);
|
||||
return handler_instances_add(&(id_node->handlers), event_handler, event_handler_arg, handler_ctx, legacy);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static esp_err_t loop_node_add_handler(esp_event_loop_node_t* loop_node, esp_event_base_t base, int32_t id, esp_event_handler_t handler, void* handler_arg)
|
||||
static esp_err_t loop_node_add_handler(esp_event_loop_node_t* loop_node,
|
||||
esp_event_base_t base,
|
||||
int32_t id,
|
||||
esp_event_handler_t event_handler,
|
||||
void *event_handler_arg,
|
||||
esp_event_handler_instance_context_t **handler_ctx,
|
||||
bool legacy)
|
||||
{
|
||||
if (base == esp_event_any_base && id == ESP_EVENT_ANY_ID) {
|
||||
return handler_instances_add(&(loop_node->handlers), handler, handler_arg);
|
||||
return handler_instances_add(&(loop_node->handlers), event_handler, event_handler_arg, handler_ctx, legacy);
|
||||
}
|
||||
else {
|
||||
esp_err_t err = ESP_OK;
|
||||
@ -273,7 +299,7 @@ static esp_err_t loop_node_add_handler(esp_event_loop_node_t* loop_node, esp_eve
|
||||
SLIST_INIT(&(base_node->handlers));
|
||||
SLIST_INIT(&(base_node->id_nodes));
|
||||
|
||||
err = base_node_add_handler(base_node, id, handler, handler_arg);
|
||||
err = base_node_add_handler(base_node, id, event_handler, event_handler_arg, handler_ctx, legacy);
|
||||
|
||||
if (err == ESP_OK) {
|
||||
if (!last_base_node) {
|
||||
@ -288,20 +314,30 @@ static esp_err_t loop_node_add_handler(esp_event_loop_node_t* loop_node, esp_eve
|
||||
|
||||
return err;
|
||||
} else {
|
||||
return base_node_add_handler(base_node, id, handler, handler_arg);
|
||||
return base_node_add_handler(base_node, id, event_handler, event_handler_arg, handler_ctx, legacy);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static esp_err_t handler_instances_remove(esp_event_handler_instances_t* handlers, esp_event_handler_t handler)
|
||||
static esp_err_t handler_instances_remove(esp_event_handler_nodes_t* handlers, esp_event_handler_instance_context_t* handler_ctx, bool legacy)
|
||||
{
|
||||
esp_event_handler_instance_t *it, *temp;
|
||||
esp_event_handler_node_t *it, *temp;
|
||||
|
||||
SLIST_FOREACH_SAFE(it, handlers, next, temp) {
|
||||
if (it->handler == handler) {
|
||||
SLIST_REMOVE(handlers, it, esp_event_handler_instance, next);
|
||||
free(it);
|
||||
return ESP_OK;
|
||||
if (legacy) {
|
||||
if (it->handler_ctx->handler == handler_ctx->handler) {
|
||||
SLIST_REMOVE(handlers, it, esp_event_handler_node, next);
|
||||
free(it->handler_ctx);
|
||||
free(it);
|
||||
return ESP_OK;
|
||||
}
|
||||
} else {
|
||||
if (it->handler_ctx == handler_ctx) {
|
||||
SLIST_REMOVE(handlers, it, esp_event_handler_node, next);
|
||||
free(it->handler_ctx);
|
||||
free(it);
|
||||
return ESP_OK;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -309,16 +345,16 @@ static esp_err_t handler_instances_remove(esp_event_handler_instances_t* handler
|
||||
}
|
||||
|
||||
|
||||
static esp_err_t base_node_remove_handler(esp_event_base_node_t* base_node, int32_t id, esp_event_handler_t handler)
|
||||
static esp_err_t base_node_remove_handler(esp_event_base_node_t* base_node, int32_t id, esp_event_handler_instance_context_t* handler_ctx, bool legacy)
|
||||
{
|
||||
if (id == ESP_EVENT_ANY_ID) {
|
||||
return handler_instances_remove(&(base_node->handlers), handler);
|
||||
return handler_instances_remove(&(base_node->handlers), handler_ctx, legacy);
|
||||
}
|
||||
else {
|
||||
esp_event_id_node_t *it, *temp;
|
||||
SLIST_FOREACH_SAFE(it, &(base_node->id_nodes), next, temp) {
|
||||
if (it->id == id) {
|
||||
esp_err_t res = handler_instances_remove(&(it->handlers), handler);
|
||||
esp_err_t res = handler_instances_remove(&(it->handlers), handler_ctx, legacy);
|
||||
|
||||
if (res == ESP_OK) {
|
||||
if (SLIST_EMPTY(&(it->handlers))) {
|
||||
@ -334,16 +370,16 @@ static esp_err_t base_node_remove_handler(esp_event_base_node_t* base_node, int3
|
||||
return ESP_ERR_NOT_FOUND;
|
||||
}
|
||||
|
||||
static esp_err_t loop_node_remove_handler(esp_event_loop_node_t* loop_node, esp_event_base_t base, int32_t id, esp_event_handler_t handler)
|
||||
static esp_err_t loop_node_remove_handler(esp_event_loop_node_t* loop_node, esp_event_base_t base, int32_t id, esp_event_handler_instance_context_t* handler_ctx, bool legacy)
|
||||
{
|
||||
if (base == esp_event_any_base && id == ESP_EVENT_ANY_ID) {
|
||||
return handler_instances_remove(&(loop_node->handlers), handler);
|
||||
return handler_instances_remove(&(loop_node->handlers), handler_ctx, legacy);
|
||||
}
|
||||
else {
|
||||
esp_event_base_node_t *it, *temp;
|
||||
SLIST_FOREACH_SAFE(it, &(loop_node->base_nodes), next, temp) {
|
||||
if (it->base == base) {
|
||||
esp_err_t res = base_node_remove_handler(it, id, handler);
|
||||
esp_err_t res = base_node_remove_handler(it, id, handler_ctx, legacy);
|
||||
|
||||
if (res == ESP_OK) {
|
||||
if (SLIST_EMPTY(&(it->handlers)) && SLIST_EMPTY(&(it->id_nodes))) {
|
||||
@ -359,11 +395,12 @@ static esp_err_t loop_node_remove_handler(esp_event_loop_node_t* loop_node, esp_
|
||||
return ESP_ERR_NOT_FOUND;
|
||||
}
|
||||
|
||||
static void handler_instances_remove_all(esp_event_handler_instances_t* handlers)
|
||||
static void handler_instances_remove_all(esp_event_handler_nodes_t* handlers)
|
||||
{
|
||||
esp_event_handler_instance_t *it, *temp;
|
||||
esp_event_handler_node_t *it, *temp;
|
||||
SLIST_FOREACH_SAFE(it, handlers, next, temp) {
|
||||
SLIST_REMOVE(handlers, it, esp_event_handler_instance, next);
|
||||
SLIST_REMOVE(handlers, it, esp_event_handler_node, next);
|
||||
free(it->handler_ctx);
|
||||
free(it);
|
||||
}
|
||||
}
|
||||
@ -526,7 +563,7 @@ esp_err_t esp_event_loop_run(esp_event_loop_handle_t event_loop, TickType_t tick
|
||||
|
||||
bool exec = false;
|
||||
|
||||
esp_event_handler_instance_t *handler, *temp_handler;
|
||||
esp_event_handler_node_t *handler, *temp_handler;
|
||||
esp_event_loop_node_t *loop_node, *temp_node;
|
||||
esp_event_base_node_t *base_node, *temp_base;
|
||||
esp_event_id_node_t *id_node, *temp_id_node;
|
||||
@ -645,8 +682,9 @@ esp_err_t esp_event_loop_delete(esp_event_loop_handle_t event_loop)
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t esp_event_handler_register_with(esp_event_loop_handle_t event_loop, esp_event_base_t event_base,
|
||||
int32_t event_id, esp_event_handler_t event_handler, void* event_handler_arg)
|
||||
esp_err_t esp_event_handler_register_with_internal(esp_event_loop_handle_t event_loop, esp_event_base_t event_base,
|
||||
int32_t event_id, esp_event_handler_t event_handler, void* event_handler_arg,
|
||||
esp_event_handler_instance_context_t** handler_ctx_arg, bool legacy)
|
||||
{
|
||||
assert(event_loop);
|
||||
assert(event_handler);
|
||||
@ -687,7 +725,7 @@ esp_err_t esp_event_handler_register_with(esp_event_loop_handle_t event_loop, es
|
||||
SLIST_INIT(&(loop_node->handlers));
|
||||
SLIST_INIT(&(loop_node->base_nodes));
|
||||
|
||||
err = loop_node_add_handler(loop_node, event_base, event_id, event_handler, event_handler_arg);
|
||||
err = loop_node_add_handler(loop_node, event_base, event_id, event_handler, event_handler_arg, handler_ctx_arg, legacy);
|
||||
|
||||
if (err == ESP_OK) {
|
||||
if (!last_loop_node) {
|
||||
@ -701,7 +739,7 @@ esp_err_t esp_event_handler_register_with(esp_event_loop_handle_t event_loop, es
|
||||
}
|
||||
}
|
||||
else {
|
||||
err = loop_node_add_handler(last_loop_node, event_base, event_id, event_handler, event_handler_arg);
|
||||
err = loop_node_add_handler(last_loop_node, event_base, event_id, event_handler, event_handler_arg, handler_ctx_arg, legacy);
|
||||
}
|
||||
|
||||
on_err:
|
||||
@ -709,11 +747,24 @@ on_err:
|
||||
return err;
|
||||
}
|
||||
|
||||
esp_err_t esp_event_handler_unregister_with(esp_event_loop_handle_t event_loop, esp_event_base_t event_base,
|
||||
int32_t event_id, esp_event_handler_t event_handler)
|
||||
esp_err_t esp_event_handler_register_with(esp_event_loop_handle_t event_loop, esp_event_base_t event_base,
|
||||
int32_t event_id, esp_event_handler_t event_handler, void* event_handler_arg)
|
||||
{
|
||||
return esp_event_handler_register_with_internal(event_loop, event_base, event_id, event_handler, event_handler_arg, NULL, true);
|
||||
}
|
||||
|
||||
esp_err_t esp_event_handler_instance_register_with(esp_event_loop_handle_t event_loop, esp_event_base_t event_base,
|
||||
int32_t event_id, esp_event_handler_t event_handler, void* event_handler_arg,
|
||||
esp_event_handler_instance_t* handler_ctx_arg)
|
||||
{
|
||||
return esp_event_handler_register_with_internal(event_loop, event_base, event_id, event_handler, event_handler_arg, (esp_event_handler_instance_context_t**) handler_ctx_arg, false);
|
||||
}
|
||||
|
||||
esp_err_t esp_event_handler_unregister_with_internal(esp_event_loop_handle_t event_loop, esp_event_base_t event_base,
|
||||
int32_t event_id, esp_event_handler_instance_context_t* handler_ctx, bool legacy)
|
||||
{
|
||||
assert(event_loop);
|
||||
assert(event_handler);
|
||||
assert(handler_ctx);
|
||||
|
||||
if (event_base == ESP_EVENT_ANY_BASE && event_id != ESP_EVENT_ANY_ID) {
|
||||
ESP_LOGE(TAG, "unregistering to any event base with specific id unsupported");
|
||||
@ -731,7 +782,7 @@ esp_err_t esp_event_handler_unregister_with(esp_event_loop_handle_t event_loop,
|
||||
esp_event_loop_node_t *it, *temp;
|
||||
|
||||
SLIST_FOREACH_SAFE(it, &(loop->loop_nodes), next, temp) {
|
||||
esp_err_t res = loop_node_remove_handler(it, event_base, event_id, event_handler);
|
||||
esp_err_t res = loop_node_remove_handler(it, event_base, event_id, handler_ctx, legacy);
|
||||
|
||||
if (res == ESP_OK && SLIST_EMPTY(&(it->base_nodes)) && SLIST_EMPTY(&(it->handlers))) {
|
||||
SLIST_REMOVE(&(loop->loop_nodes), it, esp_event_loop_node, next);
|
||||
@ -745,6 +796,24 @@ esp_err_t esp_event_handler_unregister_with(esp_event_loop_handle_t event_loop,
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t esp_event_handler_unregister_with(esp_event_loop_handle_t event_loop, esp_event_base_t event_base,
|
||||
int32_t event_id, esp_event_handler_t event_handler)
|
||||
{
|
||||
esp_event_handler_instance_context_t local_handler_ctx;
|
||||
local_handler_ctx.handler = event_handler;
|
||||
local_handler_ctx.arg = NULL;
|
||||
|
||||
return esp_event_handler_unregister_with_internal(event_loop, event_base, event_id, &local_handler_ctx, true);
|
||||
}
|
||||
|
||||
esp_err_t esp_event_handler_instance_unregister_with(esp_event_loop_handle_t event_loop, esp_event_base_t event_base,
|
||||
int32_t event_id, esp_event_handler_instance_t handler_ctx_arg)
|
||||
{
|
||||
if (!handler_ctx_arg) return ESP_ERR_INVALID_ARG;
|
||||
|
||||
return esp_event_handler_unregister_with_internal(event_loop, event_base, event_id, (esp_event_handler_instance_context_t*) handler_ctx_arg, false);
|
||||
}
|
||||
|
||||
esp_err_t esp_event_post_to(esp_event_loop_handle_t event_loop, esp_event_base_t event_base, int32_t event_id,
|
||||
void* event_data, size_t event_data_size, TickType_t ticks_to_wait)
|
||||
{
|
||||
@ -879,7 +948,7 @@ esp_err_t esp_event_dump(FILE* file)
|
||||
esp_event_loop_node_t *loop_node_it;
|
||||
esp_event_base_node_t* base_node_it;
|
||||
esp_event_id_node_t* id_node_it;
|
||||
esp_event_handler_instance_t* handler_it;
|
||||
esp_event_handler_node_t* handler_it;
|
||||
|
||||
// Allocate memory for printing
|
||||
int sz = esp_event_dump_prepare();
|
||||
@ -904,13 +973,13 @@ esp_err_t esp_event_dump(FILE* file)
|
||||
|
||||
SLIST_FOREACH(loop_node_it, &(loop_it->loop_nodes), next) {
|
||||
SLIST_FOREACH(handler_it, &(loop_node_it->handlers), next) {
|
||||
PRINT_DUMP_INFO(dst, sz, HANDLER_DUMP_FORMAT, handler_it->handler, "ESP_EVENT_ANY_BASE",
|
||||
PRINT_DUMP_INFO(dst, sz, HANDLER_DUMP_FORMAT, handler_it->handler_ctx->handler, "ESP_EVENT_ANY_BASE",
|
||||
"ESP_EVENT_ANY_ID", handler_it->invoked, handler_it->time);
|
||||
}
|
||||
|
||||
SLIST_FOREACH(base_node_it, &(loop_node_it->base_nodes), next) {
|
||||
SLIST_FOREACH(handler_it, &(base_node_it->handlers), next) {
|
||||
PRINT_DUMP_INFO(dst, sz, HANDLER_DUMP_FORMAT, handler_it->handler, base_node_it->base ,
|
||||
PRINT_DUMP_INFO(dst, sz, HANDLER_DUMP_FORMAT, handler_it->handler_ctx->handler, base_node_it->base ,
|
||||
"ESP_EVENT_ANY_ID", handler_it->invoked, handler_it->time);
|
||||
}
|
||||
|
||||
@ -919,7 +988,7 @@ esp_err_t esp_event_dump(FILE* file)
|
||||
memset(id_str_buf, 0, sizeof(id_str_buf));
|
||||
snprintf(id_str_buf, sizeof(id_str_buf), "%d", id_node_it->id);
|
||||
|
||||
PRINT_DUMP_INFO(dst, sz, HANDLER_DUMP_FORMAT, handler_it->handler, base_node_it->base ,
|
||||
PRINT_DUMP_INFO(dst, sz, HANDLER_DUMP_FORMAT, handler_it->handler_ctx->handler, base_node_it->base ,
|
||||
id_str_buf, handler_it->invoked, handler_it->time);
|
||||
}
|
||||
}
|
||||
|
@ -26,11 +26,11 @@ bool esp_event_is_handler_registered(esp_event_loop_handle_t event_loop, esp_eve
|
||||
esp_event_loop_node_t* loop_node;
|
||||
esp_event_base_node_t* base_node;
|
||||
esp_event_id_node_t* id_node;
|
||||
esp_event_handler_instance_t* handler;
|
||||
esp_event_handler_node_t* handler;
|
||||
|
||||
SLIST_FOREACH(loop_node, &(loop->loop_nodes), next) {
|
||||
SLIST_FOREACH(handler, &(loop_node->handlers), next) {
|
||||
if(event_base == ESP_EVENT_ANY_BASE && event_id == ESP_EVENT_ANY_ID && handler->handler == event_handler)
|
||||
if(event_base == ESP_EVENT_ANY_BASE && event_id == ESP_EVENT_ANY_ID && handler->handler_ctx->handler == event_handler)
|
||||
{
|
||||
result = true;
|
||||
goto out;
|
||||
@ -40,7 +40,7 @@ bool esp_event_is_handler_registered(esp_event_loop_handle_t event_loop, esp_eve
|
||||
SLIST_FOREACH(base_node, &(loop_node->base_nodes), next) {
|
||||
if (base_node->base == event_base) {
|
||||
SLIST_FOREACH(handler, &(base_node->handlers), next) {
|
||||
if(event_id == ESP_EVENT_ANY_ID && handler->handler == event_handler)
|
||||
if(event_id == ESP_EVENT_ANY_ID && handler->handler_ctx->handler == event_handler)
|
||||
{
|
||||
result = true;
|
||||
goto out;
|
||||
@ -50,12 +50,12 @@ bool esp_event_is_handler_registered(esp_event_loop_handle_t event_loop, esp_eve
|
||||
SLIST_FOREACH(id_node, &(base_node->id_nodes), next) {
|
||||
if(id_node->id == event_id) {
|
||||
SLIST_FOREACH(handler, &(id_node->handlers), next) {
|
||||
if(handler->handler == event_handler)
|
||||
if(handler->handler_ctx->handler == event_handler)
|
||||
{
|
||||
result = true;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -65,4 +65,4 @@ bool esp_event_is_handler_registered(esp_event_loop_handle_t event_loop, esp_eve
|
||||
out:
|
||||
xSemaphoreGive(loop->mutex);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
@ -32,7 +32,7 @@ extern "C" {
|
||||
/// Configuration for creating event loops
|
||||
typedef struct {
|
||||
int32_t queue_size; /**< size of the event loop queue */
|
||||
const char* task_name; /**< name of the event loop task; if NULL,
|
||||
const char *task_name; /**< name of the event loop task; if NULL,
|
||||
a dedicated task is not created for event loop*/
|
||||
UBaseType_t task_priority; /**< priority of the event loop task, ignored if task name is NULL */
|
||||
uint32_t task_stack_size; /**< stack size of the event loop task, ignored if task name is NULL */
|
||||
@ -52,7 +52,7 @@ typedef struct {
|
||||
* - ESP_FAIL: Failed to create task loop
|
||||
* - Others: Fail
|
||||
*/
|
||||
esp_err_t esp_event_loop_create(const esp_event_loop_args_t* event_loop_args, esp_event_loop_handle_t* event_loop);
|
||||
esp_err_t esp_event_loop_create(const esp_event_loop_args_t *event_loop_args, esp_event_loop_handle_t *event_loop);
|
||||
|
||||
/**
|
||||
* @brief Delete an existing event loop.
|
||||
@ -114,7 +114,10 @@ esp_err_t esp_event_loop_delete_default(void);
|
||||
esp_err_t esp_event_loop_run(esp_event_loop_handle_t event_loop, TickType_t ticks_to_run);
|
||||
|
||||
/**
|
||||
* @brief Register an event handler to the system event loop.
|
||||
* @brief Register an event handler to the system event loop (legacy).
|
||||
*
|
||||
* @note This function is obsolete and will be deprecated soon, please use esp_event_handler_instance_register()
|
||||
* instead.
|
||||
*
|
||||
* This function can be used to register a handler for either: (1) specific events,
|
||||
* (2) all events of a certain event base, or (3) all events known by the system event loop.
|
||||
@ -142,12 +145,15 @@ esp_err_t esp_event_loop_run(esp_event_loop_handle_t event_loop, TickType_t tick
|
||||
* - Others: Fail
|
||||
*/
|
||||
esp_err_t esp_event_handler_register(esp_event_base_t event_base,
|
||||
int32_t event_id,
|
||||
esp_event_handler_t event_handler,
|
||||
void* event_handler_arg);
|
||||
int32_t event_id,
|
||||
esp_event_handler_t event_handler,
|
||||
void *event_handler_arg);
|
||||
|
||||
/**
|
||||
* @brief Register an event handler to a specific loop.
|
||||
* @brief Register an event handler to a specific loop (legacy).
|
||||
*
|
||||
* @note This function is obsolete and will be deprecated soon, please use esp_event_handler_instance_register_with()
|
||||
* instead.
|
||||
*
|
||||
* This function behaves in the same manner as esp_event_handler_register, except the additional
|
||||
* specification of the event loop to register the handler to.
|
||||
@ -168,13 +174,94 @@ esp_err_t esp_event_handler_register(esp_event_base_t event_base,
|
||||
* - Others: Fail
|
||||
*/
|
||||
esp_err_t esp_event_handler_register_with(esp_event_loop_handle_t event_loop,
|
||||
esp_event_base_t event_base,
|
||||
int32_t event_id,
|
||||
esp_event_handler_t event_handler,
|
||||
void* event_handler_arg);
|
||||
esp_event_base_t event_base,
|
||||
int32_t event_id,
|
||||
esp_event_handler_t event_handler,
|
||||
void *event_handler_arg);
|
||||
|
||||
/**
|
||||
* @brief Unregister a handler with the system event loop.
|
||||
* @brief Register an instance of event handler to a specific loop.
|
||||
*
|
||||
* This function can be used to register a handler for either: (1) specific events,
|
||||
* (2) all events of a certain event base, or (3) all events known by the system event loop.
|
||||
*
|
||||
* - specific events: specify exact event_base and event_id
|
||||
* - all events of a certain base: specify exact event_base and use ESP_EVENT_ANY_ID as the event_id
|
||||
* - all events known by the loop: use ESP_EVENT_ANY_BASE for event_base and ESP_EVENT_ANY_ID as the event_id
|
||||
*
|
||||
* Besides the error, the function returns an instance object as output parameter to identify each registration.
|
||||
* This is necessary to remove (unregister) the registration before the event loop is deleted.
|
||||
*
|
||||
* Registering multiple handlers to events, registering a single handler to multiple events as well as registering
|
||||
* the same handler to the same event multiple times is possible.
|
||||
* Each registration yields a distinct instance object which identifies it over the registration
|
||||
* lifetime.
|
||||
*
|
||||
* @param[in] event_loop the event loop to register this handler function to
|
||||
* @param[in] event_base the base id of the event to register the handler for
|
||||
* @param[in] event_id the id of the event to register the handler for
|
||||
* @param[in] event_handler the handler function which gets called when the event is dispatched
|
||||
* @param[in] event_handler_arg data, aside from event data, that is passed to the handler when it is called
|
||||
* @param[out] instance An event handler instance object related to the registered event handler and data, can be NULL.
|
||||
* This needs to be kept if the specific callback instance should be unregistered before deleting the whole
|
||||
* event loop. Registering the same event handler multiple times is possible and yields distinct instance
|
||||
* objects. The data can be the same for all registrations.
|
||||
* If no unregistration is needed but the handler should be deleted when the event loop is deleted,
|
||||
* instance can be NULL.
|
||||
*
|
||||
* @note the event loop library does not maintain a copy of event_handler_arg, therefore the user should
|
||||
* ensure that event_handler_arg still points to a valid location by the time the handler gets called
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK: Success
|
||||
* - ESP_ERR_NO_MEM: Cannot allocate memory for the handler
|
||||
* - ESP_ERR_INVALID_ARG: Invalid combination of event base and event id or instance is NULL
|
||||
* - Others: Fail
|
||||
*/
|
||||
esp_err_t esp_event_handler_instance_register_with(esp_event_loop_handle_t event_loop,
|
||||
esp_event_base_t event_base,
|
||||
int32_t event_id,
|
||||
esp_event_handler_t event_handler,
|
||||
void *event_handler_arg,
|
||||
esp_event_handler_instance_t *instance);
|
||||
|
||||
/**
|
||||
* @brief Register an instance of event handler to the default loop.
|
||||
*
|
||||
* This function does the same as esp_event_handler_instance_register_with, except that it registers the
|
||||
* handler to the default event loop.
|
||||
*
|
||||
* @param[in] event_base the base id of the event to register the handler for
|
||||
* @param[in] event_id the id of the event to register the handler for
|
||||
* @param[in] event_handler the handler function which gets called when the event is dispatched
|
||||
* @param[in] event_handler_arg data, aside from event data, that is passed to the handler when it is called
|
||||
* @param[out] instance An event handler instance object related to the registered event handler and data, can be NULL.
|
||||
* This needs to be kept if the specific callback instance should be unregistered before deleting the whole
|
||||
* event loop. Registering the same event handler multiple times is possible and yields distinct instance
|
||||
* objects. The data can be the same for all registrations.
|
||||
* If no unregistration is needed but the handler should be deleted when the event loop is deleted,
|
||||
* instance can be NULL.
|
||||
*
|
||||
* @note the event loop library does not maintain a copy of event_handler_arg, therefore the user should
|
||||
* ensure that event_handler_arg still points to a valid location by the time the handler gets called
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK: Success
|
||||
* - ESP_ERR_NO_MEM: Cannot allocate memory for the handler
|
||||
* - ESP_ERR_INVALID_ARG: Invalid combination of event base and event id or instance is NULL
|
||||
* - Others: Fail
|
||||
*/
|
||||
esp_err_t esp_event_handler_instance_register(esp_event_base_t event_base,
|
||||
int32_t event_id,
|
||||
esp_event_handler_t event_handler,
|
||||
void *event_handler_arg,
|
||||
esp_event_handler_instance_t *instance);
|
||||
|
||||
/**
|
||||
* @brief Unregister a handler with the system event loop (legacy).
|
||||
*
|
||||
* @note This function is obsolete and will be deprecated soon, please use esp_event_handler_instance_unregister()
|
||||
* instead.
|
||||
*
|
||||
* This function can be used to unregister a handler so that it no longer gets called during dispatch.
|
||||
* Handlers can be unregistered for either: (1) specific events, (2) all events of a certain event base,
|
||||
@ -194,10 +281,15 @@ esp_err_t esp_event_handler_register_with(esp_event_loop_handle_t event_loop,
|
||||
* @return ESP_ERR_INVALID_ARG invalid combination of event base and event id
|
||||
* @return others fail
|
||||
*/
|
||||
esp_err_t esp_event_handler_unregister(esp_event_base_t event_base, int32_t event_id, esp_event_handler_t event_handler);
|
||||
esp_err_t esp_event_handler_unregister(esp_event_base_t event_base,
|
||||
int32_t event_id,
|
||||
esp_event_handler_t event_handler);
|
||||
|
||||
/**
|
||||
* @brief Unregister a handler with the system event loop.
|
||||
* @brief Unregister a handler from a specific event loop (legacy).
|
||||
*
|
||||
* @note This function is obsolete and will be deprecated soon, please use esp_event_handler_instance_unregister_with()
|
||||
* instead.
|
||||
*
|
||||
* This function behaves in the same manner as esp_event_handler_unregister, except the additional specification of
|
||||
* the event loop to unregister the handler with.
|
||||
@ -217,6 +309,53 @@ esp_err_t esp_event_handler_unregister_with(esp_event_loop_handle_t event_loop,
|
||||
int32_t event_id,
|
||||
esp_event_handler_t event_handler);
|
||||
|
||||
/**
|
||||
* @brief Unregister a handler instance from a specific event loop.
|
||||
*
|
||||
* This function can be used to unregister a handler so that it no longer gets called during dispatch.
|
||||
* Handlers can be unregistered for either: (1) specific events, (2) all events of a certain event base,
|
||||
* or (3) all events known by the system event loop
|
||||
*
|
||||
* - specific events: specify exact event_base and event_id
|
||||
* - all events of a certain base: specify exact event_base and use ESP_EVENT_ANY_ID as the event_id
|
||||
* - all events known by the loop: use ESP_EVENT_ANY_BASE for event_base and ESP_EVENT_ANY_ID as the event_id
|
||||
*
|
||||
* This function ignores unregistration of handler instances that have not been previously registered.
|
||||
*
|
||||
* @param[in] event_loop the event loop with which to unregister this handler function
|
||||
* @param[in] event_base the base of the event with which to unregister the handler
|
||||
* @param[in] event_id the id of the event with which to unregister the handler
|
||||
* @param[in] instance the instance object of the registration to be unregistered
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK: Success
|
||||
* - ESP_ERR_INVALID_ARG: Invalid combination of event base and event id
|
||||
* - Others: Fail
|
||||
*/
|
||||
esp_err_t esp_event_handler_instance_unregister_with(esp_event_loop_handle_t event_loop,
|
||||
esp_event_base_t event_base,
|
||||
int32_t event_id,
|
||||
esp_event_handler_instance_t instance);
|
||||
|
||||
/**
|
||||
* @brief Unregister a handler from the system event loop.
|
||||
*
|
||||
* This function does the same as esp_event_handler_instance_unregister_with, except that it unregisters the
|
||||
* handler instance from the default event loop.
|
||||
*
|
||||
* @param[in] event_base the base of the event with which to unregister the handler
|
||||
* @param[in] event_id the id of the event with which to unregister the handler
|
||||
* @param[in] instance the instance object of the registration to be unregistered
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK: Success
|
||||
* - ESP_ERR_INVALID_ARG: Invalid combination of event base and event id
|
||||
* - Others: Fail
|
||||
*/
|
||||
esp_err_t esp_event_handler_instance_unregister(esp_event_base_t event_base,
|
||||
int32_t event_id,
|
||||
esp_event_handler_instance_t instance);
|
||||
|
||||
/**
|
||||
* @brief Posts an event to the system default event loop. The event loop library keeps a copy of event_data and manages
|
||||
* the copy's lifetime automatically (allocation + deletion); this ensures that the data the
|
||||
@ -230,16 +369,16 @@ esp_err_t esp_event_handler_unregister_with(esp_event_loop_handle_t event_loop,
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK: Success
|
||||
* - ESP_ERR_TIMEOUT: Time to wait for event queue to unblock expired,
|
||||
* - ESP_ERR_TIMEOUT: Time to wait for event queue to unblock expired,
|
||||
* queue full when posting from ISR
|
||||
* - ESP_ERR_INVALID_ARG: Invalid combination of event base and event id
|
||||
* - Others: Fail
|
||||
*/
|
||||
esp_err_t esp_event_post(esp_event_base_t event_base,
|
||||
int32_t event_id,
|
||||
void* event_data,
|
||||
size_t event_data_size,
|
||||
TickType_t ticks_to_wait);
|
||||
int32_t event_id,
|
||||
void *event_data,
|
||||
size_t event_data_size,
|
||||
TickType_t ticks_to_wait);
|
||||
|
||||
/**
|
||||
* @brief Posts an event to the specified event loop. The event loop library keeps a copy of event_data and manages
|
||||
@ -258,7 +397,7 @@ esp_err_t esp_event_post(esp_event_base_t event_base,
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK: Success
|
||||
* - ESP_ERR_TIMEOUT: Time to wait for event queue to unblock expired,
|
||||
* - ESP_ERR_TIMEOUT: Time to wait for event queue to unblock expired,
|
||||
* queue full when posting from ISR
|
||||
* - ESP_ERR_INVALID_ARG: Invalid combination of event base and event id
|
||||
* - Others: Fail
|
||||
@ -266,19 +405,19 @@ esp_err_t esp_event_post(esp_event_base_t event_base,
|
||||
esp_err_t esp_event_post_to(esp_event_loop_handle_t event_loop,
|
||||
esp_event_base_t event_base,
|
||||
int32_t event_id,
|
||||
void* event_data,
|
||||
void *event_data,
|
||||
size_t event_data_size,
|
||||
TickType_t ticks_to_wait);
|
||||
|
||||
#if CONFIG_ESP_EVENT_POST_FROM_ISR
|
||||
/**
|
||||
* @brief Special variant of esp_event_post for posting events from interrupt handlers.
|
||||
*
|
||||
*
|
||||
* @param[in] event_base the event base that identifies the event
|
||||
* @param[in] event_id the event id that identifies the event
|
||||
* @param[in] event_data the data, specific to the event occurence, that gets passed to the handler
|
||||
* @param[in] event_data_size the size of the event data; max is 4 bytes
|
||||
* @param[out] task_unblocked an optional parameter (can be NULL) which indicates that an event task with
|
||||
* @param[out] task_unblocked an optional parameter (can be NULL) which indicates that an event task with
|
||||
* higher priority than currently running task has been unblocked by the posted event;
|
||||
* a context switch should be requested before the interrupt is existed.
|
||||
*
|
||||
@ -290,14 +429,14 @@ esp_err_t esp_event_post_to(esp_event_loop_handle_t event_loop,
|
||||
* - ESP_OK: Success
|
||||
* - ESP_FAIL: Event queue for the default event loop full
|
||||
* - ESP_ERR_INVALID_ARG: Invalid combination of event base and event id,
|
||||
* data size of more than 4 bytes
|
||||
* data size of more than 4 bytes
|
||||
* - Others: Fail
|
||||
*/
|
||||
esp_err_t esp_event_isr_post(esp_event_base_t event_base,
|
||||
int32_t event_id,
|
||||
void* event_data,
|
||||
size_t event_data_size,
|
||||
BaseType_t* task_unblocked);
|
||||
int32_t event_id,
|
||||
void *event_data,
|
||||
size_t event_data_size,
|
||||
BaseType_t *task_unblocked);
|
||||
|
||||
/**
|
||||
* @brief Special variant of esp_event_post_to for posting events from interrupt handlers
|
||||
@ -307,7 +446,7 @@ esp_err_t esp_event_isr_post(esp_event_base_t event_base,
|
||||
* @param[in] event_id the event id that identifies the event
|
||||
* @param[in] event_data the data, specific to the event occurence, that gets passed to the handler
|
||||
* @param[in] event_data_size the size of the event data
|
||||
* @param[out] task_unblocked an optional parameter (can be NULL) which indicates that an event task with
|
||||
* @param[out] task_unblocked an optional parameter (can be NULL) which indicates that an event task with
|
||||
* higher priority than currently running task has been unblocked by the posted event;
|
||||
* a context switch should be requested before the interrupt is existed.
|
||||
*
|
||||
@ -319,15 +458,15 @@ esp_err_t esp_event_isr_post(esp_event_base_t event_base,
|
||||
* - ESP_OK: Success
|
||||
* - ESP_FAIL: Event queue for the loop full
|
||||
* - ESP_ERR_INVALID_ARG: Invalid combination of event base and event id,
|
||||
* data size of more than 4 bytes
|
||||
* data size of more than 4 bytes
|
||||
* - Others: Fail
|
||||
*/
|
||||
esp_err_t esp_event_isr_post_to(esp_event_loop_handle_t event_loop,
|
||||
esp_event_base_t event_base,
|
||||
int32_t event_id,
|
||||
void* event_data,
|
||||
size_t event_data_size,
|
||||
BaseType_t* task_unblocked);
|
||||
esp_event_base_t event_base,
|
||||
int32_t event_id,
|
||||
void *event_data,
|
||||
size_t event_data_size,
|
||||
BaseType_t *task_unblocked);
|
||||
#endif
|
||||
|
||||
/**
|
||||
@ -374,7 +513,7 @@ esp_err_t esp_event_isr_post_to(esp_event_loop_handle_t event_loop,
|
||||
* - ESP_ERR_NO_MEM: Cannot allocate memory for event loops list
|
||||
* - Others: Fail
|
||||
*/
|
||||
esp_err_t esp_event_dump(FILE* file);
|
||||
esp_err_t esp_event_dump(FILE *file);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
|
@ -26,11 +26,11 @@ extern "C" {
|
||||
// Event loop library types
|
||||
typedef const char* esp_event_base_t; /**< unique pointer to a subsystem that exposes events */
|
||||
typedef void* esp_event_loop_handle_t; /**< a number that identifies an event with respect to a base */
|
||||
typedef void (*esp_event_handler_t)(void* event_handler_arg,
|
||||
esp_event_base_t event_base,
|
||||
int32_t event_id,
|
||||
typedef void (*esp_event_handler_t)(void* event_handler_arg,
|
||||
esp_event_base_t event_base,
|
||||
int32_t event_id,
|
||||
void* event_data); /**< function called when an event is posted to the queue */
|
||||
|
||||
typedef void* esp_event_handler_instance_t; /**< context identifying an instance of a registered event handler */
|
||||
|
||||
// Defines for registering/unregistering event handlers
|
||||
#define ESP_EVENT_ANY_BASE NULL /**< register handler for any event base */
|
||||
|
@ -24,23 +24,27 @@ extern "C" {
|
||||
|
||||
typedef SLIST_HEAD(base_nodes, base_node) base_nodes_t;
|
||||
|
||||
/// Event handler
|
||||
typedef struct esp_event_handler_instance {
|
||||
typedef struct esp_event_handler_context {
|
||||
esp_event_handler_t handler; /**< event handler function*/
|
||||
void* arg; /**< event handler argument */
|
||||
void* arg;
|
||||
} esp_event_handler_instance_context_t; /**< event handler argument */
|
||||
|
||||
/// Event handler
|
||||
typedef struct esp_event_handler_node {
|
||||
esp_event_handler_instance_context_t* handler_ctx; /**< event handler context*/
|
||||
#ifdef CONFIG_ESP_EVENT_LOOP_PROFILING
|
||||
uint32_t invoked; /**< number of times this handler has been invoked */
|
||||
int64_t time; /**< total runtime of this handler across all calls */
|
||||
#endif
|
||||
SLIST_ENTRY(esp_event_handler_instance) next; /**< next event handler in the list */
|
||||
} esp_event_handler_instance_t;
|
||||
SLIST_ENTRY(esp_event_handler_node) next; /**< next event handler in the list */
|
||||
} esp_event_handler_node_t;
|
||||
|
||||
typedef SLIST_HEAD(esp_event_handler_instances, esp_event_handler_instance) esp_event_handler_instances_t;
|
||||
typedef SLIST_HEAD(esp_event_handler_instances, esp_event_handler_node) esp_event_handler_nodes_t;
|
||||
|
||||
/// Event
|
||||
typedef struct esp_event_id_node {
|
||||
int32_t id; /**< id number of the event */
|
||||
esp_event_handler_instances_t handlers; /**< list of handlers to be executed when
|
||||
esp_event_handler_nodes_t handlers; /**< list of handlers to be executed when
|
||||
this event is raised */
|
||||
SLIST_ENTRY(esp_event_id_node) next; /**< pointer to the next event node on the linked list */
|
||||
} esp_event_id_node_t;
|
||||
@ -49,7 +53,7 @@ typedef SLIST_HEAD(esp_event_id_nodes, esp_event_id_node) esp_event_id_nodes_t;
|
||||
|
||||
typedef struct esp_event_base_node {
|
||||
esp_event_base_t base; /**< base identifier of the event */
|
||||
esp_event_handler_instances_t handlers; /**< event base level handlers, handlers for
|
||||
esp_event_handler_nodes_t handlers; /**< event base level handlers, handlers for
|
||||
all events with this base */
|
||||
esp_event_id_nodes_t id_nodes; /**< list of event ids with this base */
|
||||
SLIST_ENTRY(esp_event_base_node) next; /**< pointer to the next base node on the linked list */
|
||||
@ -58,7 +62,7 @@ typedef struct esp_event_base_node {
|
||||
typedef SLIST_HEAD(esp_event_base_nodes, esp_event_base_node) esp_event_base_nodes_t;
|
||||
|
||||
typedef struct esp_event_loop_node {
|
||||
esp_event_handler_instances_t handlers; /** event loop level handlers */
|
||||
esp_event_handler_nodes_t handlers; /** event loop level handlers */
|
||||
esp_event_base_nodes_t base_nodes; /** list of event bases registered to the loop */
|
||||
SLIST_ENTRY(esp_event_loop_node) next; /** pointer to the next loop node containing
|
||||
event loop level handlers and the rest of
|
||||
|
157
components/esp_event/test/test_default_loop.c
Normal file
157
components/esp_event/test/test_default_loop.c
Normal file
@ -0,0 +1,157 @@
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "esp_event.h"
|
||||
#include "sdkconfig.h"
|
||||
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
#include "esp_log.h"
|
||||
#include "driver/periph_ctrl.h"
|
||||
#include "driver/timer.h"
|
||||
|
||||
#include "esp_event.h"
|
||||
#include "esp_event_private.h"
|
||||
#include "esp_event_internal.h"
|
||||
|
||||
#include "esp_heap_caps.h"
|
||||
|
||||
#include "sdkconfig.h"
|
||||
#include "unity.h"
|
||||
|
||||
#include "test_utils.h"
|
||||
|
||||
typedef struct {
|
||||
void* data;
|
||||
SemaphoreHandle_t mutex;
|
||||
} simple_arg_t;
|
||||
|
||||
static const char* TAG = "test_event";
|
||||
|
||||
ESP_EVENT_DECLARE_BASE(s_default_test_base1);
|
||||
ESP_EVENT_DECLARE_BASE(s_default_test_base2);
|
||||
|
||||
ESP_EVENT_DEFINE_BASE(s_default_test_base1);
|
||||
ESP_EVENT_DEFINE_BASE(s_default_test_base2);
|
||||
|
||||
enum {
|
||||
TEST_EVENT_BASE1_EV1,
|
||||
TEST_EVENT_BASE1_EV2,
|
||||
TEST_EVENT_BASE1_MAX
|
||||
};
|
||||
|
||||
enum {
|
||||
TEST_EVENT_BASE2_EV1,
|
||||
TEST_EVENT_BASE2_EV2,
|
||||
TEST_EVENT_BASE2_MAX
|
||||
};
|
||||
|
||||
// The initial logging "initializing test" is to ensure mutex allocation is not counted against memory not being freed
|
||||
// during teardown.
|
||||
#define TEST_SETUP() \
|
||||
ESP_LOGI(TAG, "initializing test");
|
||||
|
||||
static void test_event_simple_handler(void* event_handler_arg, esp_event_base_t event_base, int32_t event_id, void* event_data)
|
||||
{
|
||||
if (!event_handler_arg) {
|
||||
return;
|
||||
}
|
||||
simple_arg_t* arg = (simple_arg_t*) event_handler_arg;
|
||||
xSemaphoreTake(arg->mutex, portMAX_DELAY);
|
||||
|
||||
int* count = (int*) arg->data;
|
||||
|
||||
if (event_data == NULL) {
|
||||
(*count)++;
|
||||
} else {
|
||||
(*count) += *((int*) event_data);
|
||||
}
|
||||
|
||||
xSemaphoreGive(arg->mutex);
|
||||
}
|
||||
|
||||
TEST_CASE("default loop: can create and delete loop", "[event]")
|
||||
{
|
||||
TEST_SETUP();
|
||||
|
||||
TEST_ESP_OK(esp_event_loop_create_default());
|
||||
|
||||
TEST_ESP_OK(esp_event_loop_delete_default());
|
||||
}
|
||||
|
||||
TEST_CASE("default loop: registering fails on uninitialized default loop", "[event]")
|
||||
{
|
||||
TEST_SETUP();
|
||||
|
||||
esp_event_handler_instance_t instance;
|
||||
TEST_ASSERT_EQUAL(ESP_ERR_INVALID_STATE, esp_event_handler_instance_register(s_default_test_base1,
|
||||
TEST_EVENT_BASE1_EV1,
|
||||
test_event_simple_handler,
|
||||
NULL,
|
||||
&instance));
|
||||
}
|
||||
|
||||
TEST_CASE("default loop: registering/unregistering event works", "[event]")
|
||||
{
|
||||
TEST_SETUP();
|
||||
|
||||
int count = 0;
|
||||
|
||||
simple_arg_t arg = {
|
||||
.data = &count,
|
||||
.mutex = xSemaphoreCreateMutex()
|
||||
};
|
||||
|
||||
TEST_ESP_OK(esp_event_loop_create_default());
|
||||
|
||||
esp_event_handler_instance_t instance;
|
||||
TEST_ESP_OK(esp_event_handler_instance_register(s_default_test_base1,
|
||||
TEST_EVENT_BASE1_EV1,
|
||||
test_event_simple_handler,
|
||||
&arg,
|
||||
&instance));
|
||||
TEST_ASSERT(instance);
|
||||
TEST_ESP_OK(esp_event_post(s_default_test_base1, TEST_EVENT_BASE1_EV1, NULL, 0, portMAX_DELAY));
|
||||
|
||||
vTaskDelay(10);
|
||||
|
||||
TEST_ASSERT_EQUAL(1, count);
|
||||
|
||||
TEST_ESP_OK(esp_event_handler_instance_unregister(s_default_test_base1,
|
||||
TEST_EVENT_BASE1_EV1,
|
||||
&instance));
|
||||
|
||||
vTaskDelay(10);
|
||||
|
||||
TEST_ASSERT_EQUAL(1, count);
|
||||
|
||||
TEST_ESP_OK(esp_event_loop_delete_default());
|
||||
|
||||
vSemaphoreDelete(arg.mutex);
|
||||
}
|
||||
|
||||
TEST_CASE("default event loop: registering event handler instance without instance context works", "[event]") {
|
||||
TEST_SETUP();
|
||||
|
||||
int count_1 = 0;
|
||||
|
||||
simple_arg_t arg_1 = {
|
||||
.data = &count_1,
|
||||
.mutex = xSemaphoreCreateMutex()
|
||||
};
|
||||
|
||||
TEST_ESP_OK(esp_event_loop_create_default());
|
||||
|
||||
TEST_ESP_OK(esp_event_handler_instance_register(ESP_EVENT_ANY_BASE, ESP_EVENT_ANY_ID, test_event_simple_handler, &arg_1, NULL));
|
||||
|
||||
TEST_ESP_OK(esp_event_post(s_default_test_base1, TEST_EVENT_BASE1_EV1, NULL, 0, portMAX_DELAY));
|
||||
|
||||
vTaskDelay(10);
|
||||
|
||||
TEST_ASSERT_EQUAL(1, count_1);
|
||||
|
||||
TEST_ESP_OK(esp_event_loop_delete_default());
|
||||
|
||||
vSemaphoreDelete(arg_1.mutex);
|
||||
}
|
File diff suppressed because it is too large
Load Diff
@ -345,7 +345,7 @@ UT_001:
|
||||
|
||||
UT_002:
|
||||
extends: .unit_test_template
|
||||
parallel: 10
|
||||
parallel: 12
|
||||
tags:
|
||||
- ESP32_IDF
|
||||
- UT_T1_1
|
||||
|
Loading…
Reference in New Issue
Block a user