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: Bring the library up to date #12900

Closed
wants to merge 11 commits into from

Conversation

alexcrichton
Copy link
Member

  • Remove clone-ability from all primitives. All shared state will now come
    from the usage of the primitives being shared, not the primitives being
    inherently shareable. This allows for fewer allocations for stack-allocated
    primitives.
  • Add Mutex<T> and RWLock<T> which are stack-allocated primitives for purely
    wrapping a piece of data
  • Remove RWArc<T> in favor of Arc<RWLock<T>>
  • Remove MutexArc<T> in favor of Arc<Mutex<T>>
  • Shuffle around where things are located
    • The arc module now only contains Arc
    • A new lock module contains Mutex, RWLock, and Barrier
    • A new raw module contains the primitive implementations of Semaphore,
      Mutex, and RWLock
  • The Deref/DerefMut trait was implemented where appropriate
  • CowArc was removed, the functionality is now part of Arc and is tagged
    with #[experimental].
  • The crate now has #[deny(missing_doc)]
  • Arc now supports weak pointers

This is not a large-scale rewrite of the functionality contained within the
sync crate, but rather a shuffling of who does what an a thinner hierarchy of
ownership to allow for better composability.

@huonw
Copy link
Member

huonw commented Mar 15, 2014

Travis has legitimate tidy failures.

