/*
 *  Copyright 2014 The WebRTC Project Authors. All rights reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */

#ifndef RTC_BASE_ASYNC_INVOKER_H_
#define RTC_BASE_ASYNC_INVOKER_H_

#include <atomic>
#include <memory>
#include <utility>

#include "absl/base/attributes.h"
#include "api/scoped_refptr.h"
#include "rtc_base/async_invoker_inl.h"
#include "rtc_base/constructor_magic.h"
#include "rtc_base/event.h"
#include "rtc_base/ref_counted_object.h"
#include "rtc_base/third_party/sigslot/sigslot.h"
#include "rtc_base/thread.h"

namespace rtc {

// Invokes function objects (aka functors) asynchronously on a Thread, and
// owns the lifetime of calls (ie, when this object is destroyed, calls in
// flight are cancelled). AsyncInvoker can optionally execute a user-specified
// function when the asynchronous call is complete, or operates in
// fire-and-forget mode otherwise.
//
// AsyncInvoker does not own the thread it calls functors on.
//
// A note about async calls and object lifetimes: users should
// be mindful of object lifetimes when calling functions asynchronously and
// ensure objects used by the function _cannot_ be deleted between the
// invocation and execution of the functor. AsyncInvoker is designed to
// help: any calls in flight will be cancelled when the AsyncInvoker used to
// make the call is destructed, and any calls executing will be allowed to
// complete before AsyncInvoker destructs.
//
// The easiest way to ensure lifetimes are handled correctly is to create a
// class that owns the Thread and AsyncInvoker objects, and then call its
// methods asynchronously as needed.
//
// Example:
//   class MyClass {
//    public:
//     void FireAsyncTaskWithResult(Thread* thread, int x) {
//       // Specify a callback to get the result upon completion.
//       invoker_.AsyncInvoke<int>(RTC_FROM_HERE,
//           thread, Bind(&MyClass::AsyncTaskWithResult, this, x),
//           &MyClass::OnTaskComplete, this);
//     }
//     void FireAnotherAsyncTask(Thread* thread) {
//       // No callback specified means fire-and-forget.
//       invoker_.AsyncInvoke<void>(RTC_FROM_HERE,
//           thread, Bind(&MyClass::AnotherAsyncTask, this));
//
//    private:
//     int AsyncTaskWithResult(int x) {
//       // Some long running process...
//       return x * x;
//     }
//     void AnotherAsyncTask() {
//       // Some other long running process...
//     }
//     void OnTaskComplete(int result) { result_ = result; }
//
//     AsyncInvoker invoker_;
//     int result_;
//   };
//
// More details about threading:
// - It's safe to construct/destruct AsyncInvoker on different threads.
// - It's safe to call AsyncInvoke from different threads.
// - It's safe to call AsyncInvoke recursively from *within* a functor that's
//   being AsyncInvoked.
// - However, it's *not* safe to call AsyncInvoke from *outside* a functor
//   that's being AsyncInvoked while the AsyncInvoker is being destroyed on
//   another thread. This is just inherently unsafe and there's no way to
//   prevent that. So, the user of this class should ensure that the start of
//   each "chain" of invocations is synchronized somehow with the AsyncInvoker's
//   destruction. This can be done by starting each chain of invocations on the
//   same thread on which it will be destroyed, or by using some other
//   synchronization method.
class DEPRECATED_AsyncInvoker : public MessageHandlerAutoCleanup {
 public:
  DEPRECATED_AsyncInvoker();
  ~DEPRECATED_AsyncInvoker() override;

  // Call |functor| asynchronously on |thread|, with no callback upon
  // completion. Returns immediately.
  template <class ReturnT, class FunctorT>
  void AsyncInvoke(const Location& posted_from,
                   Thread* thread,
                   FunctorT&& functor,
                   uint32_t id = 0) {
    std::unique_ptr<AsyncClosure> closure(
        new FireAndForgetAsyncClosure<FunctorT>(
            this, std::forward<FunctorT>(functor)));
    DoInvoke(posted_from, thread, std::move(closure), id);
  }

  // Call |functor| asynchronously on |thread| with |delay_ms|, with no callback
  // upon completion. Returns immediately.
  template <class ReturnT, class FunctorT>
  void AsyncInvokeDelayed(const Location& posted_from,
                          Thread* thread,
                          FunctorT&& functor,
                          uint32_t delay_ms,
                          uint32_t id = 0) {
    std::unique_ptr<AsyncClosure> closure(
        new FireAndForgetAsyncClosure<FunctorT>(
            this, std::forward<FunctorT>(functor)));
    DoInvokeDelayed(posted_from, thread, std::move(closure), delay_ms, id);
  }

  // Synchronously execute on |thread| all outstanding calls we own
  // that are pending on |thread|, and wait for calls to complete
  // before returning. Optionally filter by message id.
  // The destructor will not wait for outstanding calls, so if that
  // behavior is desired, call Flush() before destroying this object.
  void Flush(Thread* thread, uint32_t id = MQID_ANY);

  // Cancels any outstanding calls we own that are pending on any thread, and
  // which have not yet started to execute. This does not wait for any calls
  // that have already started executing to complete.
  void Clear();

 private:
  void OnMessage(Message* msg) override;
  void DoInvoke(const Location& posted_from,
                Thread* thread,
                std::unique_ptr<AsyncClosure> closure,
                uint32_t id);
  void DoInvokeDelayed(const Location& posted_from,
                       Thread* thread,
                       std::unique_ptr<AsyncClosure> closure,
                       uint32_t delay_ms,
                       uint32_t id);

  // Used to keep track of how many invocations (AsyncClosures) are still
  // alive, so that the destructor can wait for them to finish, as described in
  // the class documentation.
  //
  // TODO(deadbeef): Using a raw std::atomic like this is prone to error and
  // difficult to maintain. We should try to wrap this functionality in a
  // separate class to reduce the chance of errors being introduced in the
  // future.
  std::atomic<int> pending_invocations_;

  // Reference counted so that if the AsyncInvoker destructor finishes before
  // an AsyncClosure's destructor that's about to call
  // "invocation_complete_->Set()", it's not dereferenced after being
  // destroyed.
  rtc::Ref<Event>::Ptr invocation_complete_;

  // This flag is used to ensure that if an application AsyncInvokes tasks that
  // recursively AsyncInvoke other tasks ad infinitum, the cycle eventually
  // terminates.
  std::atomic<bool> destroying_;

  friend class AsyncClosure;

  RTC_DISALLOW_COPY_AND_ASSIGN(DEPRECATED_AsyncInvoker);
};

using AsyncInvoker ABSL_DEPRECATED("bugs.webrtc.org/12339") =
    DEPRECATED_AsyncInvoker;

}  // namespace rtc

#endif  // RTC_BASE_ASYNC_INVOKER_H_
