Skip to content

[objective_c] NSInputStream doesn't support run loop scheduling #3752

Closed

Description

@brianquinlan

The NSInputStream returned by toNSInputStream ignores scheduleInRunLoop:forMode:, never sends stream events to its delegate, and hasBytesAvailable returns YES even when no data is buffered. So a reader that schedules the stream and waits for events never receives any.

NSURLSession schedules request body streams, but because hasBytesAvailable returns YES, it calls read:maxLength on its single, process-wide com.apple.NSURLConnectionLoader thread, which waits until the Dart stream provides data. Until then, no other NSURLSession request in the process can make progress. package:cupertino_http sends StreamedRequest bodies this way.

To reproduce, add this to pkgs/objective_c/test/ns_input_stream_test.dart:

test('hasBytesAvailable when scheduled in a run loop', () {
  final controller = StreamController<List<int>>();
  final inputStream = controller.stream.toNSInputStream();
  addTearDown(inputStream.close);
  inputStream.scheduleInRunLoop(
    NSRunLoop.getCurrentRunLoop(),
    forMode: 'kCFRunLoopDefaultMode'.toNSString(),
  );
  inputStream.open();
  expect(inputStream.hasBytesAvailable, isFalse);
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions