You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

README.md 7.8KB

6 months ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202
  1. # wepoll - epoll for windows
  2. [![][ci status badge]][ci status link]
  3. This library implements the [epoll][man epoll] API for Windows
  4. applications. It is fast and scalable, and it closely resembles the API
  5. and behavior of Linux' epoll.
  6. ## Rationale
  7. Unlike Linux, OS X, and many other operating systems, Windows doesn't
  8. have a good API for receiving socket state notifications. It only
  9. supports the `select` and `WSAPoll` APIs, but they
  10. [don't scale][select scale] and suffer from
  11. [other issues][wsapoll broken].
  12. Using I/O completion ports isn't always practical when software is
  13. designed to be cross-platform. Wepoll offers an alternative that is
  14. much closer to a drop-in replacement for software that was designed
  15. to run on Linux.
  16. ## Features
  17. * Can poll 100000s of sockets efficiently.
  18. * Fully thread-safe.
  19. * Multiple threads can poll the same epoll port.
  20. * Sockets can be added to multiple epoll sets.
  21. * All epoll events (`EPOLLIN`, `EPOLLOUT`, `EPOLLPRI`, `EPOLLRDHUP`)
  22. are supported.
  23. * Level-triggered and one-shot (`EPOLLONESTHOT`) modes are supported
  24. * Trivial to embed: you need [only two files][dist].
  25. ## Limitations
  26. * Only works with sockets.
  27. * Edge-triggered (`EPOLLET`) mode isn't supported.
  28. ## How to use
  29. The library is [distributed][dist] as a single source file
  30. ([wepoll.c][wepoll.c]) and a single header file ([wepoll.h][wepoll.h]).<br>
  31. Compile the .c file as part of your project, and include the header wherever
  32. needed.
  33. ## Compatibility
  34. * Requires Windows Vista or higher.
  35. * Can be compiled with recent versions of MSVC, Clang, and GCC.
  36. ## API
  37. ### General remarks
  38. * The epoll port is a `HANDLE`, not a file descriptor.
  39. * All functions set both `errno` and `GetLastError()` on failure.
  40. * For more extensive documentation, see the [epoll(7) man page][man epoll],
  41. and the per-function man pages that are linked below.
  42. ### epoll_create/epoll_create1
  43. ```c
  44. HANDLE epoll_create(int size);
  45. HANDLE epoll_create1(int flags);
  46. ```
  47. * Create a new epoll instance (port).
  48. * `size` is ignored but most be greater than zero.
  49. * `flags` must be zero as there are no supported flags.
  50. * Returns `NULL` on failure.
  51. * [Linux man page][man epoll_create]
  52. ### epoll_close
  53. ```c
  54. int epoll_close(HANDLE ephnd);
  55. ```
  56. * Close an epoll port.
  57. * Do not attempt to close the epoll port with `close()`,
  58. `CloseHandle()` or `closesocket()`.
  59. ### epoll_ctl
  60. ```c
  61. int epoll_ctl(HANDLE ephnd,
  62. int op,
  63. SOCKET sock,
  64. struct epoll_event* event);
  65. ```
  66. * Control which socket events are monitored by an epoll port.
  67. * `ephnd` must be a HANDLE created by
  68. [`epoll_create()`](#epoll_createepoll_create1) or
  69. [`epoll_create1()`](#epoll_createepoll_create1).
  70. * `op` must be one of `EPOLL_CTL_ADD`, `EPOLL_CTL_MOD`, `EPOLL_CTL_DEL`.
  71. * `sock` must be a valid socket created by [`socket()`][msdn socket],
  72. [`WSASocket()`][msdn wsasocket], or [`accept()`][msdn accept].
  73. * `event` should be a pointer to a [`struct epoll_event`](#struct-epoll_event).<br>
  74. If `op` is `EPOLL_CTL_DEL` then the `event` parameter is ignored, and it
  75. may be `NULL`.
  76. * Returns 0 on success, -1 on failure.
  77. * It is recommended to always explicitly remove a socket from its epoll
  78. set using `EPOLL_CTL_DEL` *before* closing it.<br>
  79. As on Linux, closed sockets are automatically removed from the epoll set, but
  80. wepoll may not be able to detect that a socket was closed until the next call
  81. to [`epoll_wait()`](#epoll_wait).
  82. * [Linux man page][man epoll_ctl]
  83. ### epoll_wait
  84. ```c
  85. int epoll_wait(HANDLE ephnd,
  86. struct epoll_event* events,
  87. int maxevents,
  88. int timeout);
  89. ```
  90. * Receive socket events from an epoll port.
  91. * `events` should point to a caller-allocated array of
  92. [`epoll_event`](#struct-epoll_event) structs, which will receive the
  93. reported events.
  94. * `maxevents` is the maximum number of events that will be written to the
  95. `events` array, and must be greater than zero.
  96. * `timeout` specifies whether to block when no events are immediately available.
  97. - `<0` block indefinitely
  98. - `0` report any events that are already waiting, but don't block
  99. - `≥1` block for at most N milliseconds
  100. * Return value:
  101. - `-1` an error occurred
  102. - `0` timed out without any events to report
  103. - `≥1` the number of events stored in the `events` buffer
  104. * [Linux man page][man epoll_wait]
  105. ### struct epoll_event
  106. ```c
  107. typedef union epoll_data {
  108. void* ptr;
  109. int fd;
  110. uint32_t u32;
  111. uint64_t u64;
  112. SOCKET sock; /* Windows specific */
  113. HANDLE hnd; /* Windows specific */
  114. } epoll_data_t;
  115. ```
  116. ```c
  117. struct epoll_event {
  118. uint32_t events; /* Epoll events and flags */
  119. epoll_data_t data; /* User data variable */
  120. };
  121. ```
  122. * The `events` field is a bit mask containing the events being
  123. monitored/reported, and optional flags.<br>
  124. Flags are accepted by [`epoll_ctl()`](#epoll_ctl), but they are not reported
  125. back by [`epoll_wait()`](#epoll_wait).
  126. * The `data` field can be used to associate application-specific information
  127. with a socket; its value will be returned unmodified by
  128. [`epoll_wait()`](#epoll_wait).
  129. * [Linux man page][man epoll_ctl]
  130. | Event | Description |
  131. |---------------|----------------------------------------------------------------------|
  132. | `EPOLLIN` | incoming data available, or incoming connection ready to be accepted |
  133. | `EPOLLOUT` | ready to send data, or outgoing connection successfully established |
  134. | `EPOLLRDHUP` | remote peer initiated graceful socket shutdown |
  135. | `EPOLLPRI` | out-of-band data available for reading |
  136. | `EPOLLERR` | socket error<sup>1</sup> |
  137. | `EPOLLHUP` | socket hang-up<sup>1</sup> |
  138. | `EPOLLRDNORM` | same as `EPOLLIN` |
  139. | `EPOLLRDBAND` | same as `EPOLLPRI` |
  140. | `EPOLLWRNORM` | same as `EPOLLOUT` |
  141. | `EPOLLWRBAND` | same as `EPOLLOUT` |
  142. | `EPOLLMSG` | never reported |
  143. | Flag | Description |
  144. |------------------|---------------------------|
  145. | `EPOLLONESHOT` | report event(s) only once |
  146. | `EPOLLET` | not supported by wepoll |
  147. | `EPOLLEXCLUSIVE` | not supported by wepoll |
  148. | `EPOLLWAKEUP` | not supported by wepoll |
  149. <sup>1</sup>: the `EPOLLERR` and `EPOLLHUP` events may always be reported by
  150. [`epoll_wait()`](#epoll_wait), regardless of the event mask that was passed to
  151. [`epoll_ctl()`](#epoll_ctl).
  152. [ci status badge]: https://ci.appveyor.com/api/projects/status/github/piscisaureus/wepoll?branch=master&svg=true
  153. [ci status link]: https://ci.appveyor.com/project/piscisaureus/wepoll/branch/master
  154. [dist]: https://github.com/piscisaureus/wepoll/tree/dist
  155. [man epoll]: http://man7.org/linux/man-pages/man7/epoll.7.html
  156. [man epoll_create]: http://man7.org/linux/man-pages/man2/epoll_create.2.html
  157. [man epoll_ctl]: http://man7.org/linux/man-pages/man2/epoll_ctl.2.html
  158. [man epoll_wait]: http://man7.org/linux/man-pages/man2/epoll_wait.2.html
  159. [msdn accept]: https://msdn.microsoft.com/en-us/library/windows/desktop/ms737526(v=vs.85).aspx
  160. [msdn socket]: https://msdn.microsoft.com/en-us/library/windows/desktop/ms740506(v=vs.85).aspx
  161. [msdn wsasocket]: https://msdn.microsoft.com/en-us/library/windows/desktop/ms742212(v=vs.85).aspx
  162. [select scale]: https://daniel.haxx.se/docs/poll-vs-select.html
  163. [wsapoll broken]: https://daniel.haxx.se/blog/2012/10/10/wsapoll-is-broken/
  164. [wepoll.c]: https://github.com/piscisaureus/wepoll/blob/dist/wepoll.c
  165. [wepoll.h]: https://github.com/piscisaureus/wepoll/blob/dist/wepoll.h