jsocketpp 1.0
A cross-platform C++20 socket library.
Loading...
Searching...
No Matches
We use select for asynchronous I/O operations. Does it make sense to provide poll and epoll as alternatives?

CC0

Disclaimer: ChatGPT generated document.


1. Why select is Used

  • Portability: select is available on both POSIX (Linux, macOS, BSD, etc.) and Windows (as select() in Winsock), making it the lowest common denominator for cross-platform socket libraries.
  • Simple APIs: Easy to use for a small number of sockets.

2. Drawbacks of select

  • Limited file descriptors: On many systems, select is limited to 1024 file descriptors (FD_SETSIZE), which restricts scalability for servers handling many connections.
  • Performance: Scanning all file descriptors is inefficient for a large number of sockets.
  • Inefficiency: Rebuilding the FD sets on every call can be expensive for many descriptors.

3. Advantages of poll

  • No hard FD limit: poll works with arbitrary file descriptor values and isn’t limited by FD_SETSIZE.
  • Slightly better scaling: The API is a bit more modern than select.
  • Availability: Available on almost all POSIX systems (not native on Windows).

4. Advantages of epoll

  • Scalability: epoll (Linux only) is highly scalable, efficient for thousands of sockets (O(1) wakeups).
  • Edge/level triggered: More flexible event models.
  • Event-driven servers: The industry standard for high-performance Linux network servers.

5. Windows Counterparts

  • WSAPoll: Since Windows Vista, Winsock provides WSAPoll (similar to POSIX poll), but there is no native epoll equivalent. For high-performance on Windows, use I/O completion ports (IOCP).

6. Cross-Platform API Considerations

If your library’s goal is simple, Java-like, cross-platform sockets, here are the usual trade-offs:

  • For simple sockets and connection timeouts, select suffices and works everywhere.
  • If you want to support high-performance servers, it’s beneficial to provide an abstraction over:
    • select (default, portable)
    • poll (if available)
    • epoll (Linux)
    • IOCP (Windows, advanced)
  • Java NIO does this via the Selector API, abstracting over the platform details.

7. Practical Recommendations

  • For most applications: Using select (as you do now) is fine and maximizes portability.
  • For advanced/massively concurrent servers: Exposing poll/epoll/IOCP as optional APIs is a great enhancement.
  • How to design:
    • Provide an abstract “Selector” or “EventLoop” class with a runtime-chosen backend (select/poll/epoll/IOCP).
    • Users needing performance can opt-in; everyone else uses the default.

8. Summary Table

Feature select poll epoll WSAPoll IOCP
POSIX ✔️ ✔️ Linux
Windows ✔️ ✔️ ✔️
Scalability Limited OK Excellent OK Excellent
Simplicity Simple OK Advanced OK Advanced

9. Conclusion / Advice

  • Keep select for basic API and portability.
  • Optionally add support for poll, epoll, or IOCP for advanced users.
  • If you want a Java-like interface, consider a class like Selector with backend selection, and document the differences per platform.