Browse Source

Remove `select()` and use `poll()` (#2078)

* Revert "Fix typo in meson.build (#2070)"

This reverts commit 5c0135fa5d7e059f5dd4c3a1a8a2d767d30ac491.

* Revert "build(meson): automatically use poll or select as needed (#2067)"

This reverts commit 2b5d1eea8d7e9f881ac4be04ce31df782b26b6a9.

* Revert "Make poll() the default (#2065)"

This reverts commit 6e73a63153e936e753211a5608acf336fb848a37.

* Remove select() and use poll()
Florian Albrechtskirchinger 9 months ago
parent
commit
22d90c29b4
6 changed files with 7 additions and 144 deletions
  1. 4 38
      .github/workflows/test.yaml
  2. 0 5
      CMakeLists.txt
  3. 0 5
      README.md
  4. 2 82
      httplib.h
  5. 1 10
      meson.build
  6. 0 4
      test/Makefile

+ 4 - 38
.github/workflows/test.yaml

@@ -43,21 +43,14 @@ jobs:
       (github.event_name == 'pull_request'  &&
        github.event.pull_request.head.repo.full_name != github.event.pull_request.base.repo.full_name) ||
       (github.event_name == 'workflow_dispatch' && github.event.inputs.test_linux == 'true')
-    strategy:
-      matrix:
-        select_impl: ['select', 'poll']
     steps:
       - name: checkout
         uses: actions/checkout@v4
       - name: install libraries
         run: sudo apt-get update && sudo apt-get install -y libbrotli-dev libcurl4-openssl-dev
       - name: build and run tests
-        env:
-          SELECT_IMPL: ${{ matrix.select_impl }}
         run: cd test && make
       - name: run fuzz test target
-        env:
-          SELECT_IMPL: ${{ matrix.select_impl }}
         run: cd test && make fuzz_test
 
   macos:
@@ -67,19 +60,12 @@ jobs:
       (github.event_name == 'pull_request'  &&
        github.event.pull_request.head.repo.full_name != github.event.pull_request.base.repo.full_name) ||
       (github.event_name == 'workflow_dispatch' && github.event.inputs.test_macos == 'true')
-    strategy:
-      matrix:
-        select_impl: ['select', 'poll']
     steps:
       - name: checkout
         uses: actions/checkout@v4
       - name: build and run tests
-        env:
-          SELECT_IMPL: ${{ matrix.select_impl }}
         run: cd test && make
       - name: run fuzz test target
-        env:
-          SELECT_IMPL: ${{ matrix.select_impl }}
         run: cd test && make fuzz_test
 
   windows:
@@ -89,9 +75,6 @@ jobs:
       (github.event_name == 'pull_request'  &&
        github.event.pull_request.head.repo.full_name != github.event.pull_request.base.repo.full_name) ||
       (github.event_name == 'workflow_dispatch' && github.event.inputs.test_windows == 'true')
-    strategy:
-      matrix:
-        select_impl: ['select', 'poll']
     steps:
     - name: Prepare Git for Checkout on Windows
       run: |
@@ -113,33 +96,16 @@ jobs:
         choco install openssl
 
     - name: Configure CMake with SSL
-      run: >
-        cmake -B build -S .
-        -DCMAKE_BUILD_TYPE=Release
-        -DCMAKE_TOOLCHAIN_FILE=${{ env.VCPKG_ROOT }}/scripts/buildsystems/vcpkg.cmake
-        -DHTTPLIB_TEST=ON
-        -DHTTPLIB_REQUIRE_OPENSSL=ON
-        -DHTTPLIB_REQUIRE_ZLIB=ON
-        -DHTTPLIB_REQUIRE_BROTLI=ON
-        -DHTTPLIB_USE_SELECT=${{ matrix.select_impl == 'select' && 'ON' || 'OFF' }}
+      run: cmake -B build -S . -DCMAKE_BUILD_TYPE=Release -DCMAKE_TOOLCHAIN_FILE=${{ env.VCPKG_ROOT }}/scripts/buildsystems/vcpkg.cmake -DHTTPLIB_TEST=ON -DHTTPLIB_REQUIRE_OPENSSL=ON -DHTTPLIB_REQUIRE_ZLIB=ON -DHTTPLIB_REQUIRE_BROTLI=ON
     - name: Build with with SSL
-      run: cmake --build build --config Release -- /v:m /clp:ShowCommandLine /nologo
+      run: cmake --build build --config Release
     - name: Run tests with SSL
       run: ctest --output-on-failure --test-dir build -C Release
 
     - name: Configure CMake without SSL
-      run: >
-        cmake -B build-no-ssl -S .
-        -DCMAKE_BUILD_TYPE=Release
-        -DCMAKE_TOOLCHAIN_FILE=${{ env.VCPKG_ROOT }}/scripts/buildsystems/vcpkg.cmake
-        -DCMAKE_EXPORT_COMPILE_COMMANDS=ON
-        -DHTTPLIB_TEST=ON
-        -DHTTPLIB_REQUIRE_OPENSSL=OFF
-        -DHTTPLIB_REQUIRE_ZLIB=ON
-        -DHTTPLIB_REQUIRE_BROTLI=ON
-        -DHTTPLIB_USE_SELECT=${{ matrix.select_impl == 'select' && 'ON' || 'OFF' }}
+      run: cmake -B build-no-ssl -S . -DCMAKE_BUILD_TYPE=Release -DCMAKE_TOOLCHAIN_FILE=${{ env.VCPKG_ROOT }}/scripts/buildsystems/vcpkg.cmake -DHTTPLIB_TEST=ON -DHTTPLIB_REQUIRE_OPENSSL=OFF -DHTTPLIB_REQUIRE_ZLIB=ON -DHTTPLIB_REQUIRE_BROTLI=ON
     - name: Build without SSL
-      run: cmake --build build-no-ssl --config Release -- /v:m /clp:ShowCommandLine /nologo
+      run: cmake --build build-no-ssl --config Release
     - name: Run tests without SSL
       run: ctest --output-on-failure --test-dir build-no-ssl -C Release
     env:

+ 0 - 5
CMakeLists.txt

@@ -8,7 +8,6 @@
 	* HTTPLIB_REQUIRE_ZLIB (default off)
 	* HTTPLIB_REQUIRE_BROTLI (default off)
 	* HTTPLIB_USE_CERTS_FROM_MACOSX_KEYCHAIN (default on)
-	* HTTPLIB_USE_SELECT (default off) choose between select() and poll()
 	* HTTPLIB_COMPILE (default off)
 	* HTTPLIB_INSTALL (default on)
 	* HTTPLIB_TEST (default off)
@@ -47,7 +46,6 @@
 	* HTTPLIB_IS_USING_ZLIB - a bool for if ZLIB support is enabled.
 	* HTTPLIB_IS_USING_BROTLI - a bool for if Brotli support is enabled.
 	* HTTPLIB_IS_USING_CERTS_FROM_MACOSX_KEYCHAIN - a bool for if support of loading system certs from the Apple Keychain is enabled.
-	* HTTPLIB_IS_USING_SELECT - a bool for if select() is used instead of poll().
 	* HTTPLIB_IS_COMPILED - a bool for if the library is compiled, or otherwise header-only.
 	* HTTPLIB_INCLUDE_DIR - the root path to httplib's header (e.g. /usr/include).
 	* HTTPLIB_LIBRARY - the full path to the library if compiled (e.g. /usr/lib/libhttplib.so).
@@ -103,7 +101,6 @@ option(HTTPLIB_TEST "Enables testing and builds tests" OFF)
 option(HTTPLIB_REQUIRE_BROTLI "Requires Brotli to be found & linked, or fails build." OFF)
 option(HTTPLIB_USE_BROTLI_IF_AVAILABLE "Uses Brotli (if available) to enable Brotli decompression support." ON)
 option(HTTPLIB_USE_CERTS_FROM_MACOSX_KEYCHAIN "Enable feature to load system certs from the Apple Keychain." ON)
-option(HTTPLIB_USE_SELECT "Uses select() instead of poll()." OFF)
 # Defaults to static library
 option(BUILD_SHARED_LIBS "Build the library as a shared library instead of static. Has no effect if using header-only." OFF)
 if (BUILD_SHARED_LIBS AND WIN32 AND HTTPLIB_COMPILE)
@@ -115,7 +112,6 @@ endif()
 # Set some variables that are used in-tree and while building based on our options
 set(HTTPLIB_IS_COMPILED ${HTTPLIB_COMPILE})
 set(HTTPLIB_IS_USING_CERTS_FROM_MACOSX_KEYCHAIN ${HTTPLIB_USE_CERTS_FROM_MACOSX_KEYCHAIN})
-set(HTTPLIB_IS_USING_SELECT ${HTTPLIB_USE_SELECT})
 
 # Threads needed for <thread> on some systems, and for <pthread.h> on Linux
 set(THREADS_PREFER_PTHREAD_FLAG TRUE)
@@ -242,7 +238,6 @@ target_compile_definitions(${PROJECT_NAME} ${_INTERFACE_OR_PUBLIC}
 	$<$<BOOL:${HTTPLIB_IS_USING_ZLIB}>:CPPHTTPLIB_ZLIB_SUPPORT>
 	$<$<BOOL:${HTTPLIB_IS_USING_OPENSSL}>:CPPHTTPLIB_OPENSSL_SUPPORT>
 	$<$<AND:$<PLATFORM_ID:Darwin>,$<BOOL:${HTTPLIB_IS_USING_OPENSSL}>,$<BOOL:${HTTPLIB_IS_USING_CERTS_FROM_MACOSX_KEYCHAIN}>>:CPPHTTPLIB_USE_CERTS_FROM_MACOSX_KEYCHAIN>
-	$<$<BOOL:${HTTPLIB_IS_USING_SELECT}>:CPPHTTPLIB_USE_SELECT>
 )
 
 # CMake configuration files installation directory

+ 0 - 5
README.md

@@ -872,11 +872,6 @@ res->body; // Compressed data
 
 ```
 
-Use `select()` instead of `poll()`
-----------------------------------
-
-cpp-httplib defaults to the widely supported `poll()` system call. If your OS lacks support for `poll()`, define `CPPHTTPLIB_USE_SELECT` to use `select()` instead.
-
 Unix Domain Socket Support
 --------------------------
 

+ 2 - 82
httplib.h

@@ -145,12 +145,6 @@
 #define CPPHTTPLIB_LISTEN_BACKLOG 5
 #endif
 
-#if !defined(CPPHTTPLIB_USE_POLL) && !defined(CPPHTTPLIB_USE_SELECT)
-#define CPPHTTPLIB_USE_POLL
-#elif defined(CPPHTTPLIB_USE_POLL) && defined(CPPHTTPLIB_USE_SELECT)
-#error "CPPHTTPLIB_USE_POLL and CPPHTTPLIB_USE_SELECT are mutually exclusive"
-#endif
-
 /*
  * Headers
  */
@@ -200,9 +194,7 @@ using ssize_t = long;
 
 using socket_t = SOCKET;
 using socklen_t = int;
-#ifdef CPPHTTPLIB_USE_POLL
 #define poll(fds, nfds, timeout) WSAPoll(fds, nfds, timeout)
-#endif
 
 #else // not _WIN32
 
@@ -222,16 +214,11 @@ using socklen_t = int;
 #ifdef __linux__
 #include <resolv.h>
 #endif
+#include <csignal>
 #include <netinet/tcp.h>
-#ifdef CPPHTTPLIB_USE_POLL
 #include <poll.h>
-#endif
-#include <csignal>
 #include <pthread.h>
 #include <sys/mman.h>
-#ifndef __VMS
-#include <sys/select.h>
-#endif
 #include <sys/socket.h>
 #include <sys/un.h>
 #include <unistd.h>
@@ -3267,7 +3254,6 @@ inline ssize_t send_socket(socket_t sock, const void *ptr, size_t size,
 
 template <bool Read>
 inline ssize_t select_impl(socket_t sock, time_t sec, time_t usec) {
-#ifdef CPPHTTPLIB_USE_POLL
   struct pollfd pfd;
   pfd.fd = sock;
   pfd.events = (Read ? POLLIN : POLLOUT);
@@ -3275,25 +3261,6 @@ inline ssize_t select_impl(socket_t sock, time_t sec, time_t usec) {
   auto timeout = static_cast<int>(sec * 1000 + usec / 1000);
 
   return handle_EINTR([&]() { return poll(&pfd, 1, timeout); });
-#else
-#ifndef _WIN32
-  if (sock >= FD_SETSIZE) { return -1; }
-#endif
-
-  fd_set fds, *rfds, *wfds;
-  FD_ZERO(&fds);
-  FD_SET(sock, &fds);
-  rfds = (Read ? &fds : nullptr);
-  wfds = (Read ? nullptr : &fds);
-
-  timeval tv;
-  tv.tv_sec = static_cast<long>(sec);
-  tv.tv_usec = static_cast<decltype(tv.tv_usec)>(usec);
-
-  return handle_EINTR([&]() {
-    return select(static_cast<int>(sock + 1), rfds, wfds, nullptr, &tv);
-  });
-#endif
 }
 
 inline ssize_t select_read(socket_t sock, time_t sec, time_t usec) {
@@ -3306,7 +3273,6 @@ inline ssize_t select_write(socket_t sock, time_t sec, time_t usec) {
 
 inline Error wait_until_socket_is_ready(socket_t sock, time_t sec,
                                         time_t usec) {
-#ifdef CPPHTTPLIB_USE_POLL
   struct pollfd pfd_read;
   pfd_read.fd = sock;
   pfd_read.events = POLLIN | POLLOUT;
@@ -3327,38 +3293,6 @@ inline Error wait_until_socket_is_ready(socket_t sock, time_t sec,
   }
 
   return Error::Connection;
-#else
-#ifndef _WIN32
-  if (sock >= FD_SETSIZE) { return Error::Connection; }
-#endif
-
-  fd_set fdsr;
-  FD_ZERO(&fdsr);
-  FD_SET(sock, &fdsr);
-
-  auto fdsw = fdsr;
-  auto fdse = fdsr;
-
-  timeval tv;
-  tv.tv_sec = static_cast<long>(sec);
-  tv.tv_usec = static_cast<decltype(tv.tv_usec)>(usec);
-
-  auto ret = handle_EINTR([&]() {
-    return select(static_cast<int>(sock + 1), &fdsr, &fdsw, &fdse, &tv);
-  });
-
-  if (ret == 0) { return Error::ConnectionTimeout; }
-
-  if (ret > 0 && (FD_ISSET(sock, &fdsr) || FD_ISSET(sock, &fdsw))) {
-    auto error = 0;
-    socklen_t len = sizeof(error);
-    auto res = getsockopt(sock, SOL_SOCKET, SO_ERROR,
-                          reinterpret_cast<char *>(&error), &len);
-    auto successful = res >= 0 && !error;
-    return successful ? Error::Success : Error::Connection;
-  }
-  return Error::Connection;
-#endif
 }
 
 inline bool is_socket_alive(socket_t sock) {
@@ -7208,20 +7142,6 @@ Server::process_request(Stream &strm, const std::string &remote_addr,
   res.version = "HTTP/1.1";
   res.headers = default_headers_;
 
-#ifdef _WIN32
-  // TODO: Increase FD_SETSIZE statically (libzmq), dynamically (MySQL).
-#else
-#ifndef CPPHTTPLIB_USE_POLL
-  // Socket file descriptor exceeded FD_SETSIZE...
-  if (strm.socket() >= FD_SETSIZE) {
-    Headers dummy;
-    detail::read_headers(strm, dummy);
-    res.status = StatusCode::InternalServerError_500;
-    return write_response(strm, close_connection, req, res);
-  }
-#endif
-#endif
-
   // Request line and headers
   if (!parse_request_line(line_reader.ptr(), req) ||
       !detail::read_headers(strm, req.headers)) {
@@ -10456,7 +10376,7 @@ inline SSL_CTX *Client::ssl_context() const {
 
 } // namespace httplib
 
-#if defined(_WIN32) && defined(CPPHTTPLIB_USE_POLL)
+#ifdef _WIN32
 #undef poll
 #endif
 

+ 1 - 10
meson.build

@@ -16,26 +16,17 @@ project(
   meson_version: '>=0.62.0'
 )
 
-cxx = meson.get_compiler('cpp')
-
 # Check just in case downstream decides to edit the source
 # and add a project version
 version = meson.project_version()
 if version == 'undefined'
+  cxx = meson.get_compiler('cpp')
   version = cxx.get_define('CPPHTTPLIB_VERSION',
     prefix: '#include <httplib.h>',
     include_directories: include_directories('.')).strip('"')
   assert(version != '', 'failed to get version from httplib.h')
 endif
 
-if cxx.has_function('poll', prefix: '#include <poll.h>')
-  # Use poll if present
-  add_project_arguments('-DCPPHTTPLIB_USE_POLL', language: 'cpp')
-elif cxx.has_function('select', prefix: '#include <sys/select.h>')
-  # Use select otherwise
-  add_project_arguments('-DCPPHTTPLIB_USE_SELECT', language: 'cpp')
-endif
-
 deps = [dependency('threads')]
 args = []
 

+ 0 - 4
test/Makefile

@@ -1,10 +1,6 @@
 CXX = clang++
 CXXFLAGS = -g -std=c++11 -I. -Wall -Wextra -Wtype-limits -Wconversion -Wshadow # -fno-exceptions -DCPPHTTPLIB_NO_EXCEPTIONS -fsanitize=address
 
-ifeq ($(SELECT_IMPL),select)
-    CXXFLAGS += -DCPPHTTPLIB_USE_SELECT
-endif
-
 PREFIX ?= $(shell brew --prefix)
 
 OPENSSL_DIR = $(PREFIX)/opt/openssl@3