Home | History | Annotate | Download | only in drive_backend
      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 #ifndef CHROME_BROWSER_SYNC_FILE_SYSTEM_DRIVE_BACKEND_CALLBACK_TRACKER_H_
      6 #define CHROME_BROWSER_SYNC_FILE_SYSTEM_DRIVE_BACKEND_CALLBACK_TRACKER_H_
      7 
      8 #include <map>
      9 
     10 #include "base/bind.h"
     11 #include "base/callback_forward.h"
     12 #include "base/memory/weak_ptr.h"
     13 #include "chrome/browser/sync_file_system/drive_backend/callback_tracker_internal.h"
     14 
     15 namespace sync_file_system {
     16 namespace drive_backend {
     17 
     18 // A helper class to ensure one-shot callback to be called exactly once.
     19 //
     20 // Usage:
     21 //   class Foo {
     22 //    private:
     23 //     CallbackTracker callback_tracker_;
     24 //   };
     25 //
     26 //   void DoSomethingAsync(const SomeCallbackType& callback) {
     27 //     base::Closure abort_case_handler = base::Bind(callback, ABORT_ERROR);
     28 //
     29 //     SomeCallbackType wrapped_callback =
     30 //         callback_tracker_.Register(
     31 //             abort_case_handler, callback);
     32 //
     33 //     // The body of the operation goes here.
     34 //   }
     35 class CallbackTracker {
     36  public:
     37   typedef std::map<internal::AbortHelper*, base::Closure> AbortClosureByHelper;
     38 
     39   CallbackTracker();
     40   ~CallbackTracker();
     41 
     42   // Returns a wrapped callback.
     43   // Upon AbortAll() call, CallbackTracker invokes |abort_closure| and voids all
     44   // wrapped callbacks returned by Register().
     45   // Invocation of the wrapped callback unregisters |callback| from
     46   // CallbackTracker.
     47   template <typename T>
     48   base::Callback<T> Register(const base::Closure& abort_closure,
     49                              const base::Callback<T>& callback) {
     50     internal::AbortHelper* helper = new internal::AbortHelper(this);
     51     helpers_[helper] = abort_closure;
     52     return base::Bind(&internal::InvokeAndInvalidateHelper<T>::Run,
     53                       helper->AsWeakPtr(), callback);
     54   }
     55 
     56   void AbortAll();
     57 
     58  private:
     59   friend class internal::AbortHelper;
     60 
     61   scoped_ptr<internal::AbortHelper> PassAbortHelper(
     62       internal::AbortHelper* helper);
     63 
     64   AbortClosureByHelper helpers_;  // Owns AbortHelpers.
     65 
     66   DISALLOW_COPY_AND_ASSIGN(CallbackTracker);
     67 };
     68 
     69 }  // namespace drive_backend
     70 }  // namespace sync_file_system
     71 
     72 #endif  // CHROME_BROWSER_SYNC_FILE_SYSTEM_DRIVE_BACKEND_CALLBACK_TRACKER_H_
     73