| OLD | NEW |
| (Empty) |
| 1 // Copyright 2016 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 BLIMP_COMMON_MANDATORY_CALLBACK_H_ | |
| 6 #define BLIMP_COMMON_MANDATORY_CALLBACK_H_ | |
| 7 | |
| 8 #include <utility> | |
| 9 | |
| 10 #include "base/callback.h" | |
| 11 #include "base/logging.h" | |
| 12 | |
| 13 namespace blimp { | |
| 14 | |
| 15 // Adds a leak-detection wrapper to base::Callback objects. | |
| 16 // | |
| 17 // When a wrapped Callback is destroyed without being Run first, the checker | |
| 18 // will DCHECK-crash the program with a stack trace, so that developers can | |
| 19 // pinpoint the site of the leak. | |
| 20 // | |
| 21 // The MandatoryCallback may be passed using std::move; leak detection occurs | |
| 22 // when the MandatoryCallback is finally destroyed. | |
| 23 // | |
| 24 // Usage: | |
| 25 // void DoStuff(int d) { ... } | |
| 26 // ... | |
| 27 // base::Closure my_callback = base::Bind(&DoStuff); | |
| 28 // MandatoryCallback<void(int)> leak_checked_callback = | |
| 29 // CreateMandatoryCallback(my_callback); | |
| 30 // | |
| 31 // Note that MandatoryCallbacks lack some functionality from | |
| 32 // base::CallbackInternal. | |
| 33 // * They can only be invoked once. | |
| 34 // * They do not support parameter currying with additional Bind() calls.[1] | |
| 35 // * They cannot be Reset(). | |
| 36 // | |
| 37 // [1] Mandatory invocation support would need to be plumbed in to | |
| 38 // base::CallbackInternal and base::Bind for this to work, | |
| 39 // which is feasible but low-priority for the owners of the callback | |
| 40 // libraries. | |
| 41 | |
| 42 template <typename SignatureType> | |
| 43 class MandatoryCallback; | |
| 44 | |
| 45 // Template specialization for extracting the function signature data types. | |
| 46 template <typename ReturnType, typename... ArgTypes> | |
| 47 class MandatoryCallback<ReturnType(ArgTypes...)> { | |
| 48 public: | |
| 49 using CallbackType = base::Callback<ReturnType(ArgTypes...)>; | |
| 50 | |
| 51 explicit MandatoryCallback(const CallbackType& callback) : cb_(callback) { | |
| 52 DCHECK(!cb_.is_null()); | |
| 53 } | |
| 54 | |
| 55 MandatoryCallback(MandatoryCallback&& other) { | |
| 56 cb_ = other.cb_; | |
| 57 other.cb_.Reset(); | |
| 58 | |
| 59 #if DCHECK_IS_ON() | |
| 60 was_run_ = other.was_run_; | |
| 61 other.was_run_ = false; | |
| 62 #endif | |
| 63 } | |
| 64 | |
| 65 ~MandatoryCallback() { | |
| 66 #if DCHECK_IS_ON() | |
| 67 DCHECK(cb_.is_null() || was_run_); | |
| 68 #endif | |
| 69 } | |
| 70 | |
| 71 // This a overload that handles the case where there are no arguments provided | |
| 72 template <typename...> | |
| 73 ReturnType Run() { | |
| 74 DCHECK(cb_); // Can't be run following std::move. | |
| 75 | |
| 76 #if DCHECK_IS_ON() | |
| 77 DCHECK(!was_run_); | |
| 78 was_run_ = true; | |
| 79 #endif | |
| 80 | |
| 81 cb_.Run(); | |
| 82 } | |
| 83 | |
| 84 template <typename... RunArgs> | |
| 85 ReturnType Run(RunArgs... args) { | |
| 86 DCHECK(cb_); // Can't be run following std::move. | |
| 87 | |
| 88 #if DCHECK_IS_ON() | |
| 89 DCHECK(!was_run_); | |
| 90 was_run_ = true; | |
| 91 #endif | |
| 92 | |
| 93 cb_.Run(std::forward<RunArgs...>(args...)); | |
| 94 } | |
| 95 | |
| 96 private: | |
| 97 // Nulled after being moved. | |
| 98 CallbackType cb_; | |
| 99 | |
| 100 #if DCHECK_IS_ON() | |
| 101 bool was_run_ = false; | |
| 102 #endif | |
| 103 | |
| 104 DISALLOW_COPY_AND_ASSIGN(MandatoryCallback); | |
| 105 }; | |
| 106 | |
| 107 // Creates a leak-checking proxy callback around |callback|. | |
| 108 template <typename SignatureType> | |
| 109 MandatoryCallback<SignatureType> CreateMandatoryCallback( | |
| 110 const base::Callback<SignatureType>& callback) { | |
| 111 return MandatoryCallback<SignatureType>(callback); | |
| 112 } | |
| 113 | |
| 114 using MandatoryClosure = MandatoryCallback<void()>; | |
| 115 | |
| 116 } // namespace blimp | |
| 117 | |
| 118 #endif // BLIMP_COMMON_MANDATORY_CALLBACK_H_ | |
| OLD | NEW |