| 134 | |
| 135 | template<typename Mutex> |
| 136 | void ConditionVariableESP32::wait(unique_lock<Mutex>& lock) { |
| 137 | FL_ASSERT(lock.owns_lock(), "ConditionVariableESP32::wait() called on unlocked lock"); |
| 138 | |
| 139 | // Get the mutex from the lock |
| 140 | Mutex* mtx = lock.mutex(); |
| 141 | FL_ASSERT(mtx != nullptr, "ConditionVariableESP32::wait() called with null mutex"); |
| 142 | |
| 143 | SemaphoreHandle_t internal_mutex = static_cast<SemaphoreHandle_t>(mMutex); |
| 144 | QueueHandle_t queue = static_cast<QueueHandle_t>(mWaitQueue); |
| 145 | |
| 146 | // Get current task handle |
| 147 | TaskHandle_t current_task = xTaskGetCurrentTaskHandle(); |
| 148 | |
| 149 | // Add ourselves to the wait queue |
| 150 | WaitingTask waiter = { current_task, false }; |
| 151 | |
| 152 | // Lock internal mutex |
| 153 | xSemaphoreTake(internal_mutex, portMAX_DELAY); |
| 154 | |
| 155 | // Add to wait queue |
| 156 | BaseType_t result = xQueueSend(queue, &waiter, 0); |
| 157 | if (result != pdTRUE) { |
| 158 | FL_WARN("ConditionVariableESP32: Wait queue full"); |
| 159 | xSemaphoreGive(internal_mutex); |
| 160 | return; |
| 161 | } |
| 162 | |
| 163 | // Unlock internal mutex |
| 164 | xSemaphoreGive(internal_mutex); |
| 165 | |
| 166 | // Unlock user mutex before waiting |
| 167 | lock.unlock(); |
| 168 | |
| 169 | // Wait for notification (blocking indefinitely) |
| 170 | ulTaskNotifyTake(pdTRUE, portMAX_DELAY); |
| 171 | |
| 172 | // Re-lock user mutex after waking up |
| 173 | lock.lock(); |
| 174 | } |
| 175 | |
| 176 | template<typename Mutex, typename Predicate> |
| 177 | void ConditionVariableESP32::wait(unique_lock<Mutex>& lock, Predicate pred) { |