dart-lang / sdk

The Dart SDK, including the VM, JS and Wasm compilers, analysis, core libraries, and more.
https://dart.dev
BSD 3-Clause "New" or "Revised" License
10.26k stars 1.58k forks source link

`Socket.done` is never completed when the socket is destroyed before sending data #26288

Open sigurdm opened 8 years ago

sigurdm commented 8 years ago
import "dart:io";

main() async {
  var socket = await Socket.connect("google.com", 80);
  // socket.add([0]);
  socket.destroy();
  await socket.done;
  print("Done");
}

This program never prints "Done". If the line with socket.add is included; "Done" is printed.

zoechi commented 8 years ago

Sounds like http://stackoverflow.com/questions/28159029/why-doesnt-the-process-exit-during-this-unittest-with-dartio

bkonyi commented 6 years ago

It looks like that when Socket.destroy() is called on a Socket that hasn't been listened to or written to, the underlying StreamController is left in its initial state as it has not yet been subscribed to (see _isInitialState in stream_controller.dart). As such, we add a done event to the StreamController's pending events queue, which is where it is kept until a subscription to the Stream is created. I think we should probably drain the pending events or at least complete the done Future some other way.

sigurdm commented 5 years ago

This seems to still be the case in 2.2.1-dev.2.0. @sortie

larssn commented 3 months ago

This still seems to be the case.

Had to make the following workaround:

socket.add(data);
final sub = socket.listen((_) {}, cancelOnError: true);
await socket.done;
print('Request done!');
sub.cancel();

If the listen isn't present, it will await for socket.done forever.