In linux, epoll, EPOLLHUP may happen even if no connection call is made. It
would confuse callers for what is actually happening.
Replaced is_connect_failed, and we detect if connection failed by using the
combination of is_err and is_interrupt, please see the example, tcp_client
HermitOS is a microkernel target aiming to provide a simple OS for
virtualized applications. It recently added support for the poll() and
eventfd() system calls, which means we can target it with our poll()
based backend.
Hermit does not have a traditional libc; instead it uses hermit-abi.
However rustix does not support using hermit-abi as its underlying
layer yet. So we have to build a shim layer until it does.
Closes#177
cc bytecodealliance/rustix#1012
Signed-off-by: John Nunley <dev@notgull.net>
Technically RedoxOS supports the poll syscall, so we already support
RedoxOS. However, this is very slow. This commit ports this code to
epoll, which should be more efficient.
Closes#176
Previous, `Poller::wait` would bubble signal interruption error to the user.
However, this may be unexpected for simple use cases. Thus, this commit makes
it so, if `ErrorKind::Interrupted` is received by the underlying `wait()` call,
it clears the events and tries to wait again.
This also adds a test for this interruption written by @psychon.
Co-Authored-By: Uli Schlachter <psychon@users.noreply.github.com>
Signed-off-by: John Nunley <dev@notgull.net>
Once upon a time, this got a Vec as an argument, but that was replaced
with the Events struct. Thus, this should link to Events and not Vec.
Signed-off-by: Uli Schlachter <psychon@znc.in>
Added in 272bb11eaf for reasons that are
unclear to me. It serves no purpose aside from disabling the API of the
entire crate, so it's best to remove it.
Signed-off-by: John Nunley <dev@notgull.net>
This adds documentation to add() describing what happens when a source
is registered in multiple pollers. A test is also added to ensure this
behavior.
Signed-off-by: John Nunley <dev@notgull.net>
* Add better documentation for the IOCP module
* Extract Events from Poller
This prevents the need to have an intermediate buffer to read events
from, reducing the need for an allocation and a copy. This is a breaking
change.
* Add event extra information
Foundation for more details later on.
* Add PRI and HUP events
* Fix various failing tests
- Make sure that waitable handles interact properly with the new
infrastructure
- Fix failing doctests
* Review comments
- Make set_* take a boolean for the value of the flag
- Make Events !Sync
- Fix visibility modifiers
- Inline more methods
- Use a better strategy for testing
* Move completion packets into the Events buffer
This removes one of the mutexes that we have to lock.
* Review comments
Signed-off-by: John Nunley <dev@notgull.net>
Reimplements the C-based wepoll backend in Rust, using some handwritten code. This PR also implements bindings to the I/O Completion Ports and \Device\Afd APIs. For more information on the latter, see my blog post on the subject: https://notgull.github.io/device-afd/
Note that the IOCP API is wrapped using a `Pin`-oriented "CompletionHandle" system that is relatively brittle. This should be replaced with a better model when one becomes available.
* feat: Expose other kqueue filters
* Fix netbsd/openbsd compilation
* Build MSRV for FreeBsd/OpenBsd in CI
* Only run MSRV BSD builds on Linux
* Change API a little + fix netbsd timer
* Add inlines + move PollerSealed
* rustfmt
* Make filter fields public
* Fix examples
This replaces Poller.insert() and Poller.interest() with Poller.add()
and Poller.modify(), and renames Poller.remove() to Poller.delete().
The method Poller.add() is used for adding a new file descriptor, while
Poller.modify() is used for updating an existing one. Poller.remove() is
renamed to Poller.delete() so the naming scheme of these methods follows
that of epoll, wepoll, etc.
This new setup means that adding a new socket only requires a single
call of Poller.add(), instead of a combination of Poller.insert() and
Poller.interest(). This reduces the amount of system calls necessary,
and leads to a more pleasant API.
On systems that use kqueue or ports, the behaviour of Poller.add() and
Poller.modify() is the same. This is because on these systems adding an
already existing file descriptor will just update its configuration.
This however is an implementation detail and should not be relied upon
by users.
Migrating to this new API is pretty simple, simply replace this:
poller.insert(&socket);
poller.interest(&socket, event);
With this:
poller.add(&socket, event);
And for cases where Poller.interest() was used for updating an existing
file descriptor, simply replace it will a call to Poller.modify().
See https://github.com/stjepang/polling/issues/16 and
https://github.com/stjepang/polling/pull/17 for more information.
This adds redundant system call overhead for file descriptors which have
already been turned into non-blocking file descriptors. In addition, the
polling crate doesn't need to implement platform specific code for
enabling non-blocking mode. Instead, users of polling can do so using
(for example) standard library methods such as
TcpListener.set_nonblocking().
See https://github.com/stjepang/polling/issues/16 for more information.