From 2f39723d08eab78aec1e8d167b24bf127ddd067c Mon Sep 17 00:00:00 2001 From: Florian Albrechtskirchinger Date: Wed, 12 Mar 2025 17:12:03 +0100 Subject: [PATCH] Wrap poll()/WSAPoll() in a function and build compiled library on Windows (#2107) * Wrap poll()/WSAPoll() in a function Instead of using a macro for poll() on Windows, which breaks when the implementation is compiled separately, add a detail::poll_wrapper() function that dispatches to either ::poll() or ::WSAPoll(). * Build compiled library on Windows --- .github/workflows/test.yaml | 10 ++++++++++ httplib.h | 19 ++++++++++++------- 2 files changed, 22 insertions(+), 7 deletions(-) diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index 02f46be..7763d37 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -98,9 +98,17 @@ jobs: matrix: config: - with_ssl: false + compiled: false + run_tests: true name: without SSL - with_ssl: true + compiled: false + run_tests: true name: with SSL + - with_ssl: false + compiled: true + run_tests: false + name: compiled name: windows ${{ matrix.config.name }} steps: - name: Prepare Git for Checkout on Windows @@ -128,12 +136,14 @@ jobs: -DCMAKE_BUILD_TYPE=Release -DCMAKE_TOOLCHAIN_FILE=${{ env.VCPKG_ROOT }}/scripts/buildsystems/vcpkg.cmake -DHTTPLIB_TEST=ON + -DHTTPLIB_COMPILE=${{ matrix.config.compiled && 'ON' || 'OFF' }} -DHTTPLIB_REQUIRE_ZLIB=ON -DHTTPLIB_REQUIRE_BROTLI=ON -DHTTPLIB_REQUIRE_OPENSSL=${{ matrix.config.with_ssl && 'ON' || 'OFF' }} - name: Build ${{ matrix.config.name }} run: cmake --build build --config Release -- /v:m /clp:ShowCommandLine - name: Run tests ${{ matrix.config.name }} + if: ${{ matrix.config.run_tests }} run: ctest --output-on-failure --test-dir build -C Release env: diff --git a/httplib.h b/httplib.h index f6b7582..e009971 100644 --- a/httplib.h +++ b/httplib.h @@ -192,9 +192,9 @@ using ssize_t = long; #define WSA_FLAG_NO_HANDLE_INHERIT 0x80 #endif +using nfds_t = unsigned long; using socket_t = SOCKET; using socklen_t = int; -#define poll(fds, nfds, timeout) WSAPoll(fds, nfds, timeout) #else // not _WIN32 @@ -3240,6 +3240,14 @@ inline ssize_t send_socket(socket_t sock, const void *ptr, size_t size, }); } +inline int poll_wrapper(struct pollfd *fds, nfds_t nfds, int timeout) { +#ifdef _WIN32 + return ::WSAPoll(fds, nfds, timeout); +#else + return ::poll(fds, nfds, timeout); +#endif +} + template inline ssize_t select_impl(socket_t sock, time_t sec, time_t usec) { struct pollfd pfd; @@ -3248,7 +3256,7 @@ inline ssize_t select_impl(socket_t sock, time_t sec, time_t usec) { auto timeout = static_cast(sec * 1000 + usec / 1000); - return handle_EINTR([&]() { return poll(&pfd, 1, timeout); }); + return handle_EINTR([&]() { return poll_wrapper(&pfd, 1, timeout); }); } inline ssize_t select_read(socket_t sock, time_t sec, time_t usec) { @@ -3267,7 +3275,8 @@ inline Error wait_until_socket_is_ready(socket_t sock, time_t sec, auto timeout = static_cast(sec * 1000 + usec / 1000); - auto poll_res = handle_EINTR([&]() { return poll(&pfd_read, 1, timeout); }); + auto poll_res = + handle_EINTR([&]() { return poll_wrapper(&pfd_read, 1, timeout); }); if (poll_res == 0) { return Error::ConnectionTimeout; } @@ -10367,8 +10376,4 @@ inline SSL_CTX *Client::ssl_context() const { } // namespace httplib -#ifdef _WIN32 -#undef poll -#endif - #endif // CPPHTTPLIB_HTTPLIB_H