summaryrefslogtreecommitdiffstats
path: root/tokio/src/util/slab.rs
AgeCommit message (Collapse)Author
2020-10-21net: fix use-after-free in slab compaction (#3019)Carl Lerche
An off-by-one bug results in freeing the incorrect page. This also adds an `asan` CI job. Fixes: 3014
2020-10-12rt: simplify rt-* features (#2949)Taiki Endo
tokio: merge rt-core and rt-util as rt rename rt-threaded to rt-multi-thread tokio-util: rename rt-core to rt Closes #2942
2020-10-12rt: Remove `threaded_scheduler()` and `basic_scheduler()` (#2876)Lucio Franco
Co-authored-by: Alice Ryhl <alice@ryhl.io> Co-authored-by: Carl Lerche <me@carllerche.com>
2020-09-25chore: handle std `Mutex` poisoning in a shim (#2872)Zahari Dichev
As tokio does not rely on poisoning, we can avoid always unwrapping when locking by handling the `PoisonError` in the Mutex shim. Signed-off-by: Zahari Dichev <zaharidichev@gmail.com>
2020-09-23io: use intrusive wait list for I/O driver (#2828)Sean McArthur
This refactors I/O registration in a few ways: - Cleans up the cached readiness in `PollEvented`. This cache used to be helpful when readiness was a linked list of `*mut Node`s in `Registration`. Previous refactors have turned `Registration` into just an `AtomicUsize` holding the current readiness, so the cache is just extra work and complexity. Gone. - Polling the `Registration` for readiness now gives a `ReadyEvent`, which includes the driver tick. This event must be passed back into `clear_readiness`, so that the readiness is only cleared from `Registration` if the tick hasn't changed. Previously, it was possible to clear the readiness even though another thread had *just* polled the driver and found the socket ready again. - Registration now also contains an `async fn readiness`, which stores wakers in an instrusive linked list. This allows an unbounded number of tasks to register for readiness (previously, only 1 per direction (read and write)). By using the intrusive linked list, there is no concern of leaking the storage of the wakers, since they are stored inside the `async fn` and released when the future is dropped. - Registration retains a `poll_readiness(Direction)` method, to support `AsyncRead` and `AsyncWrite`. They aren't able to use `async fn`s, and so there are 2 reserved slots for those methods. - IO types where it makes sense to have multiple tasks waiting on them now take advantage of this new `async fn readiness`, such as `UdpSocket` and `UnixDatagram`. Additionally, this makes the `io-driver` "feature" internal-only (no longer documented, not part of public API), and adds a second internal-only feature, `io-readiness`, to group together linked list part of registration that is only used by some of the IO types. After a bit of discussion, changing stream-based transports (like `TcpStream`) to have `async fn read(&self)` is punted, since that is likely too easy of a footgun to activate. Refs: #2779, #2728
2020-08-11io: rewrite slab to support compaction (#2757)Carl Lerche
The I/O driver uses a slab to store per-resource state. Doing this provides two benefits. First, allocating state is streamlined. Second, resources may be safely indexed using a `usize` type. The `usize` is used passed to the OS's selector when registering for receiving events. The original slab implementation used a `Vec` backed by `RwLock`. This primarily caused contention when reading state. This implementation also only **grew** the slab capacity but never shrank. In #1625, the slab was rewritten to use a lock-free strategy. The lock contention was removed but this implementation was still grow-only. This change adds the ability to release memory. Similar to the previous implementation, it structures the slab to use a vector of pages. This enables growing the slab without having to move any previous entries. It also adds the ability to release pages. This is done by introducing a lock when allocating/releasing slab entries. This does not impact benchmarks, primarily due to the existing implementation not being "done" and also having a lock around allocating and releasing. A `Slab::compact()` function is added. Pages are iterated. When a page is found with no slots in use, the page is freed. The `compact()` function is called occasionally by the I/O driver. Fixes #2505