-
Notifications
You must be signed in to change notification settings - Fork 213
Library feature for isolate-shared variables. #4381
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
Comments
Just to be 100% clear: you're talking about changing |
The It would probably be And then it's also possible to have other kinds of variables, like maybe a per-isolate variable that can be accessed in a shared isolate, |
@lrhn I was looking at this code sample from the proposal. If it's not going to be a keyword, then I'd much rather have it be a class than an annotation. int global = 0;
shared int sharedGlobal = 0; // This looks like a keyword
void main() async {
global = 42;
sharedGlobal = 42;
await Isolate.runShared(() {
print(global);
global = 24;
print(sharedGlobal); // => 42
sharedGlobal = 24;
});
print(global); // => 42
print(sharedGlobal); // => 24
} |
There are some things I like about this proposal (e.g. every shared field automatically gets atomic APIs) and some things I don't like. Being shared or not-shared is an attribute of a location not the attribute of a value stored in that location. Similar to how We would need
It gets awkward. Also it is relatively easy to make a mistake and write Finally, this part of the proposal:
Requires some sort of language feature. I guess it could be tied to source location (similar to what widget transformer is doing - so maybe two birds can be killed here with one stone here). |
The non-canonicalization based on arguments does imply some compiler hack. It doesn't have to be anything more complicated than a hidden ID argument that is unique to each const invocation location. Imagine a constructor of the form: class Shared<V> {
external V value;
const Shared(V value) : this._(value, __constCallerId__);
external const Shared._(V value, Object? id);
} where Then each instance of final class Shared<V> {
external V value;
/// Shared mutable variable initialized to [value].
external const Shared(V value);
/// Shared mutable variable with optional initializer.
///
/// Throws if [value] is read before written when no [initializer] is provided.
/// Otherwise evaluates [initializer] on first read and assigns the
/// result before returning it to [value].
external const Shared.late([V Function()? initializer]);
}
final class FinalShared<V> implements Shared {
/// Shared unmodifiable value.
external FinalShared(V value);
/// Shared unmodifiable lazily-initialized value.
external FinalShared.late(V Function() initializer);
} |
The "shared native-memory multithreading" proposal includes "shared variables", which are static/top-level variables which share the same storage location across all isolates in an isolate group.
Instead of making this an annotation on the variable, it could be made a library feature, a class with a getter and setter which read from an isolate-shared storage location. (As someone suggested in a recent meeting.)
By doing so, more operations can be defined on the shared variable, operations that are only needed for shared variables.
Example of what such a class could look like:
It avoids depending on annotations, and it makes it very explicit when you are reading a shared variable.
It does mean that the migration from unshared variable to shared gets more comlicated:
becomes
instead of just adding an annotation.
It also allows specifying operations specifically on such variables.
The text was updated successfully, but these errors were encountered: