146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved. 246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)// found in the LICENSE file. 446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#ifndef CHROME_BROWSER_SYNC_FILE_SYSTEM_DRIVE_BACKEND_CALLBACK_TRACKER_H_ 646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#define CHROME_BROWSER_SYNC_FILE_SYSTEM_DRIVE_BACKEND_CALLBACK_TRACKER_H_ 746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#include <map> 946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 1046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#include "base/bind.h" 1146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#include "base/callback_forward.h" 1246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#include "base/memory/weak_ptr.h" 1346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#include "chrome/browser/sync_file_system/drive_backend/callback_tracker_internal.h" 1446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 1546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)namespace sync_file_system { 1646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)namespace drive_backend { 1746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 1846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)// A helper class to ensure one-shot callback to be called exactly once. 1946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)// 2046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)// Usage: 2146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)// class Foo { 2246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)// private: 2346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)// CallbackTracker callback_tracker_; 2446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)// }; 2546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)// 2646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)// void DoSomethingAsync(const SomeCallbackType& callback) { 2746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)// base::Closure abort_case_handler = base::Bind(callback, ABORT_ERROR); 2846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)// 2946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)// SomeCallbackType wrapped_callback = 3046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)// callback_tracker_.Register( 3146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)// abort_case_handler, callback); 3246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)// 3346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)// // The body of the operation goes here. 3446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)// } 3546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)class CallbackTracker { 3646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) public: 3746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) typedef std::map<internal::AbortHelper*, base::Closure> AbortClosureByHelper; 3846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 3946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) CallbackTracker(); 4046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) ~CallbackTracker(); 4146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 4246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // Returns a wrapped callback. 4346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // Upon AbortAll() call, CallbackTracker invokes |abort_closure| and voids all 4446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // wrapped callbacks returned by Register(). 4546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // Invocation of the wrapped callback unregisters |callback| from 4646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // CallbackTracker. 4746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) template <typename T> 4846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) base::Callback<T> Register(const base::Closure& abort_closure, 4946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) const base::Callback<T>& callback) { 5046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) internal::AbortHelper* helper = new internal::AbortHelper(this); 5146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) helpers_[helper] = abort_closure; 5246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) return base::Bind(&internal::InvokeAndInvalidateHelper<T>::Run, 5346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) helper->AsWeakPtr(), callback); 5446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) } 5546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 5646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) void AbortAll(); 5746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 5846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) private: 5946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) friend class internal::AbortHelper; 6046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 6146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) scoped_ptr<internal::AbortHelper> PassAbortHelper( 6246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) internal::AbortHelper* helper); 6346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 6446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) AbortClosureByHelper helpers_; // Owns AbortHelpers. 6546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 6646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(CallbackTracker); 6746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)}; 6846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 6946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)} // namespace drive_backend 7046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)} // namespace sync_file_system 7146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 7246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#endif // CHROME_BROWSER_SYNC_FILE_SYSTEM_DRIVE_BACKEND_CALLBACK_TRACKER_H_ 73