Merge branch 'bugfix/esp_event_unregistration_issue' into 'master'

esp_event: fix issue with post data preparation

Closes #76

See merge request idf/esp-idf!5007
This commit is contained in:
Ivan Grokhotkov 2019-05-22 12:26:47 +08:00
commit 1466f37a9b
3 changed files with 58 additions and 14 deletions

View file

@ -132,8 +132,18 @@ static void handler_execute(esp_event_loop_instance_t* loop, esp_event_handler_i
#endif
// Execute the handler
#if CONFIG_ESP_EVENT_POST_FROM_ISR
(*(handler->handler))(handler->arg, post.base, post.id, post.data_allocd ? post.data.ptr : &post.data.val);
#else
void* data_ptr = NULL;
if (post.data_set) {
if (post.data_allocated) {
data_ptr = post.data.ptr;
} else {
data_ptr = &post.data.val;
}
}
(*(handler->handler))(handler->arg, post.base, post.id, data_ptr);
#else
(*(handler->handler))(handler->arg, post.base, post.id, post.data);
#endif
@ -160,7 +170,7 @@ static esp_err_t handler_instances_add(esp_event_handler_instances_t* handlers,
handler_instance->handler = handler;
handler_instance->arg = handler_arg;
if(SLIST_EMPTY(handlers)) {
if (SLIST_EMPTY(handlers)) {
SLIST_INSERT_HEAD(handlers, handler_instance, next);
}
else {
@ -380,7 +390,7 @@ static void loop_node_remove_all_handler(esp_event_loop_node_t* loop_node)
static void inline __attribute__((always_inline)) post_instance_delete(esp_event_post_instance_t* post)
{
#if CONFIG_ESP_EVENT_POST_FROM_ISR
if (post->data_allocd && post->data.ptr) {
if (post->data_allocated && post->data.ptr) {
free(post->data.ptr);
}
#else
@ -463,16 +473,16 @@ esp_err_t esp_event_loop_create(const esp_event_loop_args_t* event_loop_args, es
return ESP_OK;
on_err:
if(loop->queue != NULL) {
if (loop->queue != NULL) {
vQueueDelete(loop->queue);
}
if(loop->mutex != NULL) {
if (loop->mutex != NULL) {
vSemaphoreDelete(loop->mutex);
}
#ifdef CONFIG_ESP_EVENT_LOOP_PROFILING
if(loop->profiling_mutex != NULL) {
if (loop->profiling_mutex != NULL) {
vSemaphoreDelete(loop->profiling_mutex);
}
#endif
@ -497,7 +507,7 @@ esp_err_t esp_event_loop_run(esp_event_loop_handle_t event_loop, TickType_t tick
TickType_t marker = xTaskGetTickCount();
TickType_t end = 0;
#if( configUSE_16_BIT_TICKS == 1 )
#if (configUSE_16_BIT_TICKS == 1)
int32_t remaining_ticks = ticks_to_run;
#else
int64_t remaining_ticks = ticks_to_run;
@ -532,7 +542,7 @@ esp_err_t esp_event_loop_run(esp_event_loop_handle_t event_loop, TickType_t tick
}
SLIST_FOREACH(id_node, &(base_node->id_nodes), next) {
if(id_node->id == post.id) {
if (id_node->id == post.id) {
// Execute id level handlers
SLIST_FOREACH(handler, &(id_node->handlers), next) {
handler_execute(loop, handler, post);
@ -740,7 +750,7 @@ esp_err_t esp_event_post_to(esp_event_loop_handle_t event_loop, esp_event_base_t
esp_event_loop_instance_t* loop = (esp_event_loop_instance_t*) event_loop;
esp_event_post_instance_t post;
memset((void*)(&(post.data)), 0, sizeof(post.data));
memset((void*)(&post), 0, sizeof(post));
if (event_data != NULL && event_data_size != 0) {
// Make persistent copy of event data on heap.
@ -753,7 +763,8 @@ esp_err_t esp_event_post_to(esp_event_loop_handle_t event_loop, esp_event_base_t
memcpy(event_data_copy, event_data, event_data_size);
#if CONFIG_ESP_EVENT_POST_FROM_ISR
post.data.ptr = event_data_copy;
post.data_allocd = true;
post.data_allocated = true;
post.data_set = true;
#else
post.data = event_data_copy;
#endif
@ -816,7 +827,7 @@ esp_err_t esp_event_isr_post_to(esp_event_loop_handle_t event_loop, esp_event_ba
esp_event_loop_instance_t* loop = (esp_event_loop_instance_t*) event_loop;
esp_event_post_instance_t post;
memset((void*)(&(post.data)), 0, sizeof(post.data));
memset((void*)(&post), 0, sizeof(post));
if (event_data_size > sizeof(post.data.val)) {
return ESP_ERR_INVALID_ARG;
@ -824,7 +835,8 @@ esp_err_t esp_event_isr_post_to(esp_event_loop_handle_t event_loop, esp_event_ba
if (event_data != NULL && event_data_size != 0) {
memcpy((void*)(&(post.data.val)), event_data, event_data_size);
post.data_allocd = false;
post.data_allocated = false;
post.data_set = true;
}
post.base = event_base;
post.id = event_id;

View file

@ -97,7 +97,8 @@ typedef void* esp_event_post_data_t;
/// Event posted to the event queue
typedef struct esp_event_post_instance {
#if CONFIG_ESP_EVENT_POST_FROM_ISR
bool data_allocd; /**< indicates whether data is alloc'd */
bool data_allocated; /**< indicates whether data is allocated from heap */
bool data_set; /**< indicates if data is null */
#endif
esp_event_base_t base; /**< the event base */
int32_t id; /**< the event id */

View file

@ -1149,6 +1149,37 @@ TEST_CASE("events are dispatched in the order they are registered", "[event]")
}
#if CONFIG_ESP_EVENT_POST_FROM_ISR
TEST_CASE("can properly prepare event data posted to loop", "[event]")
{
TEST_SETUP();
esp_event_loop_handle_t loop;
esp_event_loop_args_t loop_args = test_event_get_default_loop_args();
loop_args.task_name = NULL;
TEST_ASSERT_EQUAL(ESP_OK, esp_event_loop_create(&loop_args, &loop));
esp_event_post_instance_t post;
esp_event_loop_instance_t* loop_def = (esp_event_loop_instance_t*) loop;
TEST_ASSERT_EQUAL(ESP_OK, esp_event_post_to(loop, s_test_base1, TEST_EVENT_BASE1_EV1, NULL, 0, portMAX_DELAY));
TEST_ASSERT_EQUAL(pdTRUE, xQueueReceive(loop_def->queue, &post, portMAX_DELAY));
TEST_ASSERT_EQUAL(false, post.data_set);
TEST_ASSERT_EQUAL(false, post.data_allocated);
TEST_ASSERT_EQUAL(NULL, post.data.ptr);
int sample = 0;
TEST_ASSERT_EQUAL(ESP_OK, esp_event_isr_post_to(loop, s_test_base1, TEST_EVENT_BASE1_EV1, &sample, sizeof(sample), NULL));
TEST_ASSERT_EQUAL(pdTRUE, xQueueReceive(loop_def->queue, &post, portMAX_DELAY));
TEST_ASSERT_EQUAL(true, post.data_set);
TEST_ASSERT_EQUAL(false, post.data_allocated);
TEST_ASSERT_EQUAL(false, post.data.val);
TEST_ASSERT_EQUAL(ESP_OK, esp_event_loop_delete(loop));
TEST_TEARDOWN();
}
TEST_CASE("can post events from interrupt handler", "[event]")
{
SemaphoreHandle_t sem = xSemaphoreCreateBinary();