|  | // 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:expect/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); | 
|  | } |