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

Commit 083ae23

Browse files
committed
Make drain() consistently asynchronous.
1 parent a52397e commit 083ae23

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
@@ -1,4 +1,6 @@
11
// @dart = 2.6
2+
3+
import 'dart:async';
24
import 'dart:convert';
35
import 'dart:typed_data';
46
import 'dart:ui' as ui;
@@ -30,6 +32,32 @@ void main() {
3032
});
3133
});
3234

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

0 commit comments

Comments
 (0)