| 454 | |
| 455 | |
| 456 | static Future<size_t> read_internal( |
| 457 | const int_fd& fd, void* buf, size_t size, IOType type) |
| 458 | { |
| 459 | process::initialize(); |
| 460 | |
| 461 | Promise<size_t>* promise = new Promise<size_t>(); |
| 462 | Future<size_t> future = promise->future(); |
| 463 | |
| 464 | // We use a `std::shared_ptr`, so we can safely support canceling. |
| 465 | auto overlapped = std::make_shared<IOOverlappedReadWrite>( |
| 466 | IOOverlappedBase{OVERLAPPED{}, fd, type}, promise); |
| 467 | |
| 468 | enable_cancellation(fd, future, overlapped); |
| 469 | |
| 470 | // Start the asynchronous operation. |
| 471 | const Result<size_t> result = |
| 472 | os::read_async(fd, buf, size, &overlapped->base.overlapped); |
| 473 | |
| 474 | // If the request is pending, then we return immediately and have the |
| 475 | // callback free the promise and overlapped. |
| 476 | if (result.isNone()) { |
| 477 | return future; |
| 478 | } |
| 479 | |
| 480 | // In an error or immediate success, we have to manually set the promise |
| 481 | // and free it. |
| 482 | if (result.isError()) { |
| 483 | promise->fail("os::read_async failed: " + result.error()); |
| 484 | } else if (result.isSome()) { |
| 485 | promise->set(result.get()); |
| 486 | } |
| 487 | delete promise; |
| 488 | return future; |
| 489 | } |
| 490 | |
| 491 | |
| 492 | static Future<size_t> write_internal( |
no test coverage detected