Conversation
|
Probably opened in a hurry to compare, but do note (in the description) that this seems to be an alternative approach to #206 (is sort-of a duplicate)? |
|
This is meant to be an implementation of "outer reference counting", as opposed to #206, which is inner reference counting. |
144f938 to
ff925be
Compare
|
I feel like we've overcome the hard part in #188, deciding on the semantics (Reference-Counted Control), now it's "just" the syntax. Something that I feel we need to at least consider here is: What is the value of I imagine the answer to be "it allows the user to implement the reference-counting in a different manner" (including in C probably), i.e. we're not tied to The downsides as I see from that is mainly that you cannot express The natural question then becomes: Are the benefits worth it compared to the downsides? |
src/owned.rs
Outdated
| /// This window handle is guaranteed to be `Send` and `Sync`. Meaning, its | ||
| /// internal mechaisms for refcounting are thread-safe. | ||
| #[derive(Debug, Clone)] | ||
| pub struct SyncWindowHandle { |
There was a problem hiding this comment.
After todays meeting we need to flip this.
There was a problem hiding this comment.
Actually, after rethinking this, one problem that this poses is that some backends are not Send + Sync, e.g. Web. So maybe the default should be !Send + !Sync after all?
I believe in today meeting we were wrongly assuming that the WindowHandle is just a counter, but that's obviously not true. It still has to contain some state that is able to produce the BorrowedWindowHandle/RawWindowHandle.
There was a problem hiding this comment.
I've removed SyncWindowHandle and made WindowHandle Send + Sync. We can have further discussion on if we want a thread-unsafe handle.
There was a problem hiding this comment.
The thread-unsafe handle is required. Web is unable to create a WindowHandle at all otherwise.
I believe the downsides are nullified/minimized in that we provide very convenient conversions in RWH. If there are other common cases out there we should consider adding conversion methods in RWH to cover them. So in my eyes the current implementation retains maximum flexibility while at the same time keeping real-life scenarios as convenient as possible. |
|
If C interop is the main motivator, then I think that can be solved with a custom I think the main difference is if we actually expose the owned handle as the return type anywhere in our API, which I think I'm somewhat proposing in #200 - then whatever handle we use there kinda has to be the maximally flexible one (or a generic?). (To be clear, I'm in favour of a separate |
ff925be to
2bfe01e
Compare
Renames the borrowed handle types to make more sense post-#188. - WindowHandle -> BorrowedWindowHandle - DisplayHandle -> BorrowedDisplayHandle - HasWindowHandle -> AsWindowHandle - HasDisplayHandle -> AsDisplayHandle My opinion is that these types still have relevance in a post-#188 world. For example, in cases where you don't require a persistent object, you could have an `fn(&impl AsWindowHandle)`. This would allow using window handles without incrementing refcounts. Signed-off-by: John Nunley <dev@notgull.net>
0add791 to
1cd8bd3
Compare
This adds "WindowHandle" and "DisplayHandle" types as discussed in #188. These act similar to `Waker`'s in stdlib, as they are a wrapper around a trait object. Signed-off-by: John Nunley <dev@notgull.net>
This adds two ways to construct owned handles: - Using an `&'static impl AsWindowHandle`. This is simple because `retain` and `release` can be implemented as no-ops. This exists to make the case of a singleton no-op display simpler. Each handle provides a `WindowHandle::unavailable()` function to demonstrate this in action. - Using a reference counted container. `WindowHandle` allows `Arc<T>`. This allows window handles to be constructed from ref-counted containers quite easily. Both of these strategies allow for window handles building on existing implementations to be implemented in entirely safe code. Signed-off-by: John Nunley <dev@notgull.net>
1cd8bd3 to
4b36004
Compare
The VTable gives you more flexibility over how the underlying pointer acts. For example, see the |
| assert_impl_all!(WindowHandle: Send, Sync); | ||
| assert_impl_all!(DisplayHandle: Send, Sync); | ||
| assert_impl_all!(WindowVtable: Send, Sync); | ||
| assert_impl_all!(DisplayVtable: Send, Sync); |
There was a problem hiding this comment.
Check for UnwindSafe + RefUnwindSafe + Unpin as well?
Or them not having it, the important part is that its cross-platform consistent.
| /// - The window handle returned by `get` must be valid for the lifetime of | ||
| /// this window handle. |
There was a problem hiding this comment.
| /// - The window handle returned by `get` must be valid for the lifetime of | |
| /// this window handle. | |
| /// - The window handle returned by `window_handle()` must be valid for the lifetime of | |
| /// this window handle. |
| /// will be called `N+1` times. The underlying window must not be destroyed | ||
| /// as long as this reference is alive. |
There was a problem hiding this comment.
We have this part twice, once under # Safety and one more time here. I'm in favor of removing it from # Safety, as that should not be unsound (AFAIU).
Probably should be in its own paragraph here.
src/owned.rs
Outdated
| /// This window handle is guaranteed to be `Send` and `Sync`. Meaning, its | ||
| /// internal mechaisms for refcounting are thread-safe. | ||
| #[derive(Debug, Clone)] | ||
| pub struct SyncWindowHandle { |
There was a problem hiding this comment.
The thread-unsafe handle is required. Web is unable to create a WindowHandle at all otherwise.
| BorrowedWindowHandle::borrow_raw(handle) | ||
| }) | ||
| } | ||
| } |
There was a problem hiding this comment.
I'm not 100% sure from reading this - but are you sure that the returned BorrowedWindowHandle actually borrows safely from the &self in a way that blocks the original handle from being dropped?
I have a nagging feeling that if you happen to have a &'static self (easily achieved with a Box or Arc around the owned::WindowHandle) then you will get back a BorrowedWindowHandle<'static> and you will have no constraints on being able to store that statically too but then you could Drop the original window handle and then the BorrowedWindowHandle could hold an invalid pointer.
I might be misreading this, but I've certainly been bitten by similar looking mistakes in the past so my spider senses are tingling here.
I feel like the &self lifetime should be named explicitly and there should be some PhantomData in the BorrowedWindowHandle to hold that lifetime - or something like that.
Fixes #188