diff options
| author | Damien George <damien.p.george@gmail.com> | 2018-11-28 14:30:11 +1100 |
|---|---|---|
| committer | Damien George <damien.p.george@gmail.com> | 2018-11-28 14:30:11 +1100 |
| commit | 0233049b794d8ed45f1f8dbaffb30e6b78aabb7e (patch) | |
| tree | 00dee272f5cf5919347c07c109fcb2d61afc76f8 /ports/esp32/mpthreadport.c | |
| parent | afd1ce0c1543ec1f621ae9ff1e8e25075ee943ff (diff) | |
esp32/mpthreadport: Prevent deadlocks when deleting all threads.
vTaskDelete now immediately calls vPortCleanUpTCB, which requires the
thread_mutex mutex, so vTaskDelete must be called after this mutex is
released.
Diffstat (limited to 'ports/esp32/mpthreadport.c')
| -rw-r--r-- | ports/esp32/mpthreadport.c | 28 |
1 files changed, 19 insertions, 9 deletions
diff --git a/ports/esp32/mpthreadport.c b/ports/esp32/mpthreadport.c index 76d9431c0..b002c880e 100644 --- a/ports/esp32/mpthreadport.c +++ b/ports/esp32/mpthreadport.c @@ -205,17 +205,27 @@ void mp_thread_mutex_unlock(mp_thread_mutex_t *mutex) { } void mp_thread_deinit(void) { - mp_thread_mutex_lock(&thread_mutex, 1); - for (thread_t *th = thread; th != NULL; th = th->next) { - // don't delete the current task - if (th->id == xTaskGetCurrentTaskHandle()) { - continue; + for (;;) { + // Find a task to delete + TaskHandle_t id = NULL; + mp_thread_mutex_lock(&thread_mutex, 1); + for (thread_t *th = thread; th != NULL; th = th->next) { + // Don't delete the current task + if (th->id != xTaskGetCurrentTaskHandle()) { + id = th->id; + break; + } + } + mp_thread_mutex_unlock(&thread_mutex); + + if (id == NULL) { + // No tasks left to delete + break; + } else { + // Call FreeRTOS to delete the task (it will call vPortCleanUpTCB) + vTaskDelete(id); } - vTaskDelete(th->id); } - mp_thread_mutex_unlock(&thread_mutex); - // allow FreeRTOS to clean-up the threads - vTaskDelay(2); } #else |
