Separate Simple Backend creation from initialization.
[chromium-blink-merge.git] / third_party / tcmalloc / chromium / src / windows / auto_testing_hook.h
blob5a047977395e2b484c8afe3478ec3443048fd48c
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved.
2 //
3 // Redistribution and use in source and binary forms, with or without
4 // modification, are permitted provided that the following conditions are
5 // met:
6 //
7 // * Redistributions of source code must retain the above copyright
8 // notice, this list of conditions and the following disclaimer.
9 // * Redistributions in binary form must reproduce the above
10 // copyright notice, this list of conditions and the following disclaimer
11 // in the documentation and/or other materials provided with the
12 // distribution.
13 // * Neither the name of Google Inc. nor the names of its
14 // contributors may be used to endorse or promote products derived from
15 // this software without specific prior written permission.
17 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
20 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
21 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
23 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 // Utility for using SideStep with unit tests.
31 #ifndef CEEE_TESTING_SIDESTEP_AUTO_TESTING_HOOK_H_
32 #define CEEE_TESTING_SIDESTEP_AUTO_TESTING_HOOK_H_
34 #include "base/basictypes.h"
35 #include "base/logging.h"
36 #include "preamble_patcher.h"
38 #define SIDESTEP_CHK(x) CHECK(x)
39 #define SIDESTEP_EXPECT_TRUE(x) SIDESTEP_CHK(x)
41 namespace sidestep {
43 // Same trick as common/scope_cleanup.h ScopeGuardImplBase
44 class AutoTestingHookBase {
45 public:
46 virtual ~AutoTestingHookBase() {}
49 // This is the typedef you normally use for the class, e.g.
51 // AutoTestingHook hook = MakeTestingHook(TargetFunc, HookTargetFunc);
53 // The 'hook' variable will then be destroyed when it goes out of scope.
55 // NOTE: You must not hold this type as a member of another class. Its
56 // destructor will not get called.
57 typedef const AutoTestingHookBase& AutoTestingHook;
59 // This is the class you must use when holding a hook as a member of another
60 // class, e.g.
62 // public:
63 // AutoTestingHookHolder holder_;
64 // MyClass() : my_hook_holder(MakeTestingHookHolder(Target, Hook)) {}
65 class AutoTestingHookHolder {
66 public:
67 explicit AutoTestingHookHolder(AutoTestingHookBase* hook) : hook_(hook) {}
68 ~AutoTestingHookHolder() { delete hook_; }
69 private:
70 AutoTestingHookHolder() {} // disallow
71 AutoTestingHookBase* hook_;
74 // This class helps patch a function, then unpatch it when the object exits
75 // scope, and also maintains the pointer to the original function stub.
77 // To enable use of the class without having to explicitly provide the
78 // type of the function pointers (and instead only providing it
79 // implicitly) we use the same trick as ScopeGuard (see
80 // common/scope_cleanup.h) uses, so to create a hook you use the MakeHook
81 // function rather than a constructor.
83 // NOTE: This function is only safe for e.g. unit tests and _not_ for
84 // production code. See PreamblePatcher class for details.
85 template <typename T>
86 class AutoTestingHookImpl : public AutoTestingHookBase {
87 public:
88 static AutoTestingHookImpl<T> MakeTestingHook(T target_function,
89 T replacement_function,
90 bool do_it) {
91 return AutoTestingHookImpl<T>(target_function, replacement_function, do_it);
94 static AutoTestingHookImpl<T>* MakeTestingHookHolder(T target_function,
95 T replacement_function,
96 bool do_it) {
97 return new AutoTestingHookImpl<T>(target_function,
98 replacement_function, do_it);
101 ~AutoTestingHookImpl() {
102 if (did_it_) {
103 SIDESTEP_CHK(SIDESTEP_SUCCESS == PreamblePatcher::Unpatch(
104 (void*)target_function_, (void*)replacement_function_,
105 (void*)original_function_));
109 // Returns a pointer to the original function. To use this method you will
110 // have to explicitly create an AutoTestingHookImpl of the specific
111 // function pointer type (i.e. not use the AutoTestingHook typedef).
112 T original_function() {
113 return original_function_;
116 private:
117 AutoTestingHookImpl(T target_function, T replacement_function, bool do_it)
118 : target_function_(target_function),
119 original_function_(NULL),
120 replacement_function_(replacement_function),
121 did_it_(do_it) {
122 if (do_it) {
123 SIDESTEP_CHK(SIDESTEP_SUCCESS == PreamblePatcher::Patch(target_function,
124 replacement_function,
125 &original_function_));
129 T target_function_; // always valid
130 T original_function_; // always valid
131 T replacement_function_; // always valid
132 bool did_it_; // Remember if we did it or not...
135 template <typename T>
136 inline AutoTestingHookImpl<T> MakeTestingHook(T target,
137 T replacement,
138 bool do_it) {
139 return AutoTestingHookImpl<T>::MakeTestingHook(target, replacement, do_it);
142 template <typename T>
143 inline AutoTestingHookImpl<T> MakeTestingHook(T target, T replacement) {
144 return AutoTestingHookImpl<T>::MakeTestingHook(target, replacement, true);
147 template <typename T>
148 inline AutoTestingHookImpl<T>* MakeTestingHookHolder(T target, T replacement) {
149 return AutoTestingHookImpl<T>::MakeTestingHookHolder(target, replacement,
150 true);
153 }; // namespace sidestep
155 #endif // CEEE_TESTING_SIDESTEP_AUTO_TESTING_HOOK_H_