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

Make auto-release pools visible #225

Open
kvark opened this issue Dec 19, 2021 · 1 comment
Open

Make auto-release pools visible #225

kvark opened this issue Dec 19, 2021 · 1 comment

Comments

@kvark
Copy link
Member

kvark commented Dec 19, 2021

Inspired by #224
All methods that return auto-referenced objects have this common property: they assume ARP alive, and they could return a reference with a lifetime not greater than that ARP. This can be directly expressed with the type system instead of being implicit:

let bar = {
  let arp = metal::AutoReleasePool::new();
  let foo = device.create_foo(&arp);
  foo.to_owned()
};

Notice how ARP becomes a regular object with RAII instead of being closure-based.
Why this is cool?

  1. ARP is explicitly used, therefore no need to fight Rust "unused variable" warnings that often occur with similar RAII APIs
  2. metal-rs clearly expresses the dependency on ARP, there is no assumption taking place
  3. everything is forcefully safe, since returned references live no longer than the ARP
  4. metal-rs is zero overhead, since it doesn't do "retain" just to be able to return an owned object
@madsmtm
Copy link
Contributor

madsmtm commented Dec 19, 2021

Also partly discussed in #222.

Quick notes: The following two examples would be UB:

let bar = {
  let outer = metal::AutoReleasePool::new();
  let foo = {
    let inner = metal::AutoReleasePool::new();
    // Released with inner pool, but lifetime is bound to the outer pool
    device.create_foo(&outer)
  };
  foo.to_owned()
};
let a = metal::AutoReleasePool::new();
let b = metal::AutoReleasePool::new();
// Drop order is required to be the inverse of creation (drop b first, then a)
drop(a);
drop(b);

So I don't think you could make a safe (zero-cost) API using just RAII, although your proposal would be substantially better than the status-quo!

I've been working on this idea as well, see related issues in objc: SSheldon/rust-objc#103 and SSheldon/rust-objc#95.

Another reference is in my fork, the current implementation (uses closures + thread locals in debug mode and auto traits on nightly) and an example usage (complicated by -[NSString UTF8String] being weirder than most).

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

No branches or pull requests

2 participants