Revert r38549, r38552, and r38557.

It's currently too difficult to include a third party package for it to be
worthwhile for this use case.

R=alanknight@google.com

Review URL: https://codereview.chromium.org//419683002

git-svn-id: https://dart.googlecode.com/svn/branches/bleeding_edge/dart/pkg/pool@38564 260f80e4-7a28-3924-810f-c04153c831b5
diff --git a/CHANGELOG.md b/CHANGELOG.md
deleted file mode 100644
index e8dee50..0000000
--- a/CHANGELOG.md
+++ /dev/null
@@ -1,3 +0,0 @@
-## 1.0.1
-
-* A `TimeoutException` is now correctly thrown if the pool detects a deadlock.
diff --git a/lib/pool.dart b/lib/pool.dart
index 61482e3..36a29c8 100644
--- a/lib/pool.dart
+++ b/lib/pool.dart
@@ -40,14 +40,14 @@
   Timer _timer;
 
   /// The amount of time to wait before timing out the pending resources.
-  final Duration _timeout;
+  Duration _timeout;
 
   /// Creates a new pool with the given limit on how many resources may be
   /// allocated at once.
   ///
   /// If [timeout] is passed, then if that much time passes without any activity
-  /// all pending [request] futures will throw a [TimeoutException]. This is
-  /// intended to avoid deadlocks.
+  /// all pending [request] futures will throw an exception. This is indented
+  /// to avoid deadlocks.
   Pool(this._maxAllocatedResources, {Duration timeout})
       : _timeout = timeout;
 
@@ -106,11 +106,8 @@
   /// emit exceptions.
   void _onTimeout() {
     for (var completer in _requestedResources) {
-      completer.completeError(
-          new TimeoutException("Pool deadlock: all resources have been "
-              "allocated for too long.",
-              _timeout),
-          new Chain.current());
+      completer.completeError("Pool deadlock: all resources have been "
+          "allocated for too long.", new Chain.current());
     }
     _requestedResources.clear();
     _timer = null;
diff --git a/pubspec.yaml b/pubspec.yaml
index 9972cbb..c1d543f 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -1,10 +1,9 @@
 name: pool
-version: 1.0.1
+version: 1.0.0
 author: Dart Team <misc@dartlang.org>
 description: A class for managing a finite pool of resources.
 homepage: http://www.dartlang.org
 dependencies:
   stack_trace: ">=0.9.2 <2.0.0"
 dev_dependencies:
-  fake_async: ">=0.1.0 <0.2.0"
   unittest: ">=0.11.0 <0.12.0"
diff --git a/test/pool_test.dart b/test/pool_test.dart
index bb9e607..bfeb876 100644
--- a/test/pool_test.dart
+++ b/test/pool_test.dart
@@ -4,7 +4,6 @@
 
 import 'dart:async';
 
-import 'package:fake_async/fake_async.dart';
 import 'package:pool/pool.dart';
 import 'package:stack_trace/stack_trace.dart';
 import 'package:unittest/unittest.dart';
@@ -20,36 +19,30 @@
     });
 
     test("resources block past the limit", () {
-      new FakeAsync().run((async) {
-        var pool = new Pool(50);
-        var requests = [];
-        for (var i = 0; i < 50; i++) {
-          expect(pool.request(), completes);
-        }
-        expect(pool.request(), doesNotComplete);
-
-        async.elapse(new Duration(seconds: 1));
-      });
+      var pool = new Pool(50);
+      var requests = [];
+      for (var i = 0; i < 50; i++) {
+        expect(pool.request(), completes);
+      }
+      expect(pool.request(), doesNotComplete);
     });
 
     test("a blocked resource is allocated when another is released", () {
-      new FakeAsync().run((async) {
-        var pool = new Pool(50);
-        var requests = [];
-        for (var i = 0; i < 49; i++) {
-          expect(pool.request(), completes);
-        }
+      var pool = new Pool(50);
+      var requests = [];
+      for (var i = 0; i < 49; i++) {
+        expect(pool.request(), completes);
+      }
 
-        pool.request().then((lastAllocatedResource) {
-          // This will only complete once [lastAllocatedResource] is released.
-          expect(pool.request(), completes);
+      return pool.request().then((lastAllocatedResource) {
+        var blockedResource = pool.request();
 
-          new Future.delayed(new Duration(microseconds: 1)).then((_) {
-            lastAllocatedResource.release();
-          });
+        return pumpEventQueue().then((_) {
+          lastAllocatedResource.release();
+          return pumpEventQueue();
+        }).then((_) {
+          expect(blockedResource, completes);
         });
-
-        async.elapse(new Duration(seconds: 1));
       });
     });
   });
@@ -64,113 +57,63 @@
     });
 
     test("blocks the callback past the limit", () {
-      new FakeAsync().run((async) {
-        var pool = new Pool(50);
-        var requests = [];
-        for (var i = 0; i < 50; i++) {
-          pool.withResource(expectAsync(() => new Completer().future));
-        }
-        pool.withResource(expectNoAsync());
-
-        async.elapse(new Duration(seconds: 1));
-      });
+      var pool = new Pool(50);
+      var requests = [];
+      for (var i = 0; i < 50; i++) {
+        pool.withResource(expectAsync(() => new Completer().future));
+      }
+      pool.withResource(expectNoAsync());
     });
 
     test("a blocked resource is allocated when another is released", () {
-      new FakeAsync().run((async) {
-        var pool = new Pool(50);
-        var requests = [];
-        for (var i = 0; i < 49; i++) {
-          pool.withResource(expectAsync(() => new Completer().future));
-        }
+      var pool = new Pool(50);
+      var requests = [];
+      for (var i = 0; i < 49; i++) {
+        pool.withResource(expectAsync(() => new Completer().future));
+      }
 
-        var completer = new Completer();
-        var lastAllocatedResource = pool.withResource(() => completer.future);
-        var blockedResourceAllocated = false;
-        var blockedResource = pool.withResource(() {
-          blockedResourceAllocated = true;
-        });
+      var completer = new Completer();
+      var lastAllocatedResource = pool.withResource(() => completer.future);
+      var blockedResourceAllocated = false;
+      var blockedResource = pool.withResource(() {
+        blockedResourceAllocated = true;
+      });
 
-        new Future.delayed(new Duration(microseconds: 1)).then((_) {
-          expect(blockedResourceAllocated, isFalse);
-          completer.complete();
-          return new Future.delayed(new Duration(microseconds: 1));
-        }).then((_) {
-          expect(blockedResourceAllocated, isTrue);
-        });
-
-        async.elapse(new Duration(seconds: 1));
+      return pumpEventQueue().then((_) {
+        expect(blockedResourceAllocated, isFalse);
+        completer.complete();
+        return pumpEventQueue();
+      }).then((_) {
+        expect(blockedResourceAllocated, isTrue);
       });
     });
   });
 
