Add stack chain support to pkg/watcher and pkg/http.

R=rnystrom@google.com
BUG=

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

git-svn-id: https://dart.googlecode.com/svn/branches/bleeding_edge/dart/pkg/watcher@30912 260f80e4-7a28-3924-810f-c04153c831b5
diff --git a/lib/src/directory_watcher/linux.dart b/lib/src/directory_watcher/linux.dart
index 5e86a43..76558dd 100644
--- a/lib/src/directory_watcher/linux.dart
+++ b/lib/src/directory_watcher/linux.dart
@@ -7,6 +7,8 @@
 import 'dart:async';
 import 'dart:io';
 
+import 'package:stack_trace/stack_trace.dart';
+
 import '../utils.dart';
 import '../watch_event.dart';
 import 'resubscribable.dart';
@@ -56,13 +58,13 @@
   _LinuxDirectoryWatcher(String directory)
       : directory = directory {
     // Batch the inotify changes together so that we can dedup events.
-    var innerStream = new Directory(directory).watch().transform(
-        new BatchedStreamTransformer<FileSystemEvent>());
+    var innerStream = Chain.track(new Directory(directory).watch())
+        .transform(new BatchedStreamTransformer<FileSystemEvent>());
     _listen(innerStream, _onBatch,
         onError: _eventsController.addError,
         onDone: _onDone);
 
-    _listen(new Directory(directory).list(), (entity) {
+    _listen(Chain.track(new Directory(directory).list()), (entity) {
       _entries[entity.path] = new _EntryState(entity is Directory);
       if (entity is! Directory) return;
       _watchSubdir(entity.path);
@@ -157,7 +159,7 @@
     // event for every new file.
     watcher.ready.then((_) {
       if (!isReady || _eventsController.isClosed) return;
-      _listen(new Directory(path).list(recursive: true), (entry) {
+      _listen(Chain.track(new Directory(path).list(recursive: true)), (entry) {
         if (entry is Directory) return;
         _eventsController.add(new WatchEvent(ChangeType.ADD, entry.path));
       }, onError: (error, stackTrace) {
diff --git a/lib/src/directory_watcher/mac_os.dart b/lib/src/directory_watcher/mac_os.dart
index 5b1feb3..16de1d9 100644
--- a/lib/src/directory_watcher/mac_os.dart
+++ b/lib/src/directory_watcher/mac_os.dart
@@ -73,7 +73,7 @@
         _files = new PathSet(directory) {
     _startWatch();
 
-    _listen(new Directory(directory).list(recursive: true),
+    _listen(Chain.track(new Directory(directory).list(recursive: true)),
         (entity) {
       if (entity is! Directory) _files.add(entity.path);
     },
@@ -109,7 +109,8 @@
             continue;
           }
 
-          _listen(new Directory(path).list(recursive: true), (entity) {
+          _listen(Chain.track(new Directory(path).list(recursive: true)),
+              (entity) {
             if (entity is Directory) return;
             _emitEvent(ChangeType.ADD, entity.path);
             _files.add(entity.path);
@@ -314,8 +315,9 @@
   /// Start or restart the underlying [Directory.watch] stream.
   void _startWatch() {
     // Batch the FSEvent changes together so that we can dedup events.
-    var innerStream = new Directory(directory).watch(recursive: true).transform(
-        new BatchedStreamTransformer<FileSystemEvent>());
+    var innerStream =
+        Chain.track(new Directory(directory).watch(recursive: true))
+        .transform(new BatchedStreamTransformer<FileSystemEvent>());
     _watchSubscription = innerStream.listen(_onBatch,
         onError: _eventsController.addError,
         onDone: _onDone);
diff --git a/lib/src/directory_watcher/polling.dart b/lib/src/directory_watcher/polling.dart
index e50a0c0..684f7aa 100644
--- a/lib/src/directory_watcher/polling.dart
+++ b/lib/src/directory_watcher/polling.dart
@@ -8,6 +8,7 @@
 import 'dart:io';
 
 import 'package:crypto/crypto.dart';
+import 'package:stack_trace/stack_trace.dart';
 
 import '../async_queue.dart';
 import '../stat.dart';
@@ -105,7 +106,7 @@
       _filesToProcess.add(null);
     }
 
-    var stream = new Directory(directory).list(recursive: true);
+    var stream = Chain.track(new Directory(directory).list(recursive: true));
     _listSubscription = stream.listen((entity) {
       assert(!_events.isClosed);
 
@@ -185,7 +186,7 @@
 
   /// Calculates the SHA-1 hash of the file at [path].
   Future<List<int>> _hashFile(String path) {
-    return new File(path).readAsBytes().then((bytes) {
+    return Chain.track(new File(path).readAsBytes()).then((bytes) {
       var sha1 = new SHA1();
       sha1.add(bytes);
       return sha1.close();
diff --git a/lib/src/stat.dart b/lib/src/stat.dart
index d36eff3..166d789 100644
--- a/lib/src/stat.dart
+++ b/lib/src/stat.dart
@@ -7,6 +7,8 @@
 import 'dart:async';
 import 'dart:io';
 
+import 'package:stack_trace/stack_trace.dart';
+
 /// A function that takes a file path and returns the last modified time for
 /// the file at that path.
 typedef DateTime MockTimeCallback(String path);
@@ -29,5 +31,5 @@
     return new Future.value(_mockTimeCallback(path));
   }
 
-  return FileStat.stat(path).then((stat) => stat.modified);
+  return Chain.track(FileStat.stat(path)).then((stat) => stat.modified);
 }
diff --git a/pubspec.yaml b/pubspec.yaml
index b95c7ef..93d8eb4 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -9,6 +9,7 @@
 dependencies:
   crypto: ">=0.9.0 <0.10.0"
   path: ">=0.9.0 <0.10.0"
+  stack_trace: ">=0.9.0 <0.10.0"
 dev_dependencies:
   scheduled_test: ">=0.9.0 <0.10.0"
   unittest: ">=0.9.0 <0.10.0"