Skip to content
New issue

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

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

Already on GitHub? # to your account

RFC: Send+Sync on metal objects #40

Open
kvark opened this issue May 3, 2018 · 7 comments
Open

RFC: Send+Sync on metal objects #40

kvark opened this issue May 3, 2018 · 7 comments

Comments

@kvark
Copy link
Member

kvark commented May 3, 2018

Given that all the interaction is done via message sending, I don't see why Send+Sync wouldn't be the case?

@kvark
Copy link
Member Author

kvark commented May 10, 2018

Proposal

  1. Have foreign_obj_type forcefully implement Send + Sync
  2. Mark all the methods (non-static, corresponding to ObjC messages) with &mut self
  3. Mark atomic property get/set accessors with &self
  4. Mark non-atomic properties with &mut self.

Clarification

Atomicity of properties in ObjC guarantees no visible partial writes. While Apple docs say this is not thread safe, they mean data-races in fact, and it's perfectly thread-safe in Rust terms (of memory safety).

@kvark
Copy link
Member Author

kvark commented May 10, 2018

@gfx-rs/metallists
Comments? Questions? Objections?
This is an important thing for us to decide.

@kvark
Copy link
Member Author

kvark commented May 10, 2018

Also pinging @SSheldon, the author of objc bindings in Rust

@kvark
Copy link
Member Author

kvark commented May 10, 2018

Sorry, I realized why this isn't going to work 😞 . &mut self means nothing if we are able to have multiple independent rust objects corresponding to the same ObjC object. There has to be something our Rust objects share between each other, e.g. all being Arc<RwLock<ObjcClassRef>> but with Arc replaced by something that uses native ObjC runtime counters.

@kvark
Copy link
Member Author

kvark commented May 11, 2018

Current approach

A bit of context here, that's what we currently have for ObjC bindings of Metal:

  • a SomeClassRef type with actual methods (immutable!) for properties and ObjC messages. It's a type-system thing in Rust that doesn't affect any ObjC reference counts. Type system guarantees that the object is alive for the lifetime of our XXXRef struct.
  • a SomeClass type that represent a strong reference to ObjC object. Cloning it is akin cloning an Arc. One can borrow it and get SomeClassRef temporarily.

Analysis

The main problem for getting any sort of type assistance here is that SomeClass objects don't share anything with each other, so we don't know (even at run-time) if those point to the same underlying ObjC object...

So here comes the main idea and restriction: let's enforce a guarantee that there is a single Rust object backing a single ObjC object. On Rust side, there is no point to mess with ObjC reference counters. Instead, we can use the regular Arc and locking primitives. As long as ObjC runtime is concerned, we only have one object.

Unresolved Problems

Any methods that return new objects to use (newXXX) would just return SomeClass by value, and the client code would then be responsible for wrapping it into sharing structures, if needed. The destructor of SomeClass would then release the only ObjC count.

What's not clear, however, is what should be done about getters that return existing objects. e.g.

let obj1 = msg_send![parent.get_some_object];
let obj2 = msg_send![parent.get_some_object];

@kvark
Copy link
Member Author

kvark commented May 11, 2018

An important missing piece of this puzzle is to how we can uniquely track ObjC objects, and @jrmuizel suggested to put the locking internals into the associated data for fast lookups (by our wrappers around ObjC objects, e.g. struct Device {...}).

@SSheldon
Copy link
Contributor

Having objects be uniquely owned by a SomeClass in rust would allow you to take the most advantage of rust's type system; I tried something a little like this with UIKit, but really struggled with ensuring that uniqueness. I haven't worked with Metal, maybe it's better suited? In UIKit, it seems like everything has a reference to everything... 😛

I like the idea of using associated types, that could make it a lot easier to verify that the uniqueness isn't being violated and could make this all much more doable.

# for free to join this conversation on GitHub. Already have an account? # to comment
Projects
None yet
Development

No branches or pull requests

2 participants