| 815 | |
| 816 | |
| 817 | Future<size_t> LibeventSSLSocketImpl::sendfile( |
| 818 | int_fd fd, |
| 819 | off_t offset, |
| 820 | size_t size) |
| 821 | { |
| 822 | // Optimistically construct a 'SendRequest' and future. |
| 823 | Owned<SendRequest> request(new SendRequest(size)); |
| 824 | Future<size_t> future = request->promise.future(); |
| 825 | |
| 826 | // Assign 'send_request' under lock, fail on error. |
| 827 | synchronized (lock) { |
| 828 | if (send_request.get() != nullptr) { |
| 829 | return Failure("Socket is already sending"); |
| 830 | } |
| 831 | std::swap(request, send_request); |
| 832 | } |
| 833 | |
| 834 | // Duplicate the file descriptor because Libevent will take ownership |
| 835 | // and control the lifecycle separately. |
| 836 | // |
| 837 | // TODO(josephw): We can avoid duplicating the file descriptor in |
| 838 | // future versions of Libevent. In Libevent versions 2.1.2 and later, |
| 839 | // we may use `evbuffer_file_segment_new` and `evbuffer_add_file_segment` |
| 840 | // instead of `evbuffer_add_file`. |
| 841 | Try<int_fd> dup = os::dup(fd); |
| 842 | if (dup.isError()) { |
| 843 | return Failure(dup.error()); |
| 844 | } |
| 845 | |
| 846 | // NOTE: This is *not* an `int_fd` because `libevent` requires a CRT |
| 847 | // integer file descriptor, which we allocate and then use |
| 848 | // exclusively here. |
| 849 | #ifdef __WINDOWS__ |
| 850 | int owned_fd = dup->crt(); |
| 851 | // The `os::cloexec` and `os::nonblock` functions do nothing on |
| 852 | // Windows, and cannot be called because they take `int_fd`. |
| 853 | #else |
| 854 | int owned_fd = dup.get(); |
| 855 | |
| 856 | // Set the close-on-exec flag. |
| 857 | Try<Nothing> cloexec = os::cloexec(owned_fd); |
| 858 | if (cloexec.isError()) { |
| 859 | os::close(owned_fd); |
| 860 | return Failure( |
| 861 | "Failed to set close-on-exec on duplicated file descriptor: " + |
| 862 | cloexec.error()); |
| 863 | } |
| 864 | |
| 865 | // Make the file descriptor non-blocking. |
| 866 | Try<Nothing> nonblock = os::nonblock(owned_fd); |
| 867 | if (nonblock.isError()) { |
| 868 | os::close(owned_fd); |
| 869 | return Failure( |
| 870 | "Failed to make duplicated file descriptor non-blocking: " + |
| 871 | nonblock.error()); |
| 872 | } |
| 873 | #endif // __WINDOWS__ |
| 874 |
nothing calls this directly
no test coverage detected