| 409 | } |
| 410 | |
| 411 | bool Transaction::wait(u32 timeout_ms) { |
| 412 | if (!pImpl) { |
| 413 | return true; // Already completed (or invalid) |
| 414 | } |
| 415 | |
| 416 | if (pImpl->completed) { |
| 417 | return true; // Already completed |
| 418 | } |
| 419 | |
| 420 | if (pImpl->cancelled) { |
| 421 | pImpl->completed = true; |
| 422 | return false; // Was cancelled |
| 423 | } |
| 424 | |
| 425 | // Check if device is still valid |
| 426 | if (!pImpl->device) { |
| 427 | pImpl->completed = true; |
| 428 | pImpl->result = fl::task::Error("Device pointer is null"); |
| 429 | return false; |
| 430 | } |
| 431 | |
| 432 | if (!pImpl->device->isReady()) { |
| 433 | pImpl->completed = true; |
| 434 | pImpl->result = fl::task::Error("Device not ready"); |
| 435 | return false; |
| 436 | } |
| 437 | |
| 438 | // Wait for the hardware to complete |
| 439 | u32 start_time = fl::millis(); |
| 440 | bool success = pImpl->device->waitComplete(timeout_ms); |
| 441 | |
| 442 | if (success) { |
| 443 | // Clear async state in device |
| 444 | if (pImpl->device->pImpl) { |
| 445 | pImpl->device->pImpl->async_state.active = false; |
| 446 | } |
| 447 | pImpl->completed = true; |
| 448 | pImpl->result = fl::nullopt; |
| 449 | |
| 450 | u32 elapsed = fl::millis() - start_time; |
| 451 | FL_LOG_SPI("Transaction: Completed successfully (waited " << elapsed << "ms)"); |
| 452 | return true; |
| 453 | } else { |
| 454 | // Timeout occurred |
| 455 | pImpl->completed = true; |
| 456 | pImpl->result = fl::task::Error("Transaction timeout"); |
| 457 | FL_WARN("Transaction: Timeout after " << timeout_ms << "ms"); |
| 458 | return false; |
| 459 | } |
| 460 | } |
| 461 | |
| 462 | bool Transaction::isDone() const { |
| 463 | return pImpl ? pImpl->completed : true; |
nothing calls this directly
no test coverage detected