blob: 3e44b8c8fb4f8da07d5fe981d18fcc8283aa8034 [file] [log] [blame]
// Copyright (c) 2017, 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.
import 'dart:async';
import 'dart:io';
/// Fires [shouldTerminate] once a `SIGINT` is intercepted.
///
/// The `SIGINT` stream can optionally be replaced with another Stream in the
/// constructor. [cancel] should be called after work is finished. If multiple
/// events are receieved on the terminate event stream before work is finished
/// the process will be terminated with [exit].
class Terminator {
/// A Future that fires when a signal has been received indicating that builds
/// should stop.
final Future shouldTerminate;
final StreamSubscription _subscription;
factory Terminator([Stream terminateEventStream]) {
var shouldTerminate = Completer<void>();
terminateEventStream ??= ProcessSignal.sigint.watch();
var numEventsSeen = 0;
var terminateListener = terminateEventStream.listen((_) {
numEventsSeen++;
if (numEventsSeen == 1) {
shouldTerminate.complete();
} else {
exit(2);
}
});
return Terminator._(shouldTerminate.future, terminateListener);
}
Terminator._(this.shouldTerminate, this._subscription);
Future cancel() => _subscription.cancel();
}