From 9faf9c9416477591fc044c95f6b1e133e473f2e9 Mon Sep 17 00:00:00 2001 From: Angus Gratton Date: Thu, 29 Jun 2017 21:30:28 +1000 Subject: [PATCH] newlib locks: Fix _lock_init() & _lock_init_recursive() failing to initialise a lock If scheduler was running, and lock was an auto variable initialised at runtime by _lock_init*, initialisation could fail if the lock variable held non-zero stack memory (and lock would be left invalid). In other cases the lock is statically initialised to zero by __LOCK_INIT* --- components/newlib/locks.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/components/newlib/locks.c b/components/newlib/locks.c index c143e3a3d..89aed712c 100644 --- a/components/newlib/locks.c +++ b/components/newlib/locks.c @@ -48,7 +48,6 @@ static void IRAM_ATTR lock_init_generic(_lock_t *lock, uint8_t mutex_type) { portENTER_CRITICAL(&lock_init_spinlock); if (xTaskGetSchedulerState() == taskSCHEDULER_NOT_STARTED) { /* nothing to do until the scheduler is running */ - *lock = 0; /* ensure lock is zeroed out, in case it's an automatic variable */ portEXIT_CRITICAL(&lock_init_spinlock); return; } @@ -84,10 +83,12 @@ static void IRAM_ATTR lock_init_generic(_lock_t *lock, uint8_t mutex_type) { } void IRAM_ATTR _lock_init(_lock_t *lock) { + *lock = 0; // In case lock is an auto variable lock_init_generic(lock, queueQUEUE_TYPE_MUTEX); } void IRAM_ATTR _lock_init_recursive(_lock_t *lock) { + *lock = 0; // In case lock is an auto variable lock_init_generic(lock, queueQUEUE_TYPE_RECURSIVE_MUTEX); } @@ -96,6 +97,10 @@ void IRAM_ATTR _lock_init_recursive(_lock_t *lock) { Note that FreeRTOS doesn't account for deleting mutexes while they are held, and neither do we... so take care not to delete newlib locks while they may be held by other tasks! + + Also, deleting a lock in this way will cause it to be lazily + re-initialised if it is used again. Caller has to avoid doing + this! */ void IRAM_ATTR _lock_close(_lock_t *lock) { portENTER_CRITICAL(&lock_init_spinlock);