blob: b5f61f2a2cfb76529eca5972592a4dada06b38b7 [file] [log] [blame]
// Copyright 2018 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef LIB_CALLBACK_CANCELLABLE_H_
#define LIB_CALLBACK_CANCELLABLE_H_
#include <set>
#include <lib/fit/function.h>
#include "lib/callback/auto_cleanable.h"
#include "lib/fxl/macros.h"
#include "lib/fxl/memory/ref_counted.h"
#include "lib/fxl/memory/ref_ptr.h"
namespace callback {
class AutoCancel;
// Cancellable can be used by any service that starts an asynchronous task to
// allow clients to cancel the operation. The contract is the following: When
// the client calls |Cancel|, the service should interrupt the asynchronous
// task, in particular, the service must not call any completion callbacks once
// the client called |Cancel|.
// If the client calls |Cancel|, or when the service calls any completion
// callbacks, the |IsDone| method must return |true|.
class Cancellable : public fxl::RefCountedThreadSafe<Cancellable> {
public:
virtual void Cancel() = 0;
virtual bool IsDone() = 0;
protected:
Cancellable();
virtual ~Cancellable();
// The client can call the |SetOnDone| method once before the cancellable is
// done. If the |OnDone| method has been called, the service must call the
// |callback| after having called any completion callbacks. It must not call
// the callback if the |Cancel| method has been called.
virtual void SetOnDone(fit::closure callback) = 0;
private:
friend AutoCancel;
FRIEND_REF_COUNTED_THREAD_SAFE(Cancellable);
};
// RAII container for a single |Cancellable|. The |Cancellable| will be canceled
// when this object is deleted.
class AutoCancel {
public:
explicit AutoCancel(fxl::RefPtr<Cancellable> cancellable = nullptr);
~AutoCancel();
// Cancels any wrapped |Cancellable|s and starts wrapping |cancellable|.
void Reset(fxl::RefPtr<Cancellable> cancellable = nullptr);
// The client can call the |set_on_empty| method once. |callback| will then be
// executed when the underlying |Cancellable| finishes.
void set_on_empty(fit::closure callback);
private:
void OnDone();
fxl::RefPtr<Cancellable> cancellable_;
fit::closure on_empty_;
FXL_DISALLOW_COPY_AND_ASSIGN(AutoCancel);
};
// RAII container for multiple |Cancellable|s. The |Cancellable|s will be
// canceled when this object is deleted. The |Cancellable| objects will also be
// deleted when they complete.
using CancellableContainer = AutoCleanableSet<AutoCancel>;
} // namespace callback
#endif // LIB_CALLBACK_CANCELLABLE_H_