From 081a9689697fe550ed7b81a4a741a47c2d023753 Mon Sep 17 00:00:00 2001 From: Joel Guittet Date: Wed, 10 Apr 2024 23:07:53 +0200 Subject: [PATCH] platform: rtos: permit deactivate if not activated --- platform/rtos/freertos/src/mender-rtos.c | 29 ++++++++++++++------- platform/rtos/posix/src/mender-rtos.c | 33 ++++++++++++++++-------- platform/rtos/zephyr/src/mender-rtos.c | 23 ++++++++++++----- 3 files changed, 59 insertions(+), 26 deletions(-) diff --git a/platform/rtos/freertos/src/mender-rtos.c b/platform/rtos/freertos/src/mender-rtos.c index 153aa2d..ffc2ff7 100644 --- a/platform/rtos/freertos/src/mender-rtos.c +++ b/platform/rtos/freertos/src/mender-rtos.c @@ -67,6 +67,7 @@ typedef struct { mender_rtos_work_params_t params; /**< Work parameters */ SemaphoreHandle_t sem_handle; /**< Semaphore used to indicate work is pending or executing */ TimerHandle_t timer_handle; /**< Timer used to periodically execute work */ + bool activated; /**< Flag indicating the work is activated */ } mender_rtos_work_context_t; /** @@ -201,6 +202,9 @@ mender_rtos_work_activate(void *handle) { mender_rtos_timer_callback(work_context->timer_handle); } + /* Indicate the work has been activated */ + work_context->activated = true; + return MENDER_OK; } @@ -251,16 +255,23 @@ mender_rtos_work_deactivate(void *handle) { /* Get work context */ mender_rtos_work_context_t *work_context = (mender_rtos_work_context_t *)handle; - /* Stop the timer used to periodically execute the work (if it is running) */ - xTimerStop(work_context->timer_handle, portMAX_DELAY); - while (pdFALSE != xTimerIsTimerActive(work_context->timer_handle)) { - vTaskDelay(1); - } + /* Check if the work was activated */ + if (true == work_context->activated) { - /* Wait if the work is pending or executing */ - if (pdPASS != xSemaphoreTake(work_context->sem_handle, portMAX_DELAY)) { - mender_log_error("Work '%s' is pending or executing", work_context->params.name); - return MENDER_FAIL; + /* Stop the timer used to periodically execute the work (if it is running) */ + xTimerStop(work_context->timer_handle, portMAX_DELAY); + while (pdFALSE != xTimerIsTimerActive(work_context->timer_handle)) { + vTaskDelay(1); + } + + /* Wait if the work is pending or executing */ + if (pdPASS != xSemaphoreTake(work_context->sem_handle, portMAX_DELAY)) { + mender_log_error("Work '%s' is pending or executing", work_context->params.name); + return MENDER_FAIL; + } + + /* Indicate the work has been deactivated */ + work_context->activated = false; } return MENDER_OK; diff --git a/platform/rtos/posix/src/mender-rtos.c b/platform/rtos/posix/src/mender-rtos.c index cde5294..65a0a4a 100644 --- a/platform/rtos/posix/src/mender-rtos.c +++ b/platform/rtos/posix/src/mender-rtos.c @@ -63,6 +63,7 @@ typedef struct { mender_rtos_work_params_t params; /**< Work parameters */ pthread_mutex_t sem_handle; /**< Semaphore used to indicate work is pending or executing */ timer_t timer_handle; /**< Timer used to periodically execute work */ + bool activated; /**< Flag indicating the work is activated */ } mender_rtos_work_context_t; /** @@ -227,6 +228,9 @@ mender_rtos_work_activate(void *handle) { mender_rtos_timer_callback(timer_data); } + /* Indicate the work has been activated */ + work_context->activated = true; + return MENDER_OK; } @@ -278,18 +282,25 @@ mender_rtos_work_deactivate(void *handle) { /* Get work context */ mender_rtos_work_context_t *work_context = (mender_rtos_work_context_t *)handle; - /* Stop the timer used to periodically execute the work (if it is running) */ - struct itimerspec its; - memset(&its, 0, sizeof(struct itimerspec)); - if (0 != timer_settime(work_context->timer_handle, 0, &its, NULL)) { - mender_log_error("Unable to stop timer"); - return MENDER_FAIL; - } + /* Check if the work was activated */ + if (true == work_context->activated) { - /* Wait if the work is pending or executing */ - if (0 != pthread_mutex_lock(&work_context->sem_handle)) { - mender_log_error("Work '%s' is pending or executing", work_context->params.name); - return MENDER_FAIL; + /* Stop the timer used to periodically execute the work (if it is running) */ + struct itimerspec its; + memset(&its, 0, sizeof(struct itimerspec)); + if (0 != timer_settime(work_context->timer_handle, 0, &its, NULL)) { + mender_log_error("Unable to stop timer"); + return MENDER_FAIL; + } + + /* Wait if the work is pending or executing */ + if (0 != pthread_mutex_lock(&work_context->sem_handle)) { + mender_log_error("Work '%s' is pending or executing", work_context->params.name); + return MENDER_FAIL; + } + + /* Indicate the work has been deactivated */ + work_context->activated = false; } return MENDER_OK; diff --git a/platform/rtos/zephyr/src/mender-rtos.c b/platform/rtos/zephyr/src/mender-rtos.c index edd9af6..a65865e 100644 --- a/platform/rtos/zephyr/src/mender-rtos.c +++ b/platform/rtos/zephyr/src/mender-rtos.c @@ -51,6 +51,7 @@ typedef struct { struct k_sem sem_handle; /**< Semaphore used to indicate work is pending or executing */ struct k_timer timer_handle; /**< Timer used to periodically execute work */ struct k_work work_handle; /**< Work handle used to execute the work function */ + bool activated; /**< Flag indicating the work is activated */ } mender_rtos_work_context_t; /** @@ -163,6 +164,9 @@ mender_rtos_work_activate(void *handle) { k_timer_start(&work_context->timer_handle, K_NO_WAIT, K_MSEC(1000 * work_context->params.period)); } + /* Indicate the work has been activated */ + work_context->activated = true; + return MENDER_OK; } @@ -207,13 +211,20 @@ mender_rtos_work_deactivate(void *handle) { /* Get work context */ mender_rtos_work_context_t *work_context = (mender_rtos_work_context_t *)handle; - /* Stop the timer used to periodically execute the work (if it is running) */ - k_timer_stop(&work_context->timer_handle); + /* Check if the work was activated */ + if (true == work_context->activated) { - /* Wait if the work is pending or executing */ - if (0 != k_sem_take(&work_context->sem_handle, K_FOREVER)) { - mender_log_error("Work '%s' is pending or executing", work_context->params.name); - return MENDER_FAIL; + /* Stop the timer used to periodically execute the work (if it is running) */ + k_timer_stop(&work_context->timer_handle); + + /* Wait if the work is pending or executing */ + if (0 != k_sem_take(&work_context->sem_handle, K_FOREVER)) { + mender_log_error("Work '%s' is pending or executing", work_context->params.name); + return MENDER_FAIL; + } + + /* Indicate the work has been deactivated */ + work_context->activated = false; } return MENDER_OK;