Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

sync: ensure Mutex, RwLock, and Semaphore futures are Send + Sync #2375

Merged
merged 5 commits into from
Apr 3, 2020

Conversation

hawkw
Copy link
Member

@hawkw hawkw commented Apr 3, 2020

Motivation

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.

Solution

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.

Fixes: #2373

Signed-off-by: Eliza Weisman eliza@buoyant.io

hawkw added 2 commits April 3, 2020 12:22
Signed-off-by: Eliza Weisman <eliza@buoyant.io>
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.

Signed-off-by: Eliza Weisman <eliza@buoyant.io>
@hawkw hawkw added the C-bug Category: This is a bug. label Apr 3, 2020
@hawkw hawkw self-assigned this Apr 3, 2020
Copy link
Member

@LucioFranco LucioFranco left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this need a bump release? if so we should prepare that along side this and we can get it out asap

Signed-off-by: Eliza Weisman <eliza@buoyant.io>
@hawkw
Copy link
Member Author

hawkw commented Apr 3, 2020

Does this need a bump release? if so we should prepare that along side this and we can get it out asap

I think we probably should do a version bump — @carllerche, what do you think?

I think that should be staged in a separate PR though.

@LucioFranco
Copy link
Member

@hawkw cool, if you can open a bump Pr I can do the rest.

@carllerche
Copy link
Member

We should push a patch release. You can include the version bump / changelog here too.

Signed-off-by: Eliza Weisman <eliza@buoyant.io>
@hawkw
Copy link
Member Author

hawkw commented Apr 3, 2020

@carllerche okay, added the version bump in 89fcffb

Copy link
Member

@carllerche carllerche left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's try to move forwards in time and not backwards 😆

tokio/Cargo.toml Outdated Show resolved Hide resolved
tokio/src/lib.rs Outdated Show resolved Hide resolved
whoops, thanks carl!

Co-Authored-By: Carl Lerche <me@carllerche.com>
@hawkw
Copy link
Member Author

hawkw commented Apr 3, 2020

Whoops, thanks for catching my typo @carllerche! +1 for obeying time's arrow :)

@carllerche
Copy link
Member

It would be nice if azure windows CI stopped randomly not reporting back....

@hawkw
Copy link
Member Author

hawkw commented Apr 3, 2020

@carllerche looks like it's good now?

@carllerche carllerche merged commit 1121a8e into master Apr 3, 2020
hawkw added a commit that referenced this pull request Apr 4, 2020
# 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>
@carllerche carllerche deleted the eliza/semaphore-sync branch April 15, 2020 20:38
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
C-bug Category: This is a bug.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Semaphore::acquire returned Future lost its Sync
3 participants