Skip to content

Oibit send and friends #20119

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

Merged
merged 16 commits into from
Dec 27, 2014
Merged

Oibit send and friends #20119

merged 16 commits into from
Dec 27, 2014

Conversation

flaper87
Copy link
Contributor

More work on opt-in built in traits. Send and Sync are not opt-in, OwnedPtr renamed to UniquePtr and the Send and Sync traits are now unsafe.

NOTE: This likely needs to be rebased on top of the yet-to-land snapshot.

r? @nikomatsakis

[breaking-change]

cc #13231

@sfackler
Copy link
Member

Can we add a lint or something for "probably wrong" implementations of Sync or Send (i.e. implementations for types that wouldn't be Sync or Send today)? I'm a bit worried with the current setup that it'll be really easy to accidentally mess up and turn a previously safe object into an unsafe object by adding something that's not Sync or Send.

I'm also not really sure why RacyCell exists, unless we add that lint.

@sfackler
Copy link
Member

Er, I may have misremembered the OIBIT RFC. The plan is that Sync and Send will still automatically be implemented, you can override a missing impl with unsafe impl Foo and opt out with impl !Foo?


/// A version of `UnsafeCell` intended for use in concurrent data
/// structures (for example, you might put it in an `Arc`).
pub struct RacyCell<T>(pub UnsafeCell<T>);
Copy link
Member

Choose a reason for hiding this comment

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

This may not necessarily be a public-facing API that we're willing to commit to at this time, could this be moved into just the std::comm implementation?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yup. Actually, @nikomatsakis had asked me to do that already. I haven't done it yet because I didn't quite understand the need. Now I do, thanks for the comment :D

@alexcrichton
Copy link
Member

Awesome work! Can't wait for this to land!

@nikomatsakis
Copy link
Contributor

@sfackler Yes, your summary is basically an accurate depiction of the end goal. This RFC does not get all the way there, but it does a big chunk of the work. This RFC doesn't offer a means to explicitly opt out (beyond the marker types that already exist). However, it DOES require an unsafe, explicit opt in if your type contains unsafe pointers (or marker types, but that'd be kind of silly). In a follow-up RFC, we will also make it so that types containing UnsafeCell are not Send or Sync (or at least not Sync, I've been wondering about this) unless they opt in as well. At that point, the opt-in story will be complete. Hopefully we'll get to the explicit opt out (and user-defined .. traits) after that.

@flaper87 flaper87 force-pushed the oibit-send-and-friends branch 3 times, most recently from b6db832 to 60bb169 Compare December 22, 2014 13:43
@nikomatsakis
Copy link
Contributor

Hmm, so, I think RacyCell can't quite be confined to comm (or rather, we shouldn't bother doing so in this PR), but we should ensure it is not publicly exported from libstd. Otherwise r+ from me.

@flaper87
Copy link
Contributor Author

@nikomatsakis I believe Mutex and the other types could keep using UnsafeCell since they all implement Sycn. I had replaced UnsafeCell with RacyCell before implementing Sync manually on those types. 2s, brb with a new version ;)

@flaper87 flaper87 force-pushed the oibit-send-and-friends branch from b8e171d to 28b3496 Compare December 22, 2014 16:33
@nikomatsakis
Copy link
Contributor

This looks great! r+ modulo the "DOX" comments

@flaper87 flaper87 force-pushed the oibit-send-and-friends branch 7 times, most recently from 31d93c4 to 0b5bc5c Compare December 23, 2014 10:34
@nikomatsakis
Copy link
Contributor

Giving high priority because this is an important language change, and also somewhat conflict prone.

@flaper87 flaper87 force-pushed the oibit-send-and-friends branch 6 times, most recently from 1ba46e0 to 386f910 Compare December 23, 2014 16:24
@flaper87 flaper87 force-pushed the oibit-send-and-friends branch from 823830c to cb8e06b Compare December 25, 2014 17:48
@flaper87 flaper87 force-pushed the oibit-send-and-friends branch from cb8e06b to bb315f2 Compare December 26, 2014 16:31
@@ -59,7 +60,8 @@ fn deflate_bytes_internal(bytes: &[u8], flags: c_int) -> Option<CVec<u8>> {
&mut outsz,
flags);
if !res.is_null() {
Some(CVec::new_with_dtor(res as *mut u8, outsz as uint, move|:| libc::free(res)))
let res = Unique(res);
Some(CVec::new_with_dtor(res.0 as *mut u8, outsz as uint, move|:| libc::free(res.0)))
Copy link
Contributor

Choose a reason for hiding this comment

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

You cast it to a Unique and immediately cast it back?

@flaper87 flaper87 force-pushed the oibit-send-and-friends branch from ad5233b to 11f71ec Compare December 27, 2014 11:50
bors added a commit that referenced this pull request Dec 27, 2014
…tsakis

More work on opt-in built in traits. `Send` and `Sync` are not opt-in, `OwnedPtr` renamed to `UniquePtr` and the `Send` and `Sync` traits are now unsafe.

NOTE: This likely needs to be rebased on top of the yet-to-land snapshot.

r? @nikomatsakis 

cc #13231
@bors bors merged commit 1a73ccc into rust-lang:master Dec 27, 2014
@nikomatsakis
Copy link
Contributor

💯

@shadowmint
Copy link

This is a breaking change; please tag it as such.

Any ffi library that was previously using *c_void pointers to have Send wrappers around a c interface (eg. database handle) will be broken after this change.

@shadowmint
Copy link

To others who find this, the solution is to manually implement Send boilerplate on your type, as shown in the change log above:

unsafe impl<T: Send + Sync> Send for Foo<T> {}

@flaper87
Copy link
Contributor Author

@shadowmint note that it's not always required a Send + Sync bound on every implementation of Send. The bounds will depend on the type your implementing Send/Sync for.

As for the broken * pointers, there's a Unique struct that you can use to wrap them. Unique owns the reference to the wrapped value, therefore it's Send and Sync.

For example:

extern crate core;
extern crate libc;

use libc::c_int;
use core::ptr::Unique;

fn test_send<T:Send>(s: T) {}

fn main() {

    let x = Unique(0 as *mut libc::c_int);
    test_send(x);
    // test_send(0 as *mut libc::c_int); // this fails
}

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.

8 participants