blob: ec1935d1e42febcca0a70c8115ccd6decd8f58a1 [file] [log] [blame]
// Copyright (c) 2015, 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.
library http2.src.error_handler;
import 'dart:async';
import 'sync_errors.dart';
/// Used by classes which may be terminated from the outside.
class TerminatableMixin {
bool _terminated = false;
/// Terminates this stream message queue. Further operations on it will fail.
void terminate([error]) {
if (!wasTerminated) {
_terminated = true;
onTerminated(error);
}
}
bool get wasTerminated => _terminated;
void onTerminated(error) {
// Subclasses can override this method if they want.
}
T ensureNotTerminatedSync<T>(T f()) {
if (wasTerminated) {
throw new TerminatedException();
}
return f();
}
Future ensureNotTerminatedAsync(Future f()) {
if (wasTerminated) {
return new Future.error(new TerminatedException());
}
return f();
}
}
/// Used by classes which may be cancelled.
class CancellableMixin {
bool _cancelled = false;
final _cancelCompleter = new Completer<void>.sync();
Future<void> get onCancel => _cancelCompleter.future;
/// Cancel this stream message queue. Further operations on it will fail.
void cancel() {
if (!wasCancelled) {
_cancelled = true;
_cancelCompleter.complete();
}
}
bool get wasCancelled => _cancelled;
}
/// Used by classes which may be closed.
class ClosableMixin {
bool _closing = false;
final Completer _completer = new Completer();
Future get done => _completer.future;
bool get isClosing => _closing;
bool get wasClosed => _completer.isCompleted;
void startClosing() {
if (!_closing) {
_closing = true;
onClosing();
}
onCheckForClose();
}
void onCheckForClose() {
// Subclasses can override this method if they want.
}
void onClosing() {
// Subclasses can override this method if they want.
}
dynamic ensureNotClosingSync(f()) {
if (isClosing) {
throw new StateError('Was in the process of closing.');
}
return f();
}
void closeWithValue([value]) {
if (!wasClosed) {
_completer.complete(value);
}
}
void closeWithError(error) {
if (!wasClosed) {
_completer.complete(error);
}
}
}