Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Sign in
Toggle navigation
F
Front-End
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
abdullh.alsoleman
Front-End
Commits
3219da9b
Unverified
Commit
3219da9b
authored
Nov 29, 2022
by
Dan Field
Committed by
GitHub
Nov 29, 2022
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Use Isolate.run as implementation for compute (#115779)
parent
8b32ac7a
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
4 additions
and
137 deletions
+4
-137
_isolates_io.dart
packages/flutter/lib/src/foundation/_isolates_io.dart
+4
-137
No files found.
packages/flutter/lib/src/foundation/_isolates_io.dart
View file @
3219da9b
...
...
@@ -3,9 +3,7 @@
// found in the LICENSE file.
import
'dart:async'
;
import
'dart:developer'
;
import
'dart:isolate'
;
import
'package:meta/meta.dart'
;
import
'constants.dart'
;
import
'isolates.dart'
as
isolates
;
...
...
@@ -13,141 +11,10 @@ import 'isolates.dart' as isolates;
export
'isolates.dart'
show
ComputeCallback
;
/// The dart:io implementation of [isolate.compute].
Future
<
R
>
compute
<
Q
,
R
>(
isolates
.
ComputeCallback
<
Q
,
R
>
callback
,
Q
message
,
{
String
?
debugLabel
})
async
{
Future
<
R
>
compute
<
Q
,
R
>(
isolates
.
ComputeCallback
<
Q
,
R
>
callback
,
Q
message
,
{
String
?
debugLabel
})
async
{
debugLabel
??=
kReleaseMode
?
'compute'
:
callback
.
toString
();
final
Flow
flow
=
Flow
.
begin
();
Timeline
.
startSync
(
'
$debugLabel
: start'
,
flow:
flow
);
final
RawReceivePort
port
=
RawReceivePort
();
Timeline
.
finishSync
();
void
timeEndAndCleanup
()
{
Timeline
.
startSync
(
'
$debugLabel
: end'
,
flow:
Flow
.
end
(
flow
.
id
));
port
.
close
();
Timeline
.
finishSync
();
}
final
Completer
<
dynamic
>
completer
=
Completer
<
dynamic
>();
port
.
handler
=
(
dynamic
msg
)
{
timeEndAndCleanup
();
completer
.
complete
(
msg
);
};
try
{
await
Isolate
.
spawn
<
_IsolateConfiguration
<
Q
,
R
>>(
_spawn
,
_IsolateConfiguration
<
Q
,
R
>(
callback
,
message
,
port
.
sendPort
,
debugLabel
,
flow
.
id
,
),
onExit:
port
.
sendPort
,
onError:
port
.
sendPort
,
debugName:
debugLabel
,
);
}
on
Object
{
timeEndAndCleanup
();
rethrow
;
}
final
dynamic
response
=
await
completer
.
future
;
if
(
response
==
null
)
{
throw
RemoteError
(
'Isolate exited without result or error.'
,
''
);
}
assert
(
response
is
List
<
dynamic
>);
response
as
List
<
dynamic
>;
final
int
type
=
response
.
length
;
assert
(
1
<=
type
&&
type
<=
3
);
switch
(
type
)
{
// success; see _buildSuccessResponse
case
1
:
return
response
[
0
]
as
R
;
// native error; see Isolate.addErrorListener
case
2
:
await
Future
<
Never
>.
error
(
RemoteError
(
response
[
0
]
as
String
,
response
[
1
]
as
String
,
));
// caught error; see _buildErrorResponse
case
3
:
default
:
assert
(
type
==
3
&&
response
[
2
]
==
null
);
await
Future
<
Never
>.
error
(
response
[
0
]
as
Object
,
response
[
1
]
as
StackTrace
,
);
}
}
@immutable
class
_IsolateConfiguration
<
Q
,
R
>
{
const
_IsolateConfiguration
(
this
.
callback
,
this
.
message
,
this
.
resultPort
,
this
.
debugLabel
,
this
.
flowId
,
);
final
isolates
.
ComputeCallback
<
Q
,
R
>
callback
;
final
Q
message
;
final
SendPort
resultPort
;
final
String
debugLabel
;
final
int
flowId
;
FutureOr
<
R
>
applyAndTime
()
{
return
Timeline
.
timeSync
(
debugLabel
,
()
=>
callback
(
message
),
flow:
Flow
.
step
(
flowId
),
);
}
}
/// The spawn point MUST guarantee only one result event is sent through the
/// [SendPort.send] be it directly or indirectly i.e. [Isolate.exit].
///
/// In case an [Error] or [Exception] are thrown AFTER the data
/// is sent, they will NOT be handled or reported by the main [Isolate] because
/// it stops listening after the first event is received.
///
/// Also use the helpers [_buildSuccessResponse] and [_buildErrorResponse] to
/// build the response
Future
<
void
>
_spawn
<
Q
,
R
>(
_IsolateConfiguration
<
Q
,
R
>
configuration
)
async
{
late
final
List
<
dynamic
>
computationResult
;
try
{
computationResult
=
_buildSuccessResponse
(
await
configuration
.
applyAndTime
());
}
catch
(
e
,
s
)
{
computationResult
=
_buildErrorResponse
(
e
,
s
);
}
Isolate
.
exit
(
configuration
.
resultPort
,
computationResult
);
}
/// Wrap in [List] to ensure our expectations in the main [Isolate] are met.
///
/// We need to wrap a success result in a [List] because the user provided type
/// [R] could also be a [List]. Meaning, a check `result is R` could return true
/// for what was an error event.
List
<
R
>
_buildSuccessResponse
<
R
>(
R
result
)
{
return
List
<
R
>.
filled
(
1
,
result
);
}
/// Wrap in [List] to ensure our expectations in the main isolate are met.
///
/// We wrap a caught error in a 3 element [List]. Where the last element is
/// always null. We do this so we have a way to know if an error was one we
/// caught or one thrown by the library code.
List
<
dynamic
>
_buildErrorResponse
(
Object
error
,
StackTrace
stack
)
{
return
List
<
dynamic
>.
filled
(
3
,
null
)
..[
0
]
=
error
..[
1
]
=
stack
;
return
Isolate
.
run
<
R
>(()
{
return
callback
(
message
);
},
debugName:
debugLabel
);
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment