summaryrefslogtreecommitdiff
path: root/ports/esp32/mpthreadport.c
diff options
context:
space:
mode:
authorDamien George <damien.p.george@gmail.com>2018-11-28 14:30:11 +1100
committerDamien George <damien.p.george@gmail.com>2018-11-28 14:30:11 +1100
commit0233049b794d8ed45f1f8dbaffb30e6b78aabb7e (patch)
tree00dee272f5cf5919347c07c109fcb2d61afc76f8 /ports/esp32/mpthreadport.c
parentafd1ce0c1543ec1f621ae9ff1e8e25075ee943ff (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.c28
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