Compare commits
No commits in common. "dist" and "v1.0.2" have entirely different histories.
28
LICENSE
28
LICENSE
@ -1,28 +0,0 @@
|
||||
wepoll - epoll for Windows
|
||||
https://github.com/piscisaureus/wepoll
|
||||
|
||||
Copyright 2012-2020, Bert Belder <bertbelder@gmail.com>
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
167
README.md
167
README.md
@ -1,18 +1,18 @@
|
||||
# wepoll - epoll for windows
|
||||
|
||||
[![][ci status badge]][ci status link]
|
||||
|
||||
This library implements the [epoll][man epoll] API for Windows
|
||||
applications. It is fast and scalable, and it closely resembles the API
|
||||
and behavior of Linux' epoll.
|
||||
This library implements the
|
||||
[epoll](http://man7.org/linux/man-pages/man7/epoll.7.html) API for
|
||||
Windows applications. It attempts to be efficient, and to match the
|
||||
Linux API and as closely as possible.
|
||||
|
||||
## Rationale
|
||||
|
||||
Unlike Linux, OS X, and many other operating systems, Windows doesn't
|
||||
have a good API for receiving socket state notifications. It only
|
||||
supports the `select` and `WSAPoll` APIs, but they
|
||||
[don't scale][select scale] and suffer from
|
||||
[other issues][wsapoll broken].
|
||||
[don't scale](https://daniel.haxx.se/docs/poll-vs-select.html)
|
||||
and suffer from
|
||||
[other issues](https://daniel.haxx.se/blog/2012/10/10/wsapoll-is-broken/).
|
||||
|
||||
Using I/O completion ports isn't always practical when software is
|
||||
designed to be cross-platform. Wepoll offers an alternative that is
|
||||
@ -21,40 +21,37 @@ to run on Linux.
|
||||
|
||||
## Features
|
||||
|
||||
* Can poll 100000s of sockets efficiently.
|
||||
* Fully thread-safe.
|
||||
* Multiple threads can poll the same epoll port.
|
||||
* Sockets can be added to multiple epoll sets.
|
||||
* All epoll events (`EPOLLIN`, `EPOLLOUT`, `EPOLLPRI`, `EPOLLRDHUP`)
|
||||
are supported.
|
||||
* Level-triggered and one-shot (`EPOLLONESTHOT`) modes are supported
|
||||
* Trivial to embed: you need [only two files][dist].
|
||||
* can poll 100000s of sockets efficiently
|
||||
* fully thread safe
|
||||
* multiple threads can poll the same epoll port
|
||||
* sockets can be added to multiple epoll sets
|
||||
* polling for `EPOLLIN`, `EPOLLOUT`, `EPOLLPRI`, `EPOLLRDHUP`,
|
||||
`EPOLLHUP`, and `EPOLLERR` events
|
||||
* `EPOLLONESTHOT` flag
|
||||
|
||||
## Limitations
|
||||
|
||||
* Only works with sockets.
|
||||
* Edge-triggered (`EPOLLET`) mode isn't supported.
|
||||
* only works with sockets
|
||||
* some modes not suported: `EPOLLET`, `EPOLLEXCLUSIVE`
|
||||
|
||||
## How to use
|
||||
|
||||
The library is [distributed][dist] as a single source file
|
||||
([wepoll.c][wepoll.c]) and a single header file ([wepoll.h][wepoll.h]).<br>
|
||||
Compile the .c file as part of your project, and include the header wherever
|
||||
needed.
|
||||
The library is distributed as a single source file (wepoll.c) and a
|
||||
single header file (wepoll.h). Compile the .c file as part of your
|
||||
project, and include the header wherever needed.
|
||||
|
||||
## Compatibility
|
||||
|
||||
* Requires Windows Vista or higher.
|
||||
* Can be compiled with recent versions of MSVC, Clang, and GCC.
|
||||
* Requires Windows 7 or higher.
|
||||
* Can be compiled with recent versions of MSVC and Clang.
|
||||
* GCC (mingw) should work (but is untested).
|
||||
|
||||
## API
|
||||
## API notes
|
||||
|
||||
### General remarks
|
||||
### General
|
||||
|
||||
* The epoll port is a `HANDLE`, not a file descriptor.
|
||||
* All functions set both `errno` and `GetLastError()` on failure.
|
||||
* For more extensive documentation, see the [epoll(7) man page][man epoll],
|
||||
and the per-function man pages that are linked below.
|
||||
|
||||
### epoll_create/epoll_create1
|
||||
|
||||
@ -64,10 +61,10 @@ HANDLE epoll_create1(int flags);
|
||||
```
|
||||
|
||||
* Create a new epoll instance (port).
|
||||
* `size` is ignored but most be greater than zero.
|
||||
* `size` is ignored but most be nonzero.
|
||||
* `flags` must be zero as there are no supported flags.
|
||||
* Returns `NULL` on failure.
|
||||
* [Linux man page][man epoll_create]
|
||||
* Returns `INVALID_HANDLE_VALUE` on failure.
|
||||
* [man page](http://man7.org/linux/man-pages/man2/epoll_create.2.html)
|
||||
|
||||
### epoll_close
|
||||
|
||||
@ -89,22 +86,15 @@ int epoll_ctl(HANDLE ephnd,
|
||||
```
|
||||
|
||||
* Control which socket events are monitored by an epoll port.
|
||||
* `ephnd` must be a HANDLE created by
|
||||
[`epoll_create()`](#epoll_createepoll_create1) or
|
||||
[`epoll_create1()`](#epoll_createepoll_create1).
|
||||
* `ephnd` must be a HANDLE created by `epoll_create` or `epoll_create1`.
|
||||
* `op` must be one of `EPOLL_CTL_ADD`, `EPOLL_CTL_MOD`, `EPOLL_CTL_DEL`.
|
||||
* `sock` must be a valid socket created by [`socket()`][msdn socket],
|
||||
[`WSASocket()`][msdn wsasocket], or [`accept()`][msdn accept].
|
||||
* `event` should be a pointer to a [`struct epoll_event`](#struct-epoll_event).<br>
|
||||
If `op` is `EPOLL_CTL_DEL` then the `event` parameter is ignored, and it
|
||||
may be `NULL`.
|
||||
* Returns 0 on success, -1 on failure.
|
||||
* It is recommended to always explicitly remove a socket from its epoll
|
||||
set using `EPOLL_CTL_DEL` *before* closing it.<br>
|
||||
As on Linux, closed sockets are automatically removed from the epoll set, but
|
||||
wepoll may not be able to detect that a socket was closed until the next call
|
||||
to [`epoll_wait()`](#epoll_wait).
|
||||
* [Linux man page][man epoll_ctl]
|
||||
set using `EPOLL_CTL_MOD` *before* closing it. As on Linux, sockets
|
||||
are automatically removed from the epoll set when they are closed, but
|
||||
wepoll may not be able to detect this until the next call to
|
||||
`epoll_wait()`.
|
||||
* TODO: expand
|
||||
* [man page](http://man7.org/linux/man-pages/man2/epoll_ctl.2.html)
|
||||
|
||||
### epoll_wait
|
||||
|
||||
@ -116,87 +106,10 @@ int epoll_wait(HANDLE ephnd,
|
||||
```
|
||||
|
||||
* Receive socket events from an epoll port.
|
||||
* `events` should point to a caller-allocated array of
|
||||
[`epoll_event`](#struct-epoll_event) structs, which will receive the
|
||||
reported events.
|
||||
* `maxevents` is the maximum number of events that will be written to the
|
||||
`events` array, and must be greater than zero.
|
||||
* `timeout` specifies whether to block when no events are immediately available.
|
||||
- `<0` block indefinitely
|
||||
- `0` report any events that are already waiting, but don't block
|
||||
- `≥1` block for at most N milliseconds
|
||||
* Return value:
|
||||
- `-1` an error occurred
|
||||
- `0` timed out without any events to report
|
||||
- `≥1` the number of events stored in the `events` buffer
|
||||
* [Linux man page][man epoll_wait]
|
||||
* Returns
|
||||
- -1 on failure
|
||||
- 0 when a timeout occurs
|
||||
- \>0 the number of evens received
|
||||
* TODO: expand
|
||||
* [man page](http://man7.org/linux/man-pages/man2/epoll_wait.2.html)
|
||||
|
||||
### struct epoll_event
|
||||
|
||||
```c
|
||||
typedef union epoll_data {
|
||||
void* ptr;
|
||||
int fd;
|
||||
uint32_t u32;
|
||||
uint64_t u64;
|
||||
SOCKET sock; /* Windows specific */
|
||||
HANDLE hnd; /* Windows specific */
|
||||
} epoll_data_t;
|
||||
```
|
||||
|
||||
```c
|
||||
struct epoll_event {
|
||||
uint32_t events; /* Epoll events and flags */
|
||||
epoll_data_t data; /* User data variable */
|
||||
};
|
||||
```
|
||||
|
||||
* The `events` field is a bit mask containing the events being
|
||||
monitored/reported, and optional flags.<br>
|
||||
Flags are accepted by [`epoll_ctl()`](#epoll_ctl), but they are not reported
|
||||
back by [`epoll_wait()`](#epoll_wait).
|
||||
* The `data` field can be used to associate application-specific information
|
||||
with a socket; its value will be returned unmodified by
|
||||
[`epoll_wait()`](#epoll_wait).
|
||||
* [Linux man page][man epoll_ctl]
|
||||
|
||||
| Event | Description |
|
||||
|---------------|----------------------------------------------------------------------|
|
||||
| `EPOLLIN` | incoming data available, or incoming connection ready to be accepted |
|
||||
| `EPOLLOUT` | ready to send data, or outgoing connection successfully established |
|
||||
| `EPOLLRDHUP` | remote peer initiated graceful socket shutdown |
|
||||
| `EPOLLPRI` | out-of-band data available for reading |
|
||||
| `EPOLLERR` | socket error<sup>1</sup> |
|
||||
| `EPOLLHUP` | socket hang-up<sup>1</sup> |
|
||||
| `EPOLLRDNORM` | same as `EPOLLIN` |
|
||||
| `EPOLLRDBAND` | same as `EPOLLPRI` |
|
||||
| `EPOLLWRNORM` | same as `EPOLLOUT` |
|
||||
| `EPOLLWRBAND` | same as `EPOLLOUT` |
|
||||
| `EPOLLMSG` | never reported |
|
||||
|
||||
| Flag | Description |
|
||||
|------------------|---------------------------|
|
||||
| `EPOLLONESHOT` | report event(s) only once |
|
||||
| `EPOLLET` | not supported by wepoll |
|
||||
| `EPOLLEXCLUSIVE` | not supported by wepoll |
|
||||
| `EPOLLWAKEUP` | not supported by wepoll |
|
||||
|
||||
<sup>1</sup>: the `EPOLLERR` and `EPOLLHUP` events may always be reported by
|
||||
[`epoll_wait()`](#epoll_wait), regardless of the event mask that was passed to
|
||||
[`epoll_ctl()`](#epoll_ctl).
|
||||
|
||||
|
||||
[ci status badge]: https://ci.appveyor.com/api/projects/status/github/piscisaureus/wepoll?branch=master&svg=true
|
||||
[ci status link]: https://ci.appveyor.com/project/piscisaureus/wepoll/branch/master
|
||||
[dist]: https://github.com/piscisaureus/wepoll/tree/dist
|
||||
[man epoll]: http://man7.org/linux/man-pages/man7/epoll.7.html
|
||||
[man epoll_create]: http://man7.org/linux/man-pages/man2/epoll_create.2.html
|
||||
[man epoll_ctl]: http://man7.org/linux/man-pages/man2/epoll_ctl.2.html
|
||||
[man epoll_wait]: http://man7.org/linux/man-pages/man2/epoll_wait.2.html
|
||||
[msdn accept]: https://msdn.microsoft.com/en-us/library/windows/desktop/ms737526(v=vs.85).aspx
|
||||
[msdn socket]: https://msdn.microsoft.com/en-us/library/windows/desktop/ms740506(v=vs.85).aspx
|
||||
[msdn wsasocket]: https://msdn.microsoft.com/en-us/library/windows/desktop/ms742212(v=vs.85).aspx
|
||||
[select scale]: https://daniel.haxx.se/docs/poll-vs-select.html
|
||||
[wsapoll broken]: https://daniel.haxx.se/blog/2012/10/10/wsapoll-is-broken/
|
||||
[wepoll.c]: https://github.com/piscisaureus/wepoll/blob/dist/wepoll.c
|
||||
[wepoll.h]: https://github.com/piscisaureus/wepoll/blob/dist/wepoll.h
|
||||
|
||||
60
wepoll.h
60
wepoll.h
@ -1,9 +1,9 @@
|
||||
/*
|
||||
* wepoll - epoll for Windows
|
||||
* https://github.com/piscisaureus/wepoll
|
||||
* Copyright 2012-2017, Bert Belder. All rights reserved.
|
||||
*
|
||||
* Copyright 2012-2020, Bert Belder <bertbelder@gmail.com>
|
||||
* All rights reserved.
|
||||
* The red-black tree implementation:
|
||||
* Copyright 2002 Niels Provos <provos@citi.umich.edu> All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
@ -39,32 +39,32 @@
|
||||
#include <stdint.h>
|
||||
|
||||
enum EPOLL_EVENTS {
|
||||
EPOLLIN = (int) (1U << 0),
|
||||
EPOLLPRI = (int) (1U << 1),
|
||||
EPOLLOUT = (int) (1U << 2),
|
||||
EPOLLERR = (int) (1U << 3),
|
||||
EPOLLHUP = (int) (1U << 4),
|
||||
EPOLLRDNORM = (int) (1U << 6),
|
||||
EPOLLRDBAND = (int) (1U << 7),
|
||||
EPOLLWRNORM = (int) (1U << 8),
|
||||
EPOLLWRBAND = (int) (1U << 9),
|
||||
EPOLLMSG = (int) (1U << 10), /* Never reported. */
|
||||
EPOLLRDHUP = (int) (1U << 13),
|
||||
EPOLLONESHOT = (int) (1U << 31)
|
||||
EPOLLIN = 1 << 0,
|
||||
EPOLLPRI = 1 << 1,
|
||||
EPOLLOUT = 1 << 2,
|
||||
EPOLLERR = 1 << 3,
|
||||
EPOLLHUP = 1 << 4,
|
||||
EPOLLRDNORM = 1 << 6,
|
||||
EPOLLRDBAND = 1 << 7,
|
||||
EPOLLWRNORM = 1 << 8,
|
||||
EPOLLWRBAND = 1 << 9,
|
||||
EPOLLMSG = 1 << 10,
|
||||
EPOLLRDHUP = 1 << 13,
|
||||
EPOLLONESHOT = 1 << 31
|
||||
};
|
||||
|
||||
#define EPOLLIN (1U << 0)
|
||||
#define EPOLLPRI (1U << 1)
|
||||
#define EPOLLOUT (1U << 2)
|
||||
#define EPOLLERR (1U << 3)
|
||||
#define EPOLLHUP (1U << 4)
|
||||
#define EPOLLRDNORM (1U << 6)
|
||||
#define EPOLLRDBAND (1U << 7)
|
||||
#define EPOLLWRNORM (1U << 8)
|
||||
#define EPOLLWRBAND (1U << 9)
|
||||
#define EPOLLMSG (1U << 10)
|
||||
#define EPOLLRDHUP (1U << 13)
|
||||
#define EPOLLONESHOT (1U << 31)
|
||||
#define EPOLLIN EPOLLIN
|
||||
#define EPOLLPRI EPOLLPRI
|
||||
#define EPOLLOUT EPOLLOUT
|
||||
#define EPOLLERR EPOLLERR
|
||||
#define EPOLLHUP EPOLLHUP
|
||||
#define EPOLLRDNORM EPOLLRDNORM
|
||||
#define EPOLLRDBAND EPOLLRDBAND
|
||||
#define EPOLLWRNORM EPOLLWRNORM
|
||||
#define EPOLLWRBAND EPOLLWRBAND
|
||||
#define EPOLLMSG EPOLLMSG
|
||||
#define EPOLLRDHUP EPOLLRDHUP
|
||||
#define EPOLLONESHOT EPOLLONESHOT
|
||||
|
||||
#define EPOLL_CTL_ADD 1
|
||||
#define EPOLL_CTL_MOD 2
|
||||
@ -78,12 +78,12 @@ typedef union epoll_data {
|
||||
int fd;
|
||||
uint32_t u32;
|
||||
uint64_t u64;
|
||||
SOCKET sock; /* Windows specific */
|
||||
HANDLE hnd; /* Windows specific */
|
||||
SOCKET sock;
|
||||
HANDLE hnd;
|
||||
} epoll_data_t;
|
||||
|
||||
struct epoll_event {
|
||||
uint32_t events; /* Epoll events and flags */
|
||||
uint32_t events; /* Epoll events */
|
||||
epoll_data_t data; /* User data variable */
|
||||
};
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user