Home | History | Annotate | Download | only in task
      1 // Copyright 2014 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 // CancelableTaskTracker posts tasks (in the form of a Closure) to a
      6 // TaskRunner, and is able to cancel the task later if it's not needed
      7 // anymore.  On destruction, CancelableTaskTracker will cancel all
      8 // tracked tasks.
      9 //
     10 // Each cancelable task can be associated with a reply (also a Closure). After
     11 // the task is run on the TaskRunner, |reply| will be posted back to
     12 // originating TaskRunner.
     13 //
     14 // NOTE:
     15 //
     16 // CancelableCallback (base/cancelable_callback.h) and WeakPtr binding are
     17 // preferred solutions for canceling a task. However, they don't support
     18 // cancelation from another thread. This is sometimes a performance critical
     19 // requirement. E.g. We need to cancel database lookup task on DB thread when
     20 // user changes inputed text. If it is performance critical to do a best effort
     21 // cancelation of a task, then CancelableTaskTracker is appropriate,
     22 // otherwise use one of the other mechanisms.
     23 //
     24 // THREAD-SAFETY:
     25 //
     26 // 1. CancelableTaskTracker objects are not thread safe. They must
     27 // be created, used, and destroyed on the originating thread that posts the
     28 // task. It's safe to destroy a CancelableTaskTracker while there
     29 // are outstanding tasks. This is commonly used to cancel all outstanding
     30 // tasks.
     31 //
     32 // 2. Both task and reply are deleted on the originating thread.
     33 //
     34 // 3. IsCanceledCallback is thread safe and can be run or deleted on any
     35 // thread.
     36 #ifndef BASE_TASK_CANCELABLE_TASK_TRACKER_H_
     37 #define BASE_TASK_CANCELABLE_TASK_TRACKER_H_
     38 
     39 #include "base/base_export.h"
     40 #include "base/basictypes.h"
     41 #include "base/callback.h"
     42 #include "base/containers/hash_tables.h"
     43 #include "base/memory/weak_ptr.h"
     44 #include "base/threading/thread_checker.h"
     45 
     46 namespace tracked_objects {
     47 class Location;
     48 }  // namespace tracked_objects
     49 
     50 namespace base {
     51 
     52 class CancellationFlag;
     53 class TaskRunner;
     54 
     55 class BASE_EXPORT CancelableTaskTracker {
     56  public:
     57   // All values except kBadTaskId are valid.
     58   typedef int64 TaskId;
     59   static const TaskId kBadTaskId;
     60 
     61   typedef base::Callback<bool()> IsCanceledCallback;
     62 
     63   CancelableTaskTracker();
     64 
     65   // Cancels all tracked tasks.
     66   ~CancelableTaskTracker();
     67 
     68   TaskId PostTask(base::TaskRunner* task_runner,
     69                   const tracked_objects::Location& from_here,
     70                   const base::Closure& task);
     71 
     72   TaskId PostTaskAndReply(base::TaskRunner* task_runner,
     73                           const tracked_objects::Location& from_here,
     74                           const base::Closure& task,
     75                           const base::Closure& reply);
     76 
     77   // Creates a tracked TaskId and an associated IsCanceledCallback. Client can
     78   // later call TryCancel() with the returned TaskId, and run |is_canceled_cb|
     79   // from any thread to check whether the TaskId is canceled.
     80   //
     81   // The returned task ID is tracked until the last copy of
     82   // |is_canceled_cb| is destroyed.
     83   //
     84   // Note. This function is used to address some special cancelation requirement
     85   // in existing code. You SHOULD NOT need this function in new code.
     86   TaskId NewTrackedTaskId(IsCanceledCallback* is_canceled_cb);
     87 
     88   // After calling this function, |task| and |reply| will not run. If the
     89   // cancelation happens when |task| is running or has finished running, |reply|
     90   // will not run. If |reply| is running or has finished running, cancellation
     91   // is a noop.
     92   //
     93   // Note. It's OK to cancel a |task| for more than once. The later calls are
     94   // noops.
     95   void TryCancel(TaskId id);
     96 
     97   // It's OK to call this function for more than once. The later calls are
     98   // noops.
     99   void TryCancelAll();
    100 
    101   // Returns true iff there are in-flight tasks that are still being
    102   // tracked.
    103   bool HasTrackedTasks() const;
    104 
    105  private:
    106   void Track(TaskId id, base::CancellationFlag* flag);
    107   void Untrack(TaskId id);
    108 
    109   base::hash_map<TaskId, base::CancellationFlag*> task_flags_;
    110   base::WeakPtrFactory<CancelableTaskTracker> weak_factory_;
    111 
    112   TaskId next_id_;
    113   base::ThreadChecker thread_checker_;
    114 
    115   DISALLOW_COPY_AND_ASSIGN(CancelableTaskTracker);
    116 };
    117 
    118 }  // namespace base
    119 
    120 #endif  // BASE_TASK_CANCELABLE_TASK_TRACKER_H_
    121