Skip to content

Commit c83978e

Browse files
committed
gmf_core: Fixed a thread safety issue with the gmf_task running flag
Aligned struct member formatting in headers to comply with coding style
1 parent d6541b6 commit c83978e

File tree

7 files changed

+58
-52
lines changed

7 files changed

+58
-52
lines changed
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
idf_component_register(SRC_DIRS "." "elements"
22
INCLUDE_DIRS "." "elements"
3-
REQUIRES unity esp_codec_dev system_common test_utils
3+
REQUIRES unity esp_codec_dev system_common test_utils esp_gdbstub
44
EMBED_FILES "hi_lexin.pcm"
55
WHOLE_ARCHIVE)

elements/test_apps/main/elements/gmf_audio_play_el_test.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -528,7 +528,7 @@ TEST_CASE("Audio Play, two in pipe use same task, [file->dec]->rb->[resample+IIS
528528
ESP_GMF_MEM_SHOW(TAG);
529529
}
530530

531-
TEST_CASE("Audio Play, One Pipe, [HTTP->dec->resample->IIS]", "[ESP_GMF_POOL][ignore][leaks=10000]")
531+
TEST_CASE("Audio Play, One Pipe, [HTTP->dec->resample->IIS]", "[ESP_GMF_POOL][leaks=10000]")
532532
{
533533
esp_log_level_set("*", ESP_LOG_INFO);
534534
esp_log_level_set("ESP_GMF_PIPELINE", ESP_LOG_DEBUG);

gmf_core/CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
### Bug Fixes
1717

1818
- Fixed pause timeout caused by missing sync event when pause producer entered an error state
19+
- Fixed a thread safety issue with the gmf_task `running` flag
1920

2021
## v0.6.1
2122

gmf_core/include/esp_gmf_element.h

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -97,26 +97,26 @@ typedef struct {
9797
* @brief Structure representing a GMF element
9898
*/
9999
typedef struct esp_gmf_element {
100-
esp_gmf_obj_t base; /*!< Base object */
101-
esp_gmf_element_ops_t ops; /*!< Operations */
102-
uint8_t job_mask; /*!< Job mask */
100+
esp_gmf_obj_t base; /*!< Base object */
101+
esp_gmf_element_ops_t ops; /*!< Operations */
102+
uint8_t job_mask; /*!< Job mask */
103103

104-
esp_gmf_port_t *in; /*!< Input port */
105-
esp_gmf_element_port_attr_t in_attr; /*!< Input port attributes */
104+
esp_gmf_port_t *in; /*!< Input port */
105+
esp_gmf_element_port_attr_t in_attr; /*!< Input port attributes */
106106

107-
esp_gmf_port_t *out; /*!< Output port */
108-
esp_gmf_element_port_attr_t out_attr; /*!< Output port attributes */
107+
esp_gmf_port_t *out; /*!< Output port */
108+
esp_gmf_element_port_attr_t out_attr; /*!< Output port attributes */
109109

110110
/* Properties */
111-
esp_gmf_event_state_t init_state; /*!< Initial state */
112-
esp_gmf_event_state_t cur_state; /*!< Current state */
113-
esp_gmf_event_cb event_func; /*!< Event function */
114-
esp_gmf_method_t *method; /*!< It can access the data members and member functions of the objects */
115-
esp_gmf_cap_t *caps; /*!< Element capabilities */
111+
esp_gmf_event_state_t init_state; /*!< Initial state */
112+
esp_gmf_event_state_t cur_state; /*!< Current state */
113+
esp_gmf_event_cb event_func; /*!< Event function */
114+
esp_gmf_method_t *method; /*!< It can access the data members and member functions of the objects */
115+
esp_gmf_cap_t *caps; /*!< Element capabilities */
116116

117117
/* Protect */
118-
void *ctx; /*!< User Context */
119-
uint8_t dependency : 1; /*!< Indicates if the element depends on other information to open */
118+
void *ctx; /*!< User Context */
119+
uint8_t dependency : 1; /*!< Indicates if the element depends on other information to open */
120120
} esp_gmf_element_t;
121121

122122
/**

gmf_core/include/esp_gmf_pipeline.h

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -35,22 +35,22 @@ typedef esp_gmf_err_t (*esp_gmf_pipeline_prev_act)(void *handle); /*!< */
3535
* @brief Structure representing a pipeline in GMF
3636
*/
3737
typedef struct esp_gmf_pipeline {
38-
esp_gmf_element_handle_t head_el; /*!< Handle of the first element in the pipeline */
39-
esp_gmf_element_handle_t last_el; /*!< Handle of the last element in the pipeline */
40-
esp_gmf_io_handle_t in; /*!< Handle of the input I/O port */
41-
esp_gmf_io_handle_t out; /*!< Handle of the output I/O port */
42-
esp_gmf_event_item_t *evt_conveyor; /*!< Event conveyor list */
43-
esp_gmf_event_cb evt_acceptor; /*!< Event acceptor callback function */
44-
esp_gmf_event_cb user_cb; /*!< User callback function */
45-
void *user_ctx; /*!< User context */
46-
esp_gmf_event_state_t state; /*!< Current state of the pipeline */
47-
esp_gmf_task_handle_t thread; /*!< Handle of the task associated with the pipeline */
48-
esp_gmf_pipeline_prev_act prev_run; /*!< A pointer to the previous run callback */
49-
esp_gmf_pipeline_prev_act prev_stop; /*!< A pointer to the previous stop callback */
50-
void *prev_run_ctx; /*!< The previous run context */
51-
void *prev_stop_ctx; /*!< The previous stop context */
52-
uint8_t prev_state; /*!< The previous action state */
53-
void *lock; /*!< Lock for thread synchronization */
38+
esp_gmf_element_handle_t head_el; /*!< Handle of the first element in the pipeline */
39+
esp_gmf_element_handle_t last_el; /*!< Handle of the last element in the pipeline */
40+
esp_gmf_io_handle_t in; /*!< Handle of the input I/O port */
41+
esp_gmf_io_handle_t out; /*!< Handle of the output I/O port */
42+
esp_gmf_event_item_t *evt_conveyor; /*!< Event conveyor list */
43+
esp_gmf_event_cb evt_acceptor; /*!< Event acceptor callback function */
44+
esp_gmf_event_cb user_cb; /*!< User callback function */
45+
void *user_ctx; /*!< User context */
46+
esp_gmf_event_state_t state; /*!< Current state of the pipeline */
47+
esp_gmf_task_handle_t thread; /*!< Handle of the task associated with the pipeline */
48+
esp_gmf_pipeline_prev_act prev_run; /*!< A pointer to the previous run callback */
49+
esp_gmf_pipeline_prev_act prev_stop; /*!< A pointer to the previous stop callback */
50+
void *prev_run_ctx; /*!< The previous run context */
51+
void *prev_stop_ctx; /*!< The previous stop context */
52+
uint8_t prev_state; /*!< The previous action state */
53+
void *lock; /*!< Lock for thread synchronization */
5454
} esp_gmf_pipeline_t;
5555

5656
/**

gmf_core/include/esp_gmf_task.h

Lines changed: 20 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -43,31 +43,32 @@ typedef struct esp_gmf_task_config {
4343
* Represents a GMF task, including its properties, configuration, and internal state.
4444
*/
4545
typedef struct _esp_gmf_task {
46-
struct esp_gmf_obj_ base; /*!< Base object for GMF tasks */
47-
esp_gmf_job_t *working; /*!< Currently executing job in the task */
48-
esp_gmf_job_stack_t *start_stack; /*!< Stack for the start job */
46+
struct esp_gmf_obj_ base; /*!< Base object for GMF tasks */
47+
esp_gmf_job_t *working; /*!< Currently executing job in the task */
48+
esp_gmf_job_stack_t *start_stack; /*!< Stack for the start job */
4949

5050
/* Properties */
51-
esp_gmf_event_cb event_func; /*!< Callback function for task events */
52-
esp_gmf_event_state_t state; /*!< Current state of the task */
51+
esp_gmf_event_cb event_func; /*!< Callback function for task events */
52+
esp_gmf_event_state_t state; /*!< Current state of the task */
5353

5454
/* Protect */
55-
esp_gmf_task_config_t thread; /*!< Configuration settings for the task */
56-
void *ctx; /*!< Context associated with the task */
55+
esp_gmf_task_config_t thread; /*!< Configuration settings for the task */
56+
void *ctx; /*!< Context associated with the task */
5757

5858
/* Private */
59-
void *oal_thread; /*!< Handle to the thread */
60-
void *lock; /*!< Mutex lock for task synchronization */
61-
void *event_group; /*!< Event group for wait events */
62-
void *block_sem; /*!< Semaphore for blocking tasks */
63-
void *wait_sem; /*!< Semaphore for task waiting */
64-
int api_sync_time; /*!< Timeout for synchronization */
65-
66-
uint8_t _task_run : 1; /*!< Internal flag for task execution */
67-
uint8_t _running : 1; /*!< Internal flag for task running state */
68-
uint8_t _pause : 1; /*!< Internal flag for task pause state */
69-
uint8_t _stop : 1; /*!< Internal flag for task stop state */
70-
uint8_t _destroy : 1; /*!< Internal flag for task destruction */
59+
void *oal_thread; /*!< Handle to the thread */
60+
void *lock; /*!< Mutex lock for task synchronization */
61+
void *event_group; /*!< Event group for wait events */
62+
void *block_sem; /*!< Semaphore for blocking tasks */
63+
void *wait_sem; /*!< Semaphore for task waiting */
64+
int api_sync_time; /*!< Timeout for synchronization */
65+
66+
uint8_t _task_run : 1; /*!< Internal flag for task execution */
67+
uint8_t _running : 1; /*!< Internal flag for task running state */
68+
uint8_t _run : 1; /*!< Internal flag for task run API flag */
69+
uint8_t _pause : 1; /*!< Internal flag for task pause API flag */
70+
uint8_t _stop : 1; /*!< Internal flag for task stop API flag */
71+
uint8_t _destroy : 1; /*!< Internal flag for task destruction API flag */
7172
} esp_gmf_task_t;
7273

7374
/**

gmf_core/src/esp_gmf_task.c

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -271,6 +271,10 @@ static void esp_gmf_thread_fun(void *pv)
271271
ESP_LOGD(TAG, "Thread will be destroyed, [%s,%p]", OBJ_GET_TAG((esp_gmf_obj_handle_t)tsk), tsk);
272272
goto ESP_GMF_THREAD_EXIT;
273273
}
274+
if (tsk->_run == 1) {
275+
tsk->_running = 1;
276+
tsk->_run = 0;
277+
}
274278
}
275279
int ret = esp_gmf_task_event_state_change_and_notify(tsk, ESP_GMF_EVENT_STATE_RUNNING);
276280
GMF_TASK_SET_STATE_BITS(tsk->event_group, GMF_TASK_RUN_BIT);
@@ -452,7 +456,7 @@ esp_gmf_err_t esp_gmf_task_run(esp_gmf_task_handle_t handle)
452456
ESP_LOGW(TAG, "No task for run, %s, [%s,%p]", esp_gmf_event_get_state_str(tsk->state), OBJ_GET_TAG((esp_gmf_obj_handle_t)tsk), tsk);
453457
return ESP_GMF_ERR_INVALID_STATE;
454458
}
455-
tsk->_running = 1;
459+
tsk->_run = 1;
456460
xSemaphoreGive(tsk->block_sem);
457461
// Wait for run finished
458462
if (GMF_TASK_WAIT_FOR_STATE_BITS(tsk->event_group, GMF_TASK_RUN_BIT, tsk->api_sync_time) == false) {

0 commit comments

Comments
 (0)