-
Notifications
You must be signed in to change notification settings - Fork 242
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
Remove support for non-threadsafe interfaces. #452
Conversation
// to the shared counter object. | ||
|
||
ThreadsafeCounter().use { counter -> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I removed some layers of abstraction from this test, and moved it from "examples" to "fixtures". The abstractions seemed less necessary now that it's not trying to test both the threadsafe and non-threadsafe scenarios.
This is ready for review, but I don't plan to land it with any urgency. My main motivation here is to simplify work on the Arc-pointers effort, and in particular, to simplify the docs will that will need to be written for that effort. I'm not really interested in trying to explain a different version of the automagic-mutex behaviour in addition to rambling on about Arcs. |
30d0311
to
a90232a
Compare
a90232a
to
791f89d
Compare
from foreign languages on any thread, outside of the control of Rust's ownership | ||
system. UniFFI itself tries to take a hands-off approach as much as possible and | ||
depends on the Rust compiler itself to uphold safety guarantees, without assuming | ||
that foreign-language callers will be "well behaved". |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
great - so the nits below are probably mine :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Lovely!
Typically this will mean that the Rust implementation of an object uses some of Rust's | ||
data structures for thread-safe interior mutability, such as a `Mutex` or `RwLock` or | ||
the types from `std::atomic`. The precise details are completely up to the author | ||
of the component - as much as possible, UniFFI tries to stay out of your way, simply requiring |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍
underlying struct to use interior mutability and manage its own locking. | ||
* The `ArcHandleMap` can only contain structs that are `Sync` and `Send`, ensuring that | ||
shared references can safely be accessed from multiple threads. | ||
by enforcing that the contained type is `Send+Sync`, and by refusing to hand out any mutable references. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
s/enforcing that the contained type is/specifying that the contained type must be/ or something? "enforcing" makes it sound like some kind of check the map itself is doing, but it's the compiler that is actually enforcing.
docs/manual/src/udl/interfaces.md
Outdated
@@ -40,11 +40,9 @@ interface TodoList { | |||
|
|||
By convention, the `constructor()` calls the Rust's `new()` method. | |||
|
|||
Conceptually, these `interface` objects are live Rust objects that have a proxy on the foreign language side; calling any methods on them, including a constructor or destructor results in the corresponding methods being call in Rust. | |||
Conceptually, these `interface` objects are live Rust structs that have a proxy object on the foreign language side; calling any methods on them, including a constructor or destructor results in the corresponding methods being call in Rust. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
typo: called
docs/manual/src/udl/interfaces.md
Outdated
`uniffi` will generate these proxies of live objects with an interface or protocol. | ||
|
||
e.g. in Kotlin. | ||
UniFFI will generate these proxies of live objects with an interface or protocol to help with testing in the foreign-language code. For example in Kotlin, the `TodoList` would generate: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: "of live objects" can probably be dropped from this sentence?
examples/sprites/src/lib.rs
Outdated
@@ -31,8 +31,8 @@ pub fn translate(p: &Point, v: Vector) -> Point { | |||
// and which can move about over time. | |||
#[derive(Debug)] | |||
pub struct Sprite { | |||
// All interfaces must be threadsafe, meaning `Send+Sync`, and our naive | |||
// `Point` struct isn't - so we wrap it in a `RwLock` to make it so. | |||
// All interfaces must be `Send + Sync`, and our naive `Point` struct |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: almost everywhere else has no space between Send and Sync. Not sure which one is actually preferred, but we might as well be consistent.
from foreign languages on any thread, outside of the control of Rust's ownership | ||
system. UniFFI itself tries to take a hands-off approach as much as possible and | ||
depends on the Rust compiler itself to uphold safety guarantees, without assuming | ||
that foreign-language callers will be "well behaved". |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
great - so the nits below are probably mine :)
791f89d
to
82dbf73
Compare
65c6aef
to
199b8a9
Compare
324494a
to
2a958c7
Compare
2a958c7
to
fa7aa1f
Compare
Fixes #449. With the v0.9.0 release of UniFFI, non-threadsafe interfaces are explicitly deprecated. This commit removes support for non-threadsafe interfaces entirely, making threadsafety the default and only supported mode. In practice, for any `interface` declared in the UDL: * Its implementation must be `Sync` and `Send`. * Its methods cannot accept a mutable `&self` parameter. The `[Threadsafe]` attribute may still be specified explicitly in the UDL file, but will result in a deprecation warning and is otherwise ignored. We don't have a good way to write tests for the following, but I've manually verified that: * A non-`Send+Sync` interface implementation produces a compile-time error. * Use of the `[Threadsafe]` attribute results in a deprecation warning. Co-authored-by: Neil P. <npars@users.noreply.github.com> Co-authored-by: Mark Hammond <mhammond@skippinet.com.au>
fa7aa1f
to
52ef91a
Compare
Let's push ahead with this; if we feel like we need further releases in the |
Fixes #449. Depends on #451. This will be a draft until we've given the v0.9.0 release a chance to roll out to consumers.
With the v0.9.0 release of UniFFI, non-threadsafe interfaces are explicitly deprecated. This commit removes support for non-threadsafe interfaces entirely, making threadsafety the default and only supported mode. In practice, for any
interface
declared in the UDL:Sync
andSend
.&self
parameter.The
[Threadsafe]
attribute may still be specified explicitly in the UDL file, but will result in a deprecation warning and is otherwise ignored.We don't have a good way to write tests for the following, but I've manually verified that:
Send+Sync
interface implementation produces a compile-time error.[Threadsafe]
attribute results in a deprecation warning.