// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file // for details. All rights reserved. Use of this source code is governed by a // BSD-style license that can be found in the LICENSE file. // // VMOptions= // VMOptions=--short_socket_read // VMOptions=--short_socket_write // VMOptions=--short_socket_read --short_socket_write import "dart:async"; import "dart:io"; import "package:async_helper/async_helper.dart"; import "package:expect/expect.dart"; void testCancelResubscribeServerSocket(int socketCount, int backlog) { var acceptCount = 0; var doneCount = 0; var errorCount = 0; var earlyErrorCount = 0; asyncStart(); RawServerSocket.bind("127.0.0.1", 0, backlog: backlog).then((server) { Expect.isTrue(server.port > 0); void checkDone() { if (doneCount + errorCount + earlyErrorCount == socketCount) { asyncEnd(); // Be sure to close as subscription.cancel may not be called, if // backlog prevents acceptCount to grow to socketCount / 2. server.close(); } } var subscription; subscription = server.listen((client) { client.writeEventsEnabled = false; client.listen((event) { switch (event) { case RawSocketEvent.read: client.read(); break; case RawSocketEvent.readClosed: client.shutdown(SocketDirection.send); break; case RawSocketEvent.write: Expect.fail("No write event expected"); break; } }); if (++acceptCount == socketCount / 2) { // Cancel subscription and then attempt to resubscribe. subscription.cancel(); Timer.run(() { Expect.throws(() { server.listen((_) { // Server socket is closed on cancel, so no more events. Expect.fail("Event after closed through cancel"); }); }); }); } }); // Connect a number of sockets. for (int i = 0; i < socketCount; i++) { RawSocket.connect("127.0.0.1", server.port).then((socket) { bool done = false; var subscription; subscription = socket.listen((event) { switch (event) { case RawSocketEvent.read: Expect.fail("No read event expected"); break; case RawSocketEvent.readClosed: done = true; doneCount++; checkDone(); break; case RawSocketEvent.write: // We don't care if this write succeeds, so we don't check // the return value (number of bytes written). socket.write([1, 2, 3]); socket.shutdown(SocketDirection.send); break; } }, onDone: () { if (!done) { doneCount++; checkDone(); } }, onError: (e) { // "Connection reset by peer" errors are handled here. errorCount++; checkDone(); }, cancelOnError: true); }).catchError((e) { // "Connection actively refused by host" errors are handled here. earlyErrorCount++; checkDone(); }); } }); } void main() { testCancelResubscribeServerSocket(10, 20); testCancelResubscribeServerSocket(20, 5); }