| 700 | |
| 701 | |
| 702 | Future<size_t> sendfile( |
| 703 | const int_fd& socket, const int_fd& file, off_t offset, size_t size) |
| 704 | { |
| 705 | process::initialize(); |
| 706 | |
| 707 | if (offset < 0) { |
| 708 | return Failure("process::windows::sendfile got negative offset"); |
| 709 | } |
| 710 | |
| 711 | Promise<size_t>* promise = new Promise<size_t>(); |
| 712 | Future<size_t> future = promise->future(); |
| 713 | |
| 714 | auto overlapped = std::make_shared<IOOverlappedReadWrite>( |
| 715 | IOOverlappedBase{OVERLAPPED{}, socket, IOType::SENDFILE}, promise); |
| 716 | |
| 717 | uint64_t offset64 = static_cast<uint64_t>(offset); |
| 718 | overlapped->base.overlapped.Offset = static_cast<DWORD>(offset64); |
| 719 | overlapped->base.overlapped.OffsetHigh = static_cast<DWORD>(offset64 >> 32); |
| 720 | |
| 721 | enable_cancellation(socket, future, overlapped); |
| 722 | |
| 723 | const Result<size_t> result = |
| 724 | os::sendfile_async(socket, file, size, &overlapped->base.overlapped); |
| 725 | |
| 726 | // If the request is pending, then we return immediately and have the |
| 727 | // callback free the promise and overlapped. |
| 728 | if (result.isNone()) { |
| 729 | return future; |
| 730 | } |
| 731 | |
| 732 | // In an error or immediate success, we have to manually set the promise |
| 733 | // and free it. |
| 734 | if (result.isError()) { |
| 735 | promise->fail("os::sendfile_async failed: " + result.error()); |
| 736 | } else if (result.isSome()) { |
| 737 | promise->set(result.get()); |
| 738 | } |
| 739 | delete promise; |
| 740 | return future; |
| 741 | } |
| 742 | |
| 743 | } // namespace windows { |
| 744 | } // namespace process { |
no test coverage detected