-
Notifications
You must be signed in to change notification settings - Fork 233
Update shared memory proposal #4620
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
Changes from 2 commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -173,14 +173,14 @@ All compile time constants are deeply immutable instances. | |
| Unmodifiable lists (`List.unmodifiable`) which contain deeply immutable | ||
| instances are deeply immutable. | ||
|
|
||
| Closures which capture only `final` variables containing deeply immutable | ||
| instances are deeply immutable. | ||
| Closures which capture only `final`, non-`late` variables containing deeply | ||
| immutable instances are deeply immutable. | ||
|
|
||
| Finally, instances of classes annotated with `@pragma('vm:deeply-immutable')` | ||
| are deeply immutable. It is a compile error if classes annotated with this | ||
| pragma contain non-`final` fields. It is an compile time error if static | ||
| type of field within annotated class excludes deeply immutable instances. | ||
| If the static type of a field in a deeply immutable class is not | ||
| pragma contain non-`final` or `late final` fields. It is an compile time error | ||
|
mraleph marked this conversation as resolved.
Outdated
|
||
| if static type of field within annotated class excludes deeply immutable | ||
|
mraleph marked this conversation as resolved.
Outdated
|
||
| instances. If the static type of a field in a deeply immutable class is not | ||
| deeply immutable type - then compiler must insert checks in the constructor to | ||
| guarantee that this field is initialized to a deeply immutable value. | ||
|
|
||
|
|
@@ -206,7 +206,8 @@ values which are deeply immutable objects. | |
| * If static type of a field is a super-type for both deeply immutable and | ||
| non-deeply immutable objects then compiler will insert a runtime check | ||
| which ensures that values assigned to such field are deeply immutable. | ||
|
mraleph marked this conversation as resolved.
Outdated
|
||
| * A field or variable annotated with `@pragma('vm:shared')` must be `final`. | ||
| * A field or variable annotated with `@pragma('vm:shared')` must be `final` and | ||
|
mraleph marked this conversation as resolved.
Outdated
|
||
| non-`late`. | ||
|
|
||
| > [!NOTE] | ||
| > | ||
|
|
@@ -306,21 +307,103 @@ class Isolate { | |
| /// to acquire exclusive access to the isolate. | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. All these thread-based members of isolate, would it make sense to put them somewhere else than in Do we expect most people who use isolates to also want to use these thread-based functions, or will they clutter the API for the "normal" uses of
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yeah, these are fairly low-level. Maybe we need to introduce |
||
| /// | ||
| /// Throws [StateError] if target isolate is owned by another thread and | ||
| /// thus can't be entered from a different thread. | ||
| /// thus can't be entered from a different thread. See | ||
|
mraleph marked this conversation as resolved.
Outdated
|
||
| /// [markOwnedByCurrentThread] and [isOwnedByCurrentThread]. | ||
| /// | ||
| /// Throws [ArgumentError] if the target isolate belongs to another | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. How can an isolate obtain an
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
| /// isolate group. | ||
|
mraleph marked this conversation as resolved.
|
||
| /// | ||
| /// Throws [ArgumentError] if [f] is not deeply immutable. | ||
| /// | ||
| /// Throws [StateError] if result returned by [f] is not deeply immutable. | ||
|
mraleph marked this conversation as resolved.
Outdated
|
||
| R runSync<R>(R Function() f, {Duration? timeout}); | ||
| external R runSync<R>(R Function() f, {Duration? timeout}); | ||
|
|
||
| /// Create a new isolate in the current isolate group. | ||
| /// | ||
| /// Similar to `Dart_CreateIsolateInGroup` Dart VM C API. | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is this line useful to a reader? (Should I go read the docs on that function. If so, link!) (If it actualy calls that function, it might be relevant information, at some abstraction level. If it's just sort-of similar to a function that I don't know and can't be bothered to look at, that's just noise.)
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I wish I could link to these - but we don't publish documentation for these. So the best I could do is to link to sources, which is a bit wonky. It is hard to say whether these are useful or not - if reader is familiar with C API layer they are certainly useful because most of APIs introduced here are exposing functionality which is available through C API. I would prefer to keep these here for the purpose of spec review / but we can strip them later when landing actual code. |
||
| /// | ||
| /// Created isolate is in runnable state, but its event loop is not running. | ||
|
mraleph marked this conversation as resolved.
Outdated
|
||
| /// | ||
| /// To start processing isolate's messages: | ||
| /// | ||
| /// * start isolate's event loop synchronously on the current thread | ||
| /// by calling [Isolate.runEventLoopSync] | ||
| /// * integrate isolate's event loop with other event loop by registering | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why is the first step not enough? (What does the second step do?) Which "other event loop"?
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I have renamed "other event loop" to "external event loop". This path exists for integrating Dart isolate with code which already contains some sort of an event loop (e.g. imagine main platform thread on Android which has its own event loop). In this situation you use I welcome any further suggestions. |
||
| /// message callback ([Isolate.onMessage]) and draining pending messages | ||
| /// ([Isolate.handleMessage]). | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Who does that? (Which isolate should call those methods?)
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There is documentation on those methods on how to use them. I am not sure if it makes sense to copy it here? In general I would expect that these are called from outside the isolate (i.e. from the code running inside the isolate group, but not in any concrete isolate). |
||
| external static Isolate fork({String? debugName}); | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I find the name Furthermore from the motivating example in #4620 (comment) it seems that the caller may not even be an isolate with state. So when a Thread (aka shared isolate) calls Why not call it
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Renamed to |
||
|
|
||
| /// Shutdown target isolate. | ||
|
mraleph marked this conversation as resolved.
Outdated
|
||
| /// | ||
| /// This function will block until it acquires exclusive access to the | ||
| /// target isolate. Isolate can only be entered for synchronous execution | ||
| /// between turns of its event loop, when no other thread is | ||
|
mraleph marked this conversation as resolved.
|
||
| /// executing code in the target isolate. | ||
| external void shutdown(); | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. How does this differ from Could it be called
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It's closer to I would prefer to align terms with existing names from VM C API. |
||
|
|
||
| /// Set current OS thread as owner of the isolate. | ||
| /// | ||
| /// Once an isolate is owned by some OS thread it can not be | ||
|
mraleph marked this conversation as resolved.
Outdated
|
||
| /// entered by any other OS thread. An attempt to acquire | ||
| /// exclusive access to it from another thread will fail with | ||
| /// an error. | ||
| /// | ||
| /// Equivalent to `Dart_SetCurrentThreadOwnsIsolate` Dart VM C API. | ||
|
mraleph marked this conversation as resolved.
|
||
| /// | ||
| /// Throws [ArgumentError] if `this` is not `Isolate.current`. | ||
|
mraleph marked this conversation as resolved.
Outdated
|
||
| /// | ||
| /// Throws [StateError] if target isolate is already owned by another thread. | ||
|
mraleph marked this conversation as resolved.
Outdated
|
||
| external void markOwnedByCurrentThread(); | ||
|
mraleph marked this conversation as resolved.
Outdated
mraleph marked this conversation as resolved.
Outdated
|
||
|
|
||
| /// Returns `true` if the isolate is owned by the current OS thread. | ||
|
mraleph marked this conversation as resolved.
Outdated
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. When would you use this property? Unlike If you don't own the isolate, then you probably want to. In that case, you may need to know whether someone else owns it already. (So back to wanting a way to know that.)
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You can use this to decide whether you can just enter the isolate or you need to message it. |
||
| /// | ||
| /// Equivalent to `Dart_GetCurrentThreadOwnsIsolate` Dart VM C API. | ||
| external bool get isOwnedByCurrentThread; | ||
|
|
||
| /// Run event loop for the target isolate synchronously on the current thread. | ||
| /// | ||
| /// This function will block until it acquires exclusive access to the | ||
| /// target isolate. Isolate can only be entered for synchronous execution | ||
| /// between turns of its event loop, when no other thread is | ||
| /// executing code in the target isolate. | ||
|
mraleph marked this conversation as resolved.
|
||
| /// | ||
| /// The isolate will be marked as owned by the current thread. | ||
| /// | ||
| /// Similar to `Dart_RunLoop` Dart VM C API, but unlike `Dart_RunLoop` this | ||
| /// function executes isolate's event loop on the current thread instead | ||
| /// of delegating it into the thread-pool. | ||
| /// | ||
| /// Throws [StateError] if target isolate is owned by another thread. | ||
|
mraleph marked this conversation as resolved.
Outdated
|
||
| external static void runEventLoopSync(); | ||
|
mraleph marked this conversation as resolved.
Outdated
mraleph marked this conversation as resolved.
Outdated
|
||
|
|
||
| /// Set message notify callback for the isolate. | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Drop the "Set". (Document properties with noun phrases.) Styles do not agree on how to handle
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Unless we have some specific rule prohibiting setter-without-getter I would prefer to use that. We already have similar code in other places: https://api.dart.dev/dart-isolate/RawReceivePort/handler.html |
||
| /// | ||
| /// Provided callback will be called once for every message added to the | ||
|
mraleph marked this conversation as resolved.
Outdated
|
||
| /// isolates message queue. Pending messages can be then later be drained | ||
| /// by calling [Isolate.handleMessage]. | ||
| /// | ||
| /// Provided [callback] must be deeply immutable and will be called | ||
| /// on an arbitrary thread and not necessarily within some isolate. See | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. "not necessarily within some isolate" Is that "not necessarily within a specific isolate" or "not necessarily within any isolate"?
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yeah, I just don't see any good naming for this, hence the reference to |
||
| /// [NativeCallable.isolateGroupBound]. | ||
| /// | ||
| /// IMPORTANT: [Isolate.handleMessage] must *not* be called from the | ||
|
mraleph marked this conversation as resolved.
Outdated
|
||
| /// `callback`. | ||
|
mraleph marked this conversation as resolved.
Outdated
|
||
| /// | ||
| /// Similar to `Dart_SetMessageNotifyCallback` Dart VM C API. | ||
| external void set onMessage(void Function(Isolate) callback); | ||
|
mraleph marked this conversation as resolved.
Outdated
|
||
|
|
||
| /// Handle a single pending message from isolate's message queue. | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What if there aren't any? What happens if the isolate is paused?
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
| /// | ||
| /// This function will block until it acquires exclusive access to the | ||
| /// target isolate. Isolate can only be entered for synchronous execution | ||
| /// between turns of its event loop, when no other thread is | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What is a "turn"? 😉 |
||
| /// executing code in the target isolate. | ||
|
mraleph marked this conversation as resolved.
|
||
| /// | ||
| /// Similar to `Dart_HandleMessage` Dart VM C API. | ||
| external void handleMessage(); | ||
| } | ||
| ``` | ||
|
|
||
| **TODO**: Furthermore we might want to facilitate integration with third-party | ||
| event-loops: e.g. allow to create isolate without scheduling its event loop on | ||
| our own thread pool and provide equivalents of `Dart_SetMessageNotifyCallback` | ||
| and `Dart_HandleMessage`. Though maybe we should not bundle this all together | ||
| into one update. | ||
|
|
||
| ### Scoped thread local values | ||
|
|
||
| ```dart | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.