-
Notifications
You must be signed in to change notification settings - Fork 12.8k
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
Conversation
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 { |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Agreed.
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))), |
There was a problem hiding this comment.
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.)
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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.
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 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
because*
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. |
Added weak pointers for |
/// # 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. |
There was a problem hiding this comment.
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 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Share
exists now
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 |
(Also, it would be really neat if |
(Travis has relevant failures.) |
Updated with #13069 plus lots of migration from |
A snapshot is being built which I hope to include in this PR to cut down on the |
Updated with new snapshots so there is no longer any |
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.
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
* 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.
publish: Use cargo ws rename to rename crates Follow up for rust-lang#12716
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
from the usage of the primitives being shared, not the primitives being
inherently shareable. This allows for fewer allocations for stack-allocated
primitives.
Mutex<T>
andRWLock<T>
which are stack-allocated primitives for purelywrapping a piece of data
RWArc<T>
in favor ofArc<RWLock<T>>
MutexArc<T>
in favor ofArc<Mutex<T>>
arc
module now only containsArc
lock
module containsMutex
,RWLock
, andBarrier
raw
module contains the primitive implementations ofSemaphore
,Mutex
, andRWLock
CowArc
was removed, the functionality is now part ofArc
and is taggedwith
#[experimental]
.Arc
now supports weak pointersThis 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 ofownership to allow for better composability.