OVMS3-idf/components/esp_event/private_include/esp_event_internal.h
Renz Christian Bagaporo f21b8bbf55 esp_event: fix issue with post data preparation
Fixes an issue with post instance data preparation. Currently, there is
no way to check if event data has really been set during handler
execution preparation. When data is not allocated from the heap, user
could have passed 0x0 which can lead to failed checks.

This also implements using the already allocated data memory for posting
events from non-ISR functions when data size is less than the capacity.
2019-05-22 11:28:39 +08:00

112 lines
5.9 KiB
C

// Copyright 2018 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef ESP_EVENT_INTERNAL_H_
#define ESP_EVENT_INTERNAL_H_
#include "esp_event.h"
#include "stdatomic.h"
#ifdef __cplusplus
extern "C" {
#endif
typedef SLIST_HEAD(base_nodes, base_node) base_nodes_t;
/// Event handler
typedef struct esp_event_handler_instance {
esp_event_handler_t handler; /**< event handler function*/
void* arg; /**< event handler argument */
#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;
typedef SLIST_HEAD(esp_event_handler_instances, esp_event_handler_instance) esp_event_handler_instances_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
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;
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
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 */
} esp_event_base_node_t;
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_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
event bases registered to the loop */
} esp_event_loop_node_t;
typedef SLIST_HEAD(esp_event_loop_nodes, esp_event_loop_node) esp_event_loop_nodes_t;
/// Event loop
typedef struct esp_event_loop_instance {
const char* name; /**< name of this event loop */
QueueHandle_t queue; /**< event queue */
TaskHandle_t task; /**< task that consumes the event queue */
TaskHandle_t running_task; /**< for loops with no dedicated task, the
task that consumes the queue */
SemaphoreHandle_t mutex; /**< mutex for updating the events linked list */
esp_event_loop_nodes_t loop_nodes; /**< set of linked lists containing the
registered handlers for the loop */
#ifdef CONFIG_ESP_EVENT_LOOP_PROFILING
atomic_uint_least32_t events_recieved; /**< number of events successfully posted to the loop */
atomic_uint_least32_t events_dropped; /**< number of events dropped due to queue being full */
SemaphoreHandle_t profiling_mutex; /**< mutex used for profiliing */
SLIST_ENTRY(esp_event_loop_instance) next; /**< next event loop in the list */
#endif
} esp_event_loop_instance_t;
#if CONFIG_ESP_EVENT_POST_FROM_ISR
typedef union esp_event_post_data {
uint32_t val;
void *ptr;
} esp_event_post_data_t;
#else
typedef void* esp_event_post_data_t;
#endif
/// Event posted to the event queue
typedef struct esp_event_post_instance {
#if CONFIG_ESP_EVENT_POST_FROM_ISR
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 */
esp_event_post_data_t data; /**< data associated with the event */
} esp_event_post_instance_t;
#ifdef __cplusplus
} // extern "C"
#endif
#endif // #ifndef ESP_EVENT_INTERNAL_H_