With #6779 we removed unnecessary allocations from the timerwheel by
wrapping it in an `std::sync::RwLock`. Since the `Mutex` used in this
part of the project uses an abstraction in `loom::sync::Mutex` to get
rid of the poisoning aspects of `std::sync::Mutex` the same should
probably be done for the used read-write lock struct.
This commit introduces an abstraction to get rid of the poisoning
aspects of `std::sync::RwLock` by introducing a wrapper to the
`loom::sync` module similar to `loom::sync::Mutex`.
Refs: #6779
Adds join_all method to JoinSet. join_all consumes JoinSet and awaits
the completion of all tasks on it, returning the results of the tasks in
a vec. An error or panic in the task will cause join_all to panic,
canceling all other tasks.
Fixes: #6664
## Motivation
Currently, the test `uds_stream::epollhup` expects that a
`UdsStream::connect` future to a Unix socket which is closed by the
accept side to always fail with `io::ErrorKind::ConnectionReset`. On
illumos, and potentially other systems, it instead fails with
`io::ErrorKind::ConnectionRefused`.
This was discovered whilst adding an illumos CI job in PR #6769. See:
https://github.com/tokio-rs/tokio/pull/6769#issuecomment-2284753794
## Solution
This commit changes the test to accept either `ConenctionReset` or
`ConnectionRefused`. This way, we are more tolerant of different
operating systems which may decide to return slightly different errnos
here. Both ECONNREFUSED and ECONNRESET seem reasonable to expect in this
situation, although arguably, ECONNREFUSED is actually more correct: the
acceptor did not accept the connection at all, which seems like
"refusing" it to me...
* tests: handle spurious EWOULDBLOCK in io_async_fd
## Motivation
The `io_async_fd.rs` tests contain a `drain()` function, which
currently performs synchronous reads from a UDS socket until it returns
`io::ErrorKind::WouldBlock` (i.e., errno `EWOULDBLOCK`/`EAGAIN`). The
*intent* behind this function is to ensure that all data has been
drained from the UDS socket's buffer...which is what it appears to
do...on Linux. On other systems, it appears that an `EWOULDBLOCK` or
`EAGAIN` may be returned before enough data has been read from the UDS
socket to result in the other end being notified that the socket is now
writable. In particular, this appears to be the case on illumos, where
the tests using this function hang forever (see [this comment][1] on PR
#6769).
To my knowledge, this behavior is still POSIX-compliant --- the
reader will still be notified that the socket is readable, and if it
were actually doing non-blocking IO, it would continue reading upon
receipt of that notification. So, relying on `EWOULDBLOCK` to indicate
that the socket has been sufficiently drained appears to rely on
Linux/FreeBSD behavior that isn't necessarily portable to other Unices.
## Solution
This commit changes the `drain()` function to take an argument for the
number of bytes *written* to the socket previously, and continue looping
until it has read that many bytes, regardless of whether `EWOULDBLOCK`
is returned. This should ensure that the socket is drained on all
POSIX-compliant systems, and indeed, the `io_async_fd::reset_writable`
and `io_async_fd::poll_fns` tests no longer hang forever on illumos.
I think making this change is an appropriate solution to the
test failure here, as the `drain()` function is part of the test, rather
than the code in Tokio *being* tested, and (as I mentioned above) the
use of blocking reads on a non-blocking socket without a mechanism to
continue reading when the socket becomes readable again is not really
something a real life program seems likely to do. Ensuring that all the
written bytes have been read by passing in a byte count seems more
faithful to what the test is actually *trying* to do here, anyway.
Thanks to @jclulow for debugging what was going on here!
This change was cherry-picked from commit
f18d6ed7d4e0724bbe14db5519d7c80b3227a1a9 from PR #6769, so that the fix
can be merged separately.
[1]: https://github.com/tokio-rs/tokio/pull/6769#issuecomment-2284753794
Signed-off-by: Eliza Weisman <eliza@elizas.website>
## Motivation
As described in #6763, Tokio compiles for the [illumos] operating
system, but we don't presently have automated tests on illumos. We would
like to add illumos CI jobs for Tokio using [Buildomat], a CI system
which supports illumos. Buildomat CI jobs for Tokio will run on
infrastructure contributed by Oxide Computer Company.
In order for Buildomat to watch for commits to the repo, we must first
add a configuration file in `.github/buildomat/config.toml` with the
`enable = true` key. This config file must be present on the repo's main
branch for Buildomat to enable builds for the repo. See [here] for
details.
## Solution
This branch adds a `.github/buildomat` directory containing a config
file and a README summarizing what the configs in that directory are
for, as well as documenting how to get help diagnosing illumos CI
failures.
This branch does *not* add scripts for actually running CI jobs on
Buildomat. Since the config file must be present on the repo's main
branch before Buildomat runs CI jobs for the repo, I'd like to merge the
config file separately from the actual build scripts. This way, I can
actually have the build jobs run on the PR that adds them, making it
easier to ensure everything is working correctly before merging.
Closes#6766, which is obsoleted by this branch.
[illumos]: https://www.illumos.org/
[Buildomat]: https://github.com/oxidecomputer/
[here]:
https://github.com/oxidecomputer/buildomat/blob/main/README.md#per-repository-configuration