1941 Commits

Author SHA1 Message Date
Carl Lerche
8381dff39b
chore: link mini-redis in examples (#2407) 2020-04-15 15:30:03 -07:00
xliiv
9553355c27
doc: fix a few broken links (#2400) 2020-04-13 17:25:28 +02:00
Taiki Endo
770d0ec452
ci: fix FreeBSD CI (#2403) 2020-04-13 14:41:42 +02:00
Alice Ryhl
5376f9181f
chore: prepare to release 0.2.18 (#2399) tokio-0.2.18 2020-04-12 20:40:34 -07:00
Alice Ryhl
4fc2adae4f
task: make LocalSet non-Send (#2398)
This does not count as a breaking change as it fixes a
regression and a soundness bug.
2020-04-12 14:55:37 -07:00
xliiv
f39c15334e
docs: replace some html links with rustdoc paths (#2381)
Included changes
- all simple references like `<type>.<name>.html` for these types
    - enum
    - fn
    - struct
    - trait
    - type
- simple references for methods, like struct.DelayQueue.html#method.poll

Refs: #1473
2020-04-12 10:25:55 -07:00
shuo
060d22bd10
io: report error on zero-write in write_int (#2334)
* tokio-io: make write_i* same behavior as write_all when poll_write returns Ok(0)

Fixes: #2329

Co-authored-by: lishuo <lishuo.03@bytedance.com>
2020-04-12 16:05:03 +02:00
Nikita Baksalyar
8118f8f117
docs: fix incorrect documentation links & formatting (#2332)
The streams documentation referred to module-level 'split' doc which is no longer there
2020-04-12 15:59:37 +02:00
Max Inden
1e679748ec
docs: remove duplicate "a listener" (#2395) 2020-04-12 15:41:14 +02:00
Eliza Weisman
3137c6f07d
chore: prepare to release 0.2.17 (#2392)
# 0.2.17 (April 9, 2020)

### Fixes
- rt: bug in work-stealing queue (#2387) 

### Changes 
- rt: threadpool uses logical CPU count instead of physical by default
  (#2391)


Signed-off-by: Eliza Weisman <eliza@buoyant.io>
tokio-0.2.17
2020-04-09 13:49:19 -07:00
Sean McArthur
d294c992e7
Use logical CPUs instead of physical by default (#2391)
Some reasons to prefer logical count as the default:

- Chips reporting many logical CPUs vs physical, such as via
hyperthreading, probably know better than us about the workload the CPUs
can handle.
- The logical count (`num_cpus::get()`) takes into consideration
schedular affinity, and cgroups CPU quota, in case the user wants to
limit the amount of CPUs a process can use.

Closes #2269
2020-04-09 12:42:46 -07:00
Carl Lerche
58ba45a38c
rt: fix bug in work-stealing queue (#2387)
Fixes a couple bugs in the work-stealing queue introduced as
part of #2315. First, the cursor needs to be able to represent more
values than the size of the buffer. This is to be able to track if
`tail` is ahead of `head` or if they are identical. This bug resulted in
the "overflow" path being taken before the buffer was full.

The second bug can happen when a queue is being stolen from concurrently
with stealing into. In this case, it is possible for buffer slots to be
overwritten before they are released by the stealer. This is harder to
happen in practice due to the first bug preventing the queue from
filling up 100%, but could still happen. It triggered an assertion in
`steal_into`. This bug slipped through due to a bug in loom not
correctly catching the case. The loom bug is fixed as part of
tokio-rs/loom#119.

Fixes: #2382
2020-04-09 11:35:16 -07:00
nasa
de8326a5a4
doc: Sort methods on mpsc::Sender in doc (#2379) 2020-04-06 22:49:10 +02:00
Vojtech Kral
d65bf3805b
doc: add error explanation for UnboundedSender::send() (#2372) 2020-04-04 19:36:12 +02:00
Alice Ryhl
7c1bc460f7
test: add Send/Sync tests for all async fns (#2377)
Also updates Empty and Pending to be unconditionally Send and Sync.
2020-04-04 19:02:26 +02:00
Eliza Weisman
d883ac0fa0
chore: prepare tokio 0.2.16 release
# 0.2.16 (April 3, 2020)

### Fixes

- sync: fix a regression where `Mutex`, `Semaphore`, and `RwLock` futures no
  longer implement `Sync` (#2375)
- fs: fix `fs::copy` not copying file permissions (#2354)

### Added

- time: added `deadline` method to `delay_queue::Expired` (#2300)
- io: added `StreamReader` (#2052) 

Signed-off-by: Eliza Weisman <eliza@buoyant.io>
tokio-0.2.16
2020-04-03 17:00:42 -07:00
Eliza Weisman
1121a8eb23
sync: ensure Mutex, RwLock, and Semaphore futures are Send + Sync (#2375)
Previously, the `Mutex::lock`, `RwLock::{read, write}`, and
`Semaphore::acquire` futures in `tokio::sync` implemented `Send + Sync`
automatically. This was by virtue of being implemented using a `poll_fn`
that only closed over `Send + Sync` types. However, this broke in
PR #2325, which rewrote those types using the new `batch_semaphore`.
Now, they await an `Acquire` future, which contains a `Waiter`, which
internally contains an `UnsafeCell`, and thus does not implement `Sync`.

Since removing previously implemented traits breaks existing code, this
inadvertantly caused a breaking change. There were tests ensuring that
the `Mutex`, `RwLock`, and `Semaphore` types themselves were `Send +
Sync`, but no tests that the _futures they return_ implemented those
traits.

I've fixed this by adding an explicit impl of `Sync` for the
`batch_semaphore::Acquire` future. Since the `Waiter` type held by this
struct is only accessed when borrowed mutably, it is safe for it to
implement `Sync`.

Additionally, I've added to the bounds checks for the effected
`tokio::sync` types to ensure that returned futures continue to
implement `Send + Sync` in the future.
2020-04-03 15:45:29 -07:00
nasa
6fa40b6e20
doc: Fix readme link (#2370) 2020-04-03 09:00:18 -04:00
Alice Ryhl
e10471dc3a
io: Add StreamReader (#2052)
Allow conversion from a stream of chunks of bytes to an `AsyncRead`.
2020-04-02 14:18:52 -07:00
Alice Ryhl
0245515e4d
examples: add comment about dependency gotcha (#2355) 2020-04-02 23:16:00 +02:00
MOZGIII
03cb3b6ca1
Expose time::deplay_queue::Expired::deadline (#2300)
* Expose time::deplay_queue::Expired::deadline

* Return by value
2020-04-02 17:11:17 -04:00
Kevin Leimkuhler
3eaa1885c3
fs: Copy file permissions (#2354)
Signed-off-by: Kevin Leimkuhler <kevin@kleimkuhler.com>
2020-04-02 17:10:44 -04:00
Benjamin Halsted
cf4cbc142b
test: Added read_error() and write_error() (#2337)
Enable testing of edge cases caused by io errors.
2020-04-02 17:10:12 -04:00
Benjamin Halsted
215d7d4c5f
util: documentation example for LengthDelimitedCodec (#2339)
There is a gap in examples for Builder::num_skip() that shows how to
move past unused bytes between the length and payload.
2020-04-02 17:09:56 -04:00
Lucio Franco
2a8d917d2c
chore: Prepare 0.2.15 release (#2365)
Signed-off-by: Lucio Franco <luciofranco14@gmail.com>
tokio-0.2.15
2020-04-02 12:40:04 -04:00
Jon Gjengset
7fb1698e8d
sync: Add disarm to mpsc::Sender (#2358)
Fixes #898.
2020-04-02 11:27:37 -04:00
Carl Lerche
fa4fe9ef6f
rt: fix queue regression (#2362)
The new queue uses `u8` to track offsets. Cursors are expected to wrap.
An operation was performed with `+` instead of `wrapping_add`. This was
not _obviously_ issue before as it is difficult to wrap a `usize` on
64bit platforms, but wrapping a `u8` is trivial.

The fix is to use `wrapping_add` instead of `+`. A new test is added
that catches the issue.

Fixes #2361
2020-04-02 07:52:02 -07:00
Carl Lerche
f01136b5c0
chore: prepare tokio v0.2.14 release (#2356) tokio-0.2.14 2020-04-01 13:54:11 -07:00
Carl Lerche
caa7e180e4
rt: cap fifo scheduler slot to avoid starvation (#2349)
The work-stealing scheduler includes an optimization where each worker
includes a single slot to store the **last** scheduled task. Tasks in
scheduler's LIFO slot are executed next. This speeds up and reduces
latency with message passing patterns.

Previously, this optimization was susceptible to starving other tasks in
certain cases. If two tasks ping-ping between each other without ever
yielding, the worker would never execute other tasks.

An early PR (#2160) introduced a form of pre-emption. Each task is
allocated a per-poll operation budget. Tokio resources will return ready
until the budget is depleted, at which point, Tokio resources will
always return `Pending`.

This patch leverages the operation budget to limit the LIFO scheduler
optimization. When executing tasks from the LIFO slot, the budget is
**not** reset. Once the budget goes to zero, the task in the LIFO slot
is pushed to the back of the queue.
2020-03-28 13:55:12 -07:00
Alice Ryhl
7b2438e744
sync: fix notified link (#2351) 2020-03-28 13:20:51 -07:00
Eliza Weisman
00725f6876
sync: fix possible dangling pointer in semaphore (#2340)
## Motivation

When cancelling futures which are waiting to acquire semaphore permits,
there is a possible dangling pointer if notified futures are dropped
after the notified wakers have been split into a separate list. Because
these futures' wait queue nodes are no longer in the main list guarded
by the lock, their `Drop` impls will complete immediately, and they may
be dropped while still in the list of tasks to notify.

## Solution

This branch fixes this by popping from the wait list inside the lock.
The wakers of popped nodes are temporarily stored in a stack array,
so that they can be notified after the lock is released. Since the
size of the stack array is fixed, we may in some cases have to loop
multiple times, acquiring and releasing the lock, until all permits
have been released. This may also have the possible side advantage of
preventing a thread releasing a very large number of permits from
starving other threads that need to enqueue waiters.

I've also added a loom test that can reliably reproduce a segfault
on master, but passes on this branch (after a lot of iterations).

Signed-off-by: Eliza Weisman <eliza@buoyant.io>
2020-03-27 16:14:07 -07:00
kalcutter
5c71268bb8
sync: broadcast, revert "Keep lock until sender notified" (#2348)
This reverts commit 826fc21abfd04779cde92e4cc33de2adb42cf327.

The code was intentional. Holding the lock while notifying is
unnecessary. Also change the code to use `drop` so clippy doesn't
confuse people against their will.
2020-03-27 14:22:16 -07:00
Carl Lerche
8020b02bd0
fs: add coop test (#2344) 2020-03-26 22:17:56 -07:00
Carl Lerche
11acfbbea4
rt: add task join coop test (#2345)
Add test verifying that joining on a task consumes the caller's budget.
2020-03-26 22:17:48 -07:00
Carl Lerche
f2005a78ca
timer: fix loom test (#2346)
Fixes a test from a PR that was written before the recent loom upgrade.
A change in the details how loom executes models resulted in the test to
start failing. The fix is to reduce the number of iterations performed
by the test.
2020-03-26 15:23:33 -07:00
Brian L. Troutwine
3fb213a861
timer: improve memory ordering in Inner's increment (#2107)
This commit improves the memory ordering in the implementation of
Inner's increment function. The former code did a sequentially
consistent load of self.num, then entered a loop with a sequentially
consistent compare and swap on the same, bailing out with and Err only
if the loaded value was MAX_TIMEOUTS. The use of SeqCst means that all
threads must observe all relevant memory operations in the same order,
implying synchronization between all CPUs.

This commit adjusts the implementation in two key ways. First, the
initial load of self.num is now down with Relaxed ordering. If two
threads entered this code simultaneously, formerly, tokio required
that one proceed before the other, negating their parallelism. Now,
either thread may proceed without coordination. Second, the SeqCst
compare_and_swap is changed to a Release, Relaxed
compare_exchange_weak. The first memory ordering referrs to success:
if the value is swapped the load of that value for comparison will be
Relaxed and the store will be Release. The second memory ordering
referrs to failure: if the value is not swapped the load is
Relaxed. The _weak variant may spuriously fail but will generate
better code.

These changes mean that it is possible for more loops to be taken per
call than strictly necessary but with greater parallelism available on
this operation, improved energy consumption as CPUs don't have to
coordinate as much.
2020-03-26 13:04:08 -07:00
Christofer Nolander
6cf1a5b6b8
time: fix DelayQueue rewriting delay on insert after Poll::Ready (#2285)
When the queue was polled and yielded an index from the wheel, the delay
until the next item was never updated. As a result, when one item was
yielded from `poll_idx` the following insert erronously updated the
delay to the instant of the inserted item.

Fixes: #1700
2020-03-26 12:54:56 -07:00
Carl Lerche
1cb1e291c1
rt: track loom changes + tweak queue (#2315)
Loom is having a big refresh to improve performance and tighten up the
concurrency model. This diff tracks those changes.

Included in the changes is the removal of `CausalCell` deferred checks.
This is due to it technically being undefined behavior in the C++11
memory model. To address this, the work-stealing queue is updated to
avoid needing this behavior. This is done by limiting the queue to have
one concurrent stealer.
2020-03-26 12:23:12 -07:00
Carl Lerche
186196b911
stream: iter() should yield every so often. (#2343) 2020-03-25 14:56:24 -07:00
Tudor Sidea
57ba37c978
time: fix repeated pause/resume of time (#2253)
The resume function was breaking the guarantee that Instants should
never be less than any previously measured Instants when created.

Altered the pause and resume function such that they will not break this
guarantee. After resume, the time should continue from where it left
off.

Created test to prove that the advanced function still works as
expected.

Added additional tests for the pause/advance/resume functions.
2020-03-23 22:20:07 -07:00
Eliza Weisman
acf8a7da7a
sync: new internal semaphore based on intrusive lists (#2325)
## Motivation

Many of Tokio's synchronization primitives (`RwLock`, `Mutex`,
`Semaphore`, and the bounded MPSC channel) are based on the internal
semaphore implementation, called `semaphore_ll`. This semaphore type
provides a lower-level internal API for the semaphore implementation
than the public `Semaphore` type, and supports "batch" operations, where
waiters may acquire more than one permit at a time, and batches of
permits may be released back to the semaphore.

Currently, `semaphore_ll` uses an atomic singly-linked list for the
waiter queue. The linked list implementation is specific to the
semaphore. This implementation therefore requires a heap allocation for
every waiter in the queue. These allocations are owned by the semaphore,
rather than by the task awaiting permits from the semaphore. Critically,
they are only _deallocated_ when permits are released back to the
semaphore, at which point it dequeues as many waiters from the front of
the queue as can be satisfied with the released permits. If a task
attempts to acquire permits from the semaphore and is cancelled (such as
by timing out), their waiter nodes remain in the list until they are
dequeued while releasing permits. In cases where large numbers of tasks
are cancelled while waiting for permits, this results in extremely high
memory use for the semaphore (see #2237).

## Solution

@Matthias247 has proposed that Tokio adopt the approach used in his
`futures-intrusive` crate: using an _intrusive_ linked list to store the
wakers of tasks waiting on a synchronization primitive. In an intrusive
list, each list node is stored as part of the entry that node
represents, rather than in a heap allocation that owns the entry.
Because futures must be pinned in order to be polled, the necessary
invariant of such a list --- that entries may not move while in the list
--- may be upheld by making the waiter node `!Unpin`. In this approach,
the waiter node can be stored inline in the future, rather than
requiring  separate heap allocation, and cancelled futures may remove
their nodes from the list.

This branch adds a new semaphore implementation that uses the intrusive
list added to Tokio in #2210. The implementation is essentially a hybrid
of the old `semaphore_ll` and the semaphore used in `futures-intrusive`:
while a `Mutex` around the wait list is necessary, since the intrusive
list is not thread-safe, the permit state is stored outside of the mutex
and updated atomically. 

The mutex is acquired only when accessing the wait list — if a task 
can acquire sufficient permits without waiting, it does not need to
acquire the lock. When releasing permits, we iterate over the wait
list from the end of the queue until we run out of permits to release,
and split off all the nodes that received enough permits to wake up
into a separate list. Then, we can drain the new list and notify those
wakers *after* releasing the lock. Because the split operation only
modifies the pointers on the head node of the split-off list and the
new tail node of the old list, it is O(1) and does not require an
allocation to return a variable length number of waiters to notify.


Because of the intrusive list invariants, the API provided by the new
`batch_semaphore` is somewhat different than that of `semaphore_ll`. In
particular, the `Permit` type has been removed. This type was primarily
intended allow the reuse of a wait list node allocated on the heap.
Since the intrusive list means we can avoid heap-allocating waiters,
this is no longer necessary. Instead, acquiring permits is done by
polling an `Acquire` future returned by the `Semaphore` type. The use of
a future here ensures that the waiter node is always pinned while
waiting to acquire permits, and that a reference to the semaphore is
available to remove the waiter if the future is cancelled.
Unfortunately, the current implementation of the bounded MPSC requires a
`poll_acquire` operation, and has methods that call it while outside of
a pinned context. Therefore, I've left the old `semaphore_ll`
implementation in place to be used by the bounded MPSC, and updated the
`Mutex`, `RwLock`, and `Semaphore` APIs to use the new implementation.
Hopefully, a subsequent change can update the bounded MPSC to use the
new semaphore as well.

Fixes #2237

Signed-off-by: Eliza Weisman <eliza@buoyant.io>
2020-03-23 13:45:48 -07:00
MarinPostma
2258de5147
io: impl as RawFd / AsRawHandle for stdio (#2335)
Fixes: #2311
2020-03-22 22:25:49 -07:00
Carl Lerche
dd27f1a259
rt: remove unsafe from shell runtime. (#2333)
Since the original shell runtime was implemented, utilities have been
added to encapsulate `unsafe`. The shell runtime is now able to use
those utilities and not include its own `unsafe` code.
2020-03-20 21:06:50 -07:00
Nikhil Benesch
5fd1b8f67c
util: Prepare 0.3.1 release (#2330) 2020-03-18 20:05:55 -04:00
Nikhil Benesch
9e58b37ad5
tokio-util: fix minimum supported version of tokio (#2326)
tokio-util uses tokio::stream::StreamExt, which was not introduced until
tokio v0.2.5. The current dependency specification is incorrect, and
breaks with cargo update -Z minimal-versions.
2020-03-18 18:18:53 -04:00
Daniel Müller
c3b830110a
sync: Add RwLock::into_inner method (#2321)
Add RwLock::into_inner method that consumes the lock and returns
the wrapped value.

Fixes: #2320
2020-03-18 11:52:11 -07:00
Alice Ryhl
602ad2e0ba
runtime: update the documentation around Handle (#2328)
This PR was prompted by having encountered a few cases of people not noticing that Runtime::handle can be cloned, and therefore not realizing it could be moved to another thread.
2020-03-17 22:59:26 +01:00
Jon Gjengset
06a4d895ec
Add cooperative task yielding (#2160)
A single call to `poll` on a top-level task may potentially do a lot of
work before it returns `Poll::Pending`. If a task runs for a long period
of time without yielding back to the executor, it can starve other tasks
waiting on that executor to execute them, or drive underlying resources.
See for example rust-lang/futures-rs#2047, rust-lang/futures-rs#1957,
and rust-lang/futures-rs#869. Since Rust does not have a runtime, it is
difficult to forcibly preempt a long-running task.

Consider a future like this one:

```rust
use tokio::stream::StreamExt;
async fn drop_all<I: Stream>(input: I) {
    while let Some(_) = input.next().await {}
}
```

It may look harmless, but consider what happens under heavy load if the
input stream is _always_ ready. If we spawn `drop_all`, the task will
never yield, and will starve other tasks and resources on the same
executor.

This patch adds a `coop` module that provides an opt-in mechanism for
futures to cooperate with the executor to avoid starvation. This
alleviates the problem above:

```
use tokio::stream::StreamExt;
async fn drop_all<I: Stream>(input: I) {
    while let Some(_) = input.next().await {
        tokio::coop::proceed().await;
    }
}
```

The call to [`proceed`] will coordinate with the executor to make sure
that every so often control is yielded back to the executor so it can
run other tasks.

The implementation uses a thread-local counter that simply counts how
many "cooperation points" we have passed since the task was first
polled. Once the "budget" has been spent, any subsequent points will
return `Poll::Pending`, eventually making the top-level task yield. When
it finally does yield, the executor resets the budget before
running the next task.

The budget per task poll is currently hard-coded to 128. Eventually, we
may want to make it dynamic as more cooperation points are added. The
number 128 was chosen more or less arbitrarily to balance the cost of
yielding unnecessarily against the time an executor may be "held up".

At the moment, all the tokio leaf futures ("resources") call into coop,
but external futures have no way of doing so. We probably want to
continue limiting coop points to leaf futures in the future, but may
want to also enable third-party leaf futures to cooperate to benefit the
ecosystem as a whole. This is reflected in the methods marked as `pub`
in `mod coop` (even though the module is only `pub(crate)`). We will
likely also eventually want to expose `coop::limit`, which enables
sub-executors and manual `impl Future` blocks to avoid one sub-task
spending all of their poll budget.

Benchmarks (see tokio-rs/tokio#2160) suggest that the overhead of `coop`
is marginal.
2020-03-16 17:17:56 -04:00
Alice Ryhl
fce6845f2b
Document common cargo commands (#2293)
* Document common cargo commands
* Add loom command
2020-03-15 13:02:39 +01:00
th0114nd
826fc21abf
Keep lock until sender notified (#2302) 2020-03-08 20:46:19 -07:00