Uh, so this might actually be a bug, arguably? But anyway. We looked into Arc and Pin and the API seems either completely pointless or severely lacking.
So to start you use
Arc::pin(foo). And you can
Pin::clone(...) the resulting
But as you start to dig into it, there's a lack of
Arc::pin_cyclic, there's a whole effectively unused weak counter in a
Pin<Arc<...>> because you can't
Pin<Arc<...>>, and it just in general feels like, if you ever reach for
Pin<Arc<...>>, you're actually using the wrong abstraction?
We have a lot of questions about all this. "If
Pin is about self-references, why would anyone use
Arc::new_cyclic?", "Why's there no
downgrade for these?", among others. These don't seem to be answered in any of the existing material. They're definitely not answered on the github, there's nothing that talks about
downgrade either on the issues or the pull requests. There's not enough rationale for using
Arc::pin anywhere in the docs. It seems that
Arc::pin exists purely because
Box::pin exists (unless we missed some (un)obvious pull request somewhere)!
What are we missing, if anything? If we're not missing anything... what does this all mean? These APIs are stable, so... now what?
In theory it would be perfectly logical to have a
Pin<Arc<Mutex<SomeFuture>>>. Or perhaps a
Pin<Arc<Mutex<SomeOtherStructure>>> for any structure that happens to use self-references in its implementation. In practice this doesn’t work, because
DerefMut but not
Deref, which is one of the reasons I believe
Pin should have been designed differently.
I had this topic recently in some discussion. AFAICT an alternative
Alternatively, Mutex could introduce some additional boolean inner state that, when you first call the
PinnableMutex that only supports
Pin<&PinnableMutex<T>> -> Pin<&mut T>, i. e. there's no
&self -> &mut T method, should be sound. Then
Pin<Arc<PinnableMutex<SomeFuture>>> is usable with existing APIs for
Pin<&Mutex<T>> -> Pin<&mut T> method, stores the information that it's now in "pinned mode" which prevents any successful future use of the
&Mutex<T> -> &mut T method (e.g. by having it returning an error or panicking).
That's just technically an alternative I could come up with, I don't claim it's a "good" API necessarily.
Right, it is missing API because you can't have a
I actually made a crate that have a PinWeak type, that fills this hole. The documentation explains it:
A new_cycle function could be added in the crate.
We wonder where exactly this went wrong? Where would we want to look to figure that out?
This is correct; if you don't expose the ability to get an unpinned mutable reference from a shared reference, the API works. I demonstrated the correct API using RefCell as a model, but the same principle applies to Mutex. GitHub - withoutboats/pin-cell: pin-safe interior mutability
Apparently no one needs to combine pinning with interior mutability in this way in practice, so the APIs have not developed in the ecosystem.
This was a trade off, like so many things: either don't allow getting a shared reference from a pinned reference, and now pinned references cannot call any methods that don't know about pin, even though the vast majority don't use interior mutability, or people who want pinned interior mutability in this way need to use custom concurrency primitives. I'm happy with the choice we made.
Hah, neat timing for your answer. I just finished following the urge to create a
Neat! It occurs to me that possibly the reason this hasn't existed yet is really that people don't know it's possible. Safety requirements of pinning are famously opaque.
lock_no_pin looks unsound to me: the soundness requirement for interior mutability is that there is no ability to get a mutable reference to the interior without having a mutable reference to the exterior. Otherwise, you can move out of a pinned mutex via
The returned guard object only implements
Deref, unless the target is
The only reason we looked into
Pin is that we're trying to do some weird stuff with
UnsafeCell: IntrusiveQCellOwner? · Issue #30 · uazu/qcell · GitHub
We don't think
Pin is actually necessary for safety and soundness here, but we could be wrong.
Anyway... these are all tangents. What's up with
This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.