Update the Linux watcher to accommodate changes in [Directory.watch].

This also removes the extra time allotted for the test since issue
14606 is now mitigated.

R=rnystrom@google.com
BUG=15446

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

git-svn-id: https://dart.googlecode.com/svn/branches/bleeding_edge/dart/pkg/watcher@30874 260f80e4-7a28-3924-810f-c04153c831b5
diff --git a/pkgs/watcher/lib/src/directory_watcher/linux.dart b/pkgs/watcher/lib/src/directory_watcher/linux.dart
index d62c6ef..5e86a43 100644
--- a/pkgs/watcher/lib/src/directory_watcher/linux.dart
+++ b/pkgs/watcher/lib/src/directory_watcher/linux.dart
@@ -213,7 +213,7 @@
 
       if (oldState == _EntryState.DIRECTORY) {
         var watcher = _subWatchers.remove(path);
-        if (watcher == null) return;
+        if (watcher == null) continue;
         for (var path in watcher._allFiles) {
           _eventsController.add(new WatchEvent(ChangeType.REMOVE, path));
         }
@@ -247,6 +247,17 @@
   /// Handles the underlying event stream closing, indicating that the directory
   /// being watched was removed.
   void _onDone() {
+    // Most of the time when a directory is removed, its contents will get
+    // individual REMOVE events before the watch stream is closed -- in that
+    // case, [_entries] will be empty here. However, if the directory's removal
+    // is caused by a MOVE, we need to manually emit events.
+    if (isReady) {
+      _entries.forEach((path, state) {
+        if (state == _EntryState.DIRECTORY) return;
+        _eventsController.add(new WatchEvent(ChangeType.REMOVE, path));
+      });
+    }
+
     // The parent directory often gets a close event before the subdirectories
     // are done emitting events. We wait for them to finish before we close
     // [events] so that we can be sure to emit a remove event for every file
diff --git a/pkgs/watcher/test/directory_watcher/linux_test.dart b/pkgs/watcher/test/directory_watcher/linux_test.dart
index ba69569..f53b272 100644
--- a/pkgs/watcher/test/directory_watcher/linux_test.dart
+++ b/pkgs/watcher/test/directory_watcher/linux_test.dart
@@ -14,14 +14,7 @@
 
   watcherFactory = (dir) => new LinuxDirectoryWatcher(dir);
 
-  setUp(() {
-    // Increase the timeout because closing a [Directory.watch] stream blocks
-    // the main isolate for a very long time on Goobuntu, as of kernel
-    // 3.2.5-gg1336 (see issue 14606).
-    currentSchedule.timeout *= 3;
-
-    createSandbox();
-  });
+  setUp(createSandbox);
 
   sharedTests();