-  group("with a timeout", () {
-    test("doesn't time out if there are no pending requests", () {
-      new FakeAsync().run((async) {
-        var pool = new Pool(50, timeout: new Duration(seconds: 5));
-        for (var i = 0; i < 50; i++) {
-          expect(pool.request(), completes);
-        }
+  // TODO(nweiz): Test timeouts when it's easier to use third-party packages.
+  // See r38552.
+}
 
-        async.elapse(new Duration(seconds: 6));
-      });
-    });
-
-    test("resets the timer if a resource is returned", () {
-      new FakeAsync().run((async) {
-        var pool = new Pool(50, timeout: new Duration(seconds: 5));
-        for (var i = 0; i < 49; i++) {
-          expect(pool.request(), completes);
-        }
-
-        pool.request().then((lastAllocatedResource) {
-          // This will only complete once [lastAllocatedResource] is released.
-          expect(pool.request(), completes);
-
-          new Future.delayed(new Duration(seconds: 3)).then((_) {
-            lastAllocatedResource.release();
-            expect(pool.request(), doesNotComplete);
-          });
-        });
-
-        async.elapse(new Duration(seconds: 6));
-      });
-    });
-
-    test("resets the timer if a resource is requested", () {
-      new FakeAsync().run((async) {
-        var pool = new Pool(50, timeout: new Duration(seconds: 5));
-        for (var i = 0; i < 50; i++) {
-          expect(pool.request(), completes);
-        }
-        expect(pool.request(), doesNotComplete);
-
-        new Future.delayed(new Duration(seconds: 3)).then((_) {
-          expect(pool.request(), doesNotComplete);
-        });
-
-        async.elapse(new Duration(seconds: 6));
-      });
-    });    
-
-    test("times out if nothing happens", () {
-      new FakeAsync().run((async) {
-        var pool = new Pool(50, timeout: new Duration(seconds: 5));
-        for (var i = 0; i < 50; i++) {
-          expect(pool.request(), completes);
-        }
-        expect(pool.request(), throwsA(new isInstanceOf<TimeoutException>()));
-
-        async.elapse(new Duration(seconds: 6));
-      });
-    });    
-  });
+/// Returns a [Future] that completes after pumping the event queue [times]
+/// times. By default, this should pump the event queue enough times to allow
+/// any code to run, as long as it's not waiting on some external event.
+Future pumpEventQueue([int times = 20]) {
+  if (times == 0) return new Future.value();
+  // We use a delayed future to allow microtask events to finish. The
+  // Future.value or Future() constructors use scheduleMicrotask themselves and
+  // would therefore not wait for microtask callbacks that are scheduled after
+  // invoking this method.
+  return new Future.delayed(Duration.ZERO, () => pumpEventQueue(times - 1));
 }
 
 /// Returns a function that will cause the test to fail if it's called.
 ///
-/// This should only be called within a [FakeAsync.run] zone.
+/// This won't let the test complete until it's confident that the function
+/// won't be called.
 Function expectNoAsync() {
+  // Make sure the test lasts long enough for the function to get called if it's
+  // going to get called.
+  expect(pumpEventQueue(), completes);
+
   var stack = new Trace.current(1);
   return () => handleExternalError(
       new TestFailure("Expected function not to be called."), "",
@@ -179,9 +122,13 @@
 
 /// A matcher for Futures that asserts that they don't complete.
 ///
-/// This should only be called within a [FakeAsync.run] zone.
+/// This won't let the test complete until it's confident that the function
+/// won't be called.
 Matcher get doesNotComplete => predicate((future) {
   expect(future, new isInstanceOf<Future>('Future'));
+  // Make sure the test lasts long enough for the function to get called if it's
+  // going to get called.
+  expect(pumpEventQueue(), completes);
 
   var stack = new Trace.current(1);
   future.then((_) => handleExternalError(