| 182 | |
| 183 | template<typename Mutex, typename Rep, typename Period> |
| 184 | cv_status ConditionVariableESP32::wait_for( |
| 185 | unique_lock<Mutex>& lock, |
| 186 | const std::chrono::duration<Rep, Period>& rel_time) { // okay std namespace |
| 187 | |
| 188 | FL_ASSERT(lock.owns_lock(), "ConditionVariableESP32::wait_for() called on unlocked lock"); |
| 189 | |
| 190 | // Convert duration to milliseconds |
| 191 | auto ms = std::chrono::duration_cast<std::chrono::milliseconds>(rel_time); // okay std namespace |
| 192 | |
| 193 | // Get the mutex from the lock |
| 194 | Mutex* mtx = lock.mutex(); |
| 195 | FL_ASSERT(mtx != nullptr, "ConditionVariableESP32::wait_for() called with null mutex"); |
| 196 | |
| 197 | SemaphoreHandle_t internal_mutex = static_cast<SemaphoreHandle_t>(mMutex); |
| 198 | QueueHandle_t queue = static_cast<QueueHandle_t>(mWaitQueue); |
| 199 | |
| 200 | // Get current task handle |
| 201 | TaskHandle_t current_task = xTaskGetCurrentTaskHandle(); |
| 202 | |
| 203 | // Add ourselves to the wait queue |
| 204 | WaitingTask waiter = { current_task, false }; |
| 205 | |
| 206 | // Lock internal mutex |
| 207 | xSemaphoreTake(internal_mutex, portMAX_DELAY); |
| 208 | |
| 209 | // Add to wait queue |
| 210 | BaseType_t result = xQueueSend(queue, &waiter, 0); |
| 211 | if (result != pdTRUE) { |
| 212 | FL_WARN("ConditionVariableESP32: Wait queue full"); |
| 213 | xSemaphoreGive(internal_mutex); |
| 214 | return cv_status::timeout; |
| 215 | } |
| 216 | |
| 217 | // Unlock internal mutex |
| 218 | xSemaphoreGive(internal_mutex); |
| 219 | |
| 220 | // Unlock user mutex before waiting |
| 221 | lock.unlock(); |
| 222 | |
| 223 | // Wait for notification with timeout |
| 224 | TickType_t ticks = pdMS_TO_TICKS(ms.count()); |
| 225 | u32 notify_value = ulTaskNotifyTake(pdTRUE, ticks); |
| 226 | |
| 227 | // Re-lock user mutex after waking up |
| 228 | lock.lock(); |
| 229 | |
| 230 | // Check if we were notified or timed out |
| 231 | return (notify_value == 0) ? cv_status::timeout : cv_status::no_timeout; |
| 232 | } |
| 233 | |
| 234 | template<typename Mutex, typename Rep, typename Period, typename Predicate> |
| 235 | bool ConditionVariableESP32::wait_for( |