@@ -509,17 +509,23 @@ initialization it complete.
509
509
In the _ shared ** everything** multithreading_ shared fields can be allowed to
510
510
contain anything - including instances of mutable Dart classes. However,
511
511
initially I propose to limit shared fields by allowing only _ trivially shareable
512
- types_ . These types are those which already can pass through
513
- ` SendPort ` without copying:
514
-
515
- - strings;
516
- - numbers;
517
- - [ deeply immutable] [ ] types;
518
- - builtin implementations of ` SendPort ` and ` TypedData ` ;
519
- - tear-offs of static methods;
520
- - closures which capture variables of trivially shareable types;
512
+ types_ , which include:
521
513
522
- Sharing of these types don't break isolate boundaries.
514
+ - Objects which do not contain mutable state and thus can already pass through
515
+ ` SendPort ` without copying:
516
+ - strings;
517
+ - numbers;
518
+ - instances of [ deeply immutable] [ ] types;
519
+ - instances of internal implementation of ` SendPort ` ;
520
+ - tear-offs of static methods;
521
+ - compile time constants;
522
+ - Objects which contain non-structural (binary) mutable state:
523
+ - ` TypedData `
524
+ - ` Struct ` instances
525
+ - Closures which capture variables which are annotated with ` @pragma('vm:shared') `
526
+ and are of trivially shareable types;
527
+
528
+ Sharing of these types does not break isolate boundaries.
523
529
524
530
[ deeply immutable ] : https://github.com/dart-lang/sdk/blob/bb59b5c72c52369e1b0d21940008c4be7e6d43b3/runtime/docs/deeply_immutable.md
525
531
@@ -553,6 +559,12 @@ Sharing of these types don't break isolate boundaries.
553
559
> Furthermore, shared fields of ` int ` and ` double ` types are allowed to exhibit
554
560
> _ tearing_ on 32-bit platforms.
555
561
562
+ > [ !NOTE]
563
+ >
564
+ > There is no static type marker for a trivially shareable closure. For convenience
565
+ > reasons we should allow writing ` @pragma('vm:shared') void Function() foo; ` but
566
+ > will have to check shareability in runtime when such variable is initialized.
567
+
556
568
## Shared Isolates
557
569
558
570
Lets take another look at the following example:
@@ -678,16 +690,29 @@ associated with that:
678
690
679
691
In _ shared ** everything** multithreading_ world ` callback ` can be allowed to
680
692
capture arbitrary state, however in _ shared ** native memory** multithreading_
681
- this state has to be restricted to trivially shareable types:
693
+ this state has to be restricted to trivially shareable types. To make it
694
+ completely unambigious we impose an additional requirement that all variables
695
+ captured by a closure will need to be annotated with ` @pragma('vm:shared') ` :
696
+
682
697
683
698
``` dart
684
- // This code is okay because `int` is trivially shareable.
699
+ // This code is okay because the variable is annotated and `int` is
700
+ // trivially shareable.
701
+ @pragma('vm:shared')
702
+ int counter = 0;
703
+ NativeCallable.shared(() {
704
+ counter++;
705
+ });
706
+
707
+ // This code causes a runtime error because `counter` is not not
708
+ // annotated with vm:shared pragma.
685
709
int counter = 0;
686
710
NativeCallable.shared(() {
687
711
counter++;
688
712
});
689
713
690
714
// This code is not okay because `List<T>` is not trivially shareable.
715
+ @pragma('vm:shared')
691
716
List<int> list = [];
692
717
NativeCallable.shared(() {
693
718
list.add(1);
0 commit comments