Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

Commit 681f3fd

Browse files
committed
Make drain() consistently asynchronous.
1 parent 7653b92 commit 681f3fd

File tree

3 files changed

+33
-0
lines changed

3 files changed

+33
-0
lines changed

lib/ui/channel_buffers.dart

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -181,7 +181,11 @@ class ChannelBuffers {
181181
///
182182
/// This should be called once a channel is prepared to handle messages
183183
/// (i.e. when a message handler is setup in the framework).
184+
///
185+
/// The messages are processed by calling the given `callback`. Each message
186+
/// is processed in its own microtask.
184187
Future<void> drain(String channel, DrainChannelCallback callback) async {
188+
await null; // Ensures that the rest of this method is scheduled in a microtask.
185189
while (!_isEmpty(channel)) {
186190
final _StoredMessage message = _pop(channel)!;
187191
await callback(message.data, message.callback);

lib/web_ui/lib/src/ui/channel_buffers.dart

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,7 @@ class ChannelBuffers {
119119
}
120120

121121
Future<void> drain(String channel, DrainChannelCallback callback) async {
122+
await null; // Ensures that the rest of this method is scheduled in a microtask.
122123
while (!_isEmpty(channel)) {
123124
final _StoredMessage message = _pop(channel)!;
124125
await callback(message.data, message.callback);

testing/dart/channel_buffers_test.dart

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
// found in the LICENSE file.
44

55
// @dart = 2.6
6+
7+
import 'dart:async';
68
import 'dart:convert';
79
import 'dart:typed_data';
810
import 'dart:ui' as ui;
@@ -34,6 +36,32 @@ void main() {
3436
});
3537
});
3638

39+
test('drain is async', () async {
40+
const String channel = 'foo';
41+
final ByteData data = _makeByteData('message');
42+
final ui.ChannelBuffers buffers = ui.ChannelBuffers();
43+
final ui.PlatformMessageResponseCallback callback = (ByteData responseData) {};
44+
buffers.push(channel, data, callback);
45+
final List<String> log = <String>[];
46+
final Completer<void> completer = Completer<void>();
47+
scheduleMicrotask(() { log.add('before drain, microtask'); });
48+
log.add('before drain');
49+
buffers.drain(channel, (ByteData drainedData, ui.PlatformMessageResponseCallback drainedCallback) async {
50+
log.add('callback');
51+
completer.complete();
52+
});
53+
log.add('after drain, before await');
54+
await completer.future;
55+
log.add('after await');
56+
expect(log, <String>[
57+
'before drain',
58+
'after drain, before await',
59+
'before drain, microtask',
60+
'callback',
61+
'after await'
62+
]);
63+
});
64+
3765
test('push drain zero', () async {
3866
const String channel = 'foo';
3967
final ByteData data = _makeByteData('bar');

0 commit comments

Comments
 (0)