(BTW, github was eating the type parameters in your description as HTML; I surrounded them with `'s, which seems to have fixed it.)

#[inline]
#[experimental]
pub fn get_mut<'a>(&'a mut self) -> &'a mut T {
Copy link
Member

Choose a reason for hiding this comment

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

It'd be nice if this method name emphasized that it's a COW operation.

Copy link
Contributor

Choose a reason for hiding this comment

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

Agreed.

@alexcrichton
Copy link
Member Author

A semantic difference that fell out as part of this rewrite is that you can nest rwlocks now. We're moving in the direction of not trying to prevent deadlock, so I think that this is fine.

@@ -484,7 +484,7 @@ fn test() {

let db_path = make_path(~"db.json");

let cx = Context::new(RWArc::new(Database::new(db_path)),
let cx = Context::new(Arc::new(RWLock::new(Database::new(db_path))),
Copy link
Member

Choose a reason for hiding this comment

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

I'm surprised that this is valid: shouldn't RWLock be not-Freeze? (I guess this is mostly irrelevant with Freeze disappearing, though.)

Copy link
Member Author

Choose a reason for hiding this comment

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

I believe that the Freeze bound was mostly for non-recursive locks, but we've basically stopped doing that now, and this explicitly wanted them to be Freeze so they could go in arcs.

The name Share is much more appropriate, and the usage mostly reflects what things will look like for the Freeze => Share transition.

Copy link
Member

Choose a reason for hiding this comment

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

My point is RWLock shouldn't be Freeze, aiui, since it has inner mutability (right?)... but it is Share so this isn't worth worrying about.

@bill-myers
Copy link
Contributor

Awesome, finally the API gets in a mostly sensible shape.

Only thing that seems really objectionable is putting "condvar" inside MutexGuard, since most mutexes won't need condvars, and tying them is really inflexible (e.g. can't put them in a HashMap<~str, Condvar> but only a static array inside the mutex itself).

I think condvars need to be split from mutexes, take a guard parameter, and check at runtime that the guard is from the correct lock.

Also, naming seems debatable: maybe Mutex and RWLock should be renamed to something like SyncCell and RwSyncCell or perhaps just Sync and RwSync?

The current naming scheme in this pull request is akin to calling RefCell BorrowFlags instead.

/// signaling, for use with the lock types.
pub struct Condvar<'a> {
priv name: &'static str,
// n.b. Inner must be after PoisonOnFail becase we must set the poison flag
Copy link
Contributor

Choose a reason for hiding this comment

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

because*

@alexcrichton
Copy link
Member Author

I think condvars need to be split from mutexes, take a guard parameter, and check at runtime that the guard is from the correct lock.

This PR is aimed at a refactoring to get things into shape, I agree that condvars need to be revisited, but I'm going to do that as a separate PR.

@alexcrichton
Copy link
Member Author

Added weak pointers for Arc, removed get functions, and renamed get_mut to make_unique

/// # Example
///
/// In this example, a large vector of floats is shared between several tasks.
/// With simple pipes, without Arc, a copy would have to be made for each task.
Copy link
Member

Choose a reason for hiding this comment

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

Arc

lock: mutex::Mutex,
// n.b, we need Sem to be `Freeze` (soon to be `Share`), but the WaitQueue
Copy link
Member

Choose a reason for hiding this comment

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

Share exists now

@huonw
Copy link
Member

huonw commented Mar 22, 2014

Ok, read over pretty much the whole thing; although it would be (very) good for someone else to check the use of the various atomics and consistencies etc.

There are several undefined behaviour &self -> &mut self transmutes blocked on #11583, I think it would be very good for this to wait until that's fixed (i.e. #13036 lands) to avoid introducing UB.

@huonw
Copy link
Member

huonw commented Mar 22, 2014

(Also, it would be really neat if sync could get a #[deny(deprecated_owned_vector)] with these changes...)

@alexcrichton
Copy link
Member Author

Thanks for the thorough review @huonw! I am quite eager to remove the transmutes blocked on #11583!

@huonw
Copy link
Member

huonw commented Mar 22, 2014

(Travis has relevant failures.)

@alexcrichton
Copy link
Member Author

Updated with #13069 plus lots of migration from &mut self to &self

@alexcrichton
Copy link
Member Author

A snapshot is being built which I hope to include in this PR to cut down on the cfg(stage0)

@alexcrichton
Copy link
Member Author

Updated with new snapshots so there is no longer any cfg(stage0)

The proper usage of shared types is now sharing through `&self` rather than
`&mut self` because the mutable version will provide stronger guarantees (no
aliasing on *any* thread).
This commit also lifts it up a level in the module hierarchy in the soon-to-come
reorganization of libsync.
This also uses the Unsafe type for any interior mutability in the type to avoid
transmutes.
Similarly to the rest of the previous commits, this moves the once primitive to
using &self instead of &mut self for proper sharing among many threads now.
This commit rewrites the core primitives of the sync library: Mutex, RWLock, and
Semaphore. These primitives now have updated, more modernized apis:

* Guards are returned instead of locking with closures. All condition variables
  have moved inside the guards and extraneous methods have been removed.
* Downgrading on an rwlock is now done through the guard instead of the rwlock
  itself.

These types are meant to be general locks, not locks of an internal type (for
external usage). New types will be introduced for locking shared data.
This introduces new synchronization types which are meant to be the foundational
building blocks for sharing data among tasks. The new Mutex and RWLock types
have a type parameter which is the internal data that is accessed. Access to the
data is all performed through the guards returned, and the guards all have
autoderef implemented for easy access.
alexcrichton and others added 4 commits March 24, 2014 17:17
This removes the now-outdated MutexArc and RWArc types. These are superseded by
Arc<Mutex<T>> and Arc<RWLock<T>>. The only remaining arc is the one true Arc.
Additionally, the arc now has weak pointers implemented for it to assist in
breaking cycles.

This commit brings the arc api up to parity with the sibling Rc api, making them
nearly interchangeable for inter and intra task communication.
This updates the exports and layout of the crate
bors added a commit that referenced this pull request Mar 25, 2014
* Remove clone-ability from all primitives. All shared state will now come
  from the usage of the primitives being shared, not the primitives being
  inherently shareable. This allows for fewer allocations for stack-allocated
  primitives.
* Add `Mutex<T>` and `RWLock<T>` which are stack-allocated primitives for purely
  wrapping a piece of data
* Remove `RWArc<T>` in favor of `Arc<RWLock<T>>`
* Remove `MutexArc<T>` in favor of `Arc<Mutex<T>>`
* Shuffle around where things are located
  * The `arc` module now only contains `Arc`
  * A new `lock` module contains `Mutex`, `RWLock`, and `Barrier`
  * A new `raw` module contains the primitive implementations of `Semaphore`,
    `Mutex`, and `RWLock`
* The Deref/DerefMut trait was implemented where appropriate
* `CowArc` was removed, the functionality is now part of `Arc` and is tagged
  with `#[experimental]`.
* The crate now has #[deny(missing_doc)]
* `Arc` now supports weak pointers

This is not a large-scale rewrite of the functionality contained within the
`sync` crate, but rather a shuffling of who does what an a thinner hierarchy of
ownership to allow for better composability.
@bors bors closed this Mar 25, 2014
@alexcrichton alexcrichton deleted the rewrite-sync branch March 25, 2014 17:07
matthiaskrgr pushed a commit to matthiaskrgr/rust that referenced this pull request Aug 2, 2022
publish: Use cargo ws rename to rename crates

Follow up for rust-lang#12716
flip1995 pushed a commit to flip1995/rust that referenced this pull request Jun 13, 2024
Remove `lazy_static` mention

I planned to replace any mention with `LazyLock` but I think `thread_local` is more appropriate here - `const`s that aren't `Sync` wouldn't be able to go in a `lazy_static`/`static LazyLock` either

Also removed a test file that was mostly commented out so wasn't testing anything

changelog: none
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants