| OLD | NEW |
| (Empty) |
| 1 // Copyright (c) 2006-2009 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 // Callback classes provides a generic interface for classes requiring | |
| 6 // callback from other classes. | |
| 7 // We support callbacks with 0, 1, 2, 3, and 4 arguments. | |
| 8 // Closure -- provides "void Run()" | |
| 9 // Callback1<T1> -- provides "void Run(T1)" | |
| 10 // Callback2<T1,T2> -- provides "void Run(T1, T2)" | |
| 11 // Callback3<T1,T2,T3> -- provides "void Run(T1, T2, T3)" | |
| 12 // Callback4<T1,T2,T3,T4> -- provides "void Run(T1, T2, T3, T4)" | |
| 13 // | |
| 14 // In addition, ResultCallback classes provide a generic interface for | |
| 15 // callbacks that return a value. | |
| 16 // ResultCallback<R> -- provides "R Run()" | |
| 17 // ResultCallback1<R,T1> -- provides "R Run(T1)" | |
| 18 // ResultCallback2<R,T1,T2> -- provides "R Run(T1, T2)" | |
| 19 // ResultCallback3<R,T1,T2,T3> -- provides "R Run(T1, T2, T3)" | |
| 20 // ResultCallback4<R,T1,T2,T3,T4> -- provides "R Run(T1, T2, T3, T4)" | |
| 21 | |
| 22 // We provide a convenient mechanism, NewCallback, for generating one of these | |
| 23 // callbacks given an object pointer, a pointer to a member | |
| 24 // function with the appropriate signature in that object's class, | |
| 25 // and some optional arguments that can be bound into the callback | |
| 26 // object. The mechanism also works with just a function pointer. | |
| 27 // | |
| 28 // Note: there are two types of arguments passed to the callback method: | |
| 29 // * "pre-bound arguments" - supplied when the callback object is created | |
| 30 // * "call-time arguments" - supplied when the callback object is invoked | |
| 31 // | |
| 32 // These two types correspond to "early binding" and "late | |
| 33 // binding". An argument whose value is known when the callback is | |
| 34 // created ("early") can be pre-bound (a.k.a. "Curried"), You can | |
| 35 // combine pre-bound and call-time arguments in different ways. For | |
| 36 // example, invoking a callback with 3 pre-bound arguments and 1 | |
| 37 // call-time argument will have the same effect as invoking a callback | |
| 38 // with 2 pre-bound arguments and 2 call-time arguments, or 4 | |
| 39 // pre-bound arguments and no call-time arguments. This last case is | |
| 40 // often useful; a callback with no call-time arguments is a Closure; | |
| 41 // these are used in many places in the Google libraries, e.g., "done" | |
| 42 // closures. See the examples below. | |
| 43 // | |
| 44 // WARNING: In the current implementation (or perhaps with the current | |
| 45 // compiler) NewCallback() is pickier about the types of pre-bound arguments | |
| 46 // than you might expect. The types must match exactly, rather than merely | |
| 47 // being compatible. | |
| 48 // For example, if you pre-bind an argument with the "const" specifier, | |
| 49 // make sure that the actual parameter passed to NewCallback also has the | |
| 50 // const specifier. If you don't you'll get an error about | |
| 51 // passing a your function "as argument 1 of NewCallback(void (*)())". | |
| 52 // Using a method or function that has reference arguments among its pre-bound | |
| 53 // arguments may not always work. | |
| 54 // | |
| 55 // Examples: | |
| 56 // | |
| 57 // void Call0(Closure* cb) { cb->Run(); } | |
| 58 // void Call1(Callback1<int>* cb, int a) { cb->Run(a); } | |
| 59 // void Call2(Callback2<int, float>* cb, int a, float f) { cb->Run(a, f); } | |
| 60 // float Call3(ResultCallback1<float, int>* cb, int a) { return cb->Run(a); } | |
| 61 // | |
| 62 // class Foo { | |
| 63 // public: | |
| 64 // void A(int a); | |
| 65 // void B(int a, float f); | |
| 66 // void C(const char* label, int a, float f); | |
| 67 // float D(int a); | |
| 68 // }; | |
| 69 // void F0(int a); | |
| 70 // void F1(int a, float f); | |
| 71 // void F2(const char *label, int a, float f); | |
| 72 // float F3(int a); | |
| 73 // float v; | |
| 74 // | |
| 75 // // Run stuff immediately | |
| 76 // // calling a method | |
| 77 // Foo* foo = new Foo; | |
| 78 // | |
| 79 // NewCallback(foo, &Foo::A) ->Run(10); // 0 [pre-bound] + 1 [call-tim
e] | |
| 80 // == NewCallback(foo, &Foo::A, 10) ->Run(); // 1 + 0 | |
| 81 // == foo->A(10); | |
| 82 // | |
| 83 // NewCallback(foo, &Foo::B) ->Run(10, 3.0f); // 0 + 2 | |
| 84 // == NewCallback(foo, &Foo::B, 10) ->Run(3.0f); // 1 + 1 | |
| 85 // == NewCallback(foo, &Foo::B, 10, 3.0f) ->Run(); // 2 + 0 | |
| 86 // == foo->B(10, 3.0f); | |
| 87 // | |
| 88 // NewCallback(foo, &Foo::C) ->Run("Y", 10, 3.0f); // 0 + 3 | |
| 89 // == NewCallback(foo, &Foo::C, "Y") ->Run(10, 3.0f); // 1 + 2 | |
| 90 // == NewCallback(foo, &Foo::C, "Y", 10) ->Run(3.0f); // 2 + 1 | |
| 91 // == NewCallback(foo, &Foo::C, "Y", 10, 3.0f) ->Run(); // 3 + 0 | |
| 92 // == foo->C("Y", 10, 3.0f); | |
| 93 // | |
| 94 // v = NewCallback(foo, &Foo::D) ->Run(10); == v = foo->D(10) | |
| 95 // | |
| 96 // // calling a function | |
| 97 // NewCallback(F0) ->Run(10); // == F0(10) // 0 + 1 | |
| 98 // NewCallback(F0, 10) ->Run(); // == F0(10) // 1 + 0 | |
| 99 // NewCallback(F1) ->Run(10, 3.0f); // == F1(10, 3.0f) | |
| 100 // NewCallback(F2, "X") ->Run(10, 3.0f); // == F2("X", 10, 3.0f) | |
| 101 // NewCallback(F2, "Y") ->Run(10, 3.0f); // == F2("Y", 10, 3.0f) | |
| 102 // v = NewCallback(F3) ->Run(10); // == v = F3(10) | |
| 103 // | |
| 104 // | |
| 105 // // Pass callback object to somebody else, who runs it. | |
| 106 // // Calling a method: | |
| 107 // Call1(NewCallback(foo, &Foo::A), 10); // 0 + 1 | |
| 108 // == Call0(NewCallback(foo, &Foo::A, 10) ); // 1 + 0 | |
| 109 // == foo->A(10) | |
| 110 // | |
| 111 // Call2(NewCallback(foo, &Foo::B), 10, 3.0f); // 0 + 2 | |
| 112 // == Call1(NewCallback(foo, &Foo::B, 10), 3.0f); // 1 + 1 | |
| 113 // == Call0(NewCallback(foo, &Foo::B, 10, 30.f) ); // 2 + 0 | |
| 114 // == foo->B(10, 3.0f) | |
| 115 // | |
| 116 // Call2(NewCallback(foo, &Foo::C, "X"), 10, 3.0f); == foo->C("X", 10, 3.0f) | |
| 117 // Call2(NewCallback(foo, &Foo::C, "Y"), 10, 3.0f); == foo->C("Y", 10, 3.0f) | |
| 118 // | |
| 119 // // Calling a function: | |
| 120 // Call1(NewCallback(F0), 10); // 0 + 1 | |
| 121 // == Call0(NewCallback(F0, 10) ); // 1 + 0 | |
| 122 // == F0(10); | |
| 123 // | |
| 124 // Call2(NewCallback(F1), 10, 3.0f); // == F1(10, 3.0f) | |
| 125 // Call2(NewCallback(F2, "X"), 10, 3.0f); // == F2("X", 10, 3.0f) | |
| 126 // Call2(NewCallback(F2, "Y"), 10, 3.0f); // == F2("Y", 10, 3.0f) | |
| 127 // v = Call3(NewCallback(F3), 10); // == v = F3(10) | |
| 128 // | |
| 129 // Example of a "done" closure: | |
| 130 // | |
| 131 // SelectServer ss; | |
| 132 // Closure* done = NewCallback(&ss, &SelectServer::MakeLoopExit); | |
| 133 // ProcessMyControlFlow(..., done); | |
| 134 // ss.Loop(); | |
| 135 // ... | |
| 136 // | |
| 137 // The following WILL NOT WORK: | |
| 138 // NewCallback(F2, (char *) "Y") ->Run(10, 3.0f); | |
| 139 // It gets the error: | |
| 140 // passing `void (*)(const char *, int, float)' as argument 1 of | |
| 141 // `NewCallback(void (*)())' | |
| 142 // The problem is that "char *" is not an _exact_ match for | |
| 143 // "const char *", even though it's normally a legal implicit | |
| 144 // conversion. | |
| 145 // | |
| 146 // | |
| 147 // The callback objects generated by NewCallback are self-deleting: | |
| 148 // i.e., they call the member function, and then delete themselves. | |
| 149 // If you want a callback that does not delete itself every time | |
| 150 // it runs, use "NewPermanentCallback" instead of "NewCallback". | |
| 151 // | |
| 152 // All the callback/closure classes also provide | |
| 153 // virtual void CheckIsRepeatable() const; | |
| 154 // It crashes if (we know for sure that) the callback's Run method | |
| 155 // can not be called an arbitrary number of times (including 0). | |
| 156 // It crashes for all NewCallback() generated callbacks, | |
| 157 // does not crash for NewPermanentCallback() generated callbacks, | |
| 158 // and although by default it does not crash for all callback-derived classes, | |
| 159 // for these new types of callbacks, the callback writer is encouraged to | |
| 160 // redefine this method appropriately. | |
| 161 // | |
| 162 // CAVEAT: Interfaces that accept callback pointers should clearly document | |
| 163 // if they might call Run methods of those callbacks multiple times | |
| 164 // (and use "c->CheckIsRepeatable();" as an active precondition check), | |
| 165 // or if they call the callbacks exactly once or potentially not at all, | |
| 166 // as well as if they take ownership of the passed callbacks | |
| 167 // (i.e. might manually deallocate them without calling their Run methods). | |
| 168 // The clients can then provide properly allocated and behaving callbacks | |
| 169 // (e.g. choose between NewCallback, NewPermanentCallback, or a custom object). | |
| 170 // Obviously, one should also be careful to ensure that the data a callback | |
| 171 // points to and needs for its Run method is still live when | |
| 172 // the Run method might be called. | |
| 173 // | |
| 174 // MOTIVATION FOR CALLBACK OBJECTS | |
| 175 // ------------------------------- | |
| 176 // It frees service providers from depending on service requestors by | |
| 177 // calling a generic callback other than a callback which depends on | |
| 178 // the service requestor (typically its member function). As a | |
| 179 // result, service provider classes can be developed independently. | |
| 180 // | |
| 181 // Typical usage: Suppose class A wants class B to do something and | |
| 182 // notify A when it is done. As part of the notification, it wants | |
| 183 // to be given a boolean that says what happened. | |
| 184 // | |
| 185 // class A { | |
| 186 // public: | |
| 187 // void RequestService(B* server) { | |
| 188 // ... | |
| 189 // server->StartService(NewCallback(this, &A::ServiceDone), other_args)); | |
| 190 // // the new callback deletes itself after it runs | |
| 191 // } | |
| 192 // void ServiceDone(bool status) {...} | |
| 193 // }; | |
| 194 // | |
| 195 // Class B { | |
| 196 // public: | |
| 197 // void StartService(Callback1<bool>* cb, other_args) : cb_(cb) { ...} | |
| 198 // void FinishService(bool result) { ...; cb_->Run(result); } | |
| 199 // private: | |
| 200 // Callback1<bool>* cb_; | |
| 201 // }; | |
| 202 // | |
| 203 // As can be seen, B is completely independent of A. (Of course, they | |
| 204 // have to agree on callback data type.) | |
| 205 // | |
| 206 // The result of NewCallback() is thread-compatible. The result of | |
| 207 // NewPermanentCallback() is thread-safe if the call its Run() method | |
| 208 // represents is thread-safe and thread-compatible otherwise. | |
| 209 // | |
| 210 // Other modules associated with callbacks may be found in //util/callback | |
| 211 // | |
| 212 // USING CALLBACKS WITH TRACECONTEXT | |
| 213 // --------------------------------- | |
| 214 // Callbacks generated by NewCallback() automatically propagate trace | |
| 215 // context. Callbacks generated by NewPermanentCallback() do not. For | |
| 216 // manually-derived subclasses of Closure and CallbackN, you may decide | |
| 217 // to propagate TraceContext as follows. | |
| 218 // | |
| 219 // struct MyClosure : public Closure { | |
| 220 // MyClosure() | |
| 221 // : Closure(TraceContext::THREAD) { } | |
| 222 // | |
| 223 // void Run() { | |
| 224 // TraceContext *tc = TraceContext::Thread(); | |
| 225 // tc->Swap(&trace_context_); | |
| 226 // DoMyOperation() | |
| 227 // tc->Swap(&trace_context_); | |
| 228 // delete this; | |
| 229 // } | |
| 230 // }; | |
| 231 | |
| 232 #ifndef _CALLBACK_H_ | |
| 233 #define _CALLBACK_H_ | |
| 234 | |
| 235 #include <functional> | |
| 236 | |
| 237 // The actual callback classes and various NewCallback() implementations | |
| 238 // are automatically generated by base/generate-callback-specializations.py. | |
| 239 // We include that output here. | |
| 240 #include "base/callback-specializations.h" | |
| 241 | |
| 242 // A new barrier closure executes another closure after it has been | |
| 243 // invoked N times, and then deletes itself. | |
| 244 // | |
| 245 // If "N" is zero, the supplied closure is executed immediately. | |
| 246 // Barrier closures are thread-safe. They use an atomic operation to | |
| 247 // guarantee a correct count. | |
| 248 // | |
| 249 // REQUIRES N >= 0. | |
| 250 extern Closure* NewBarrierClosure(int N, Closure* done_closure); | |
| 251 | |
| 252 // Function that does nothing; can be used to make new no-op closures: | |
| 253 // NewCallback(&DoNothing) | |
| 254 // NewPermanentCallback(&DoNothing) | |
| 255 // This is a replacement for the formerly available TheNoopClosure() primitive. | |
| 256 extern void DoNothing(); | |
| 257 | |
| 258 // AutoClosureRunner executes a closure upon deletion. This class | |
| 259 // is similar to scoped_ptr: it is typically stack-allocated and can be | |
| 260 // used to perform some type of cleanup upon exiting a block. | |
| 261 // | |
| 262 // Note: use of AutoClosureRunner with Closures that must be executed at | |
| 263 // specific points is discouraged, since the point at which the Closure | |
| 264 // executes is not explicitly marked. For example, consider a Closure | |
| 265 // that should execute after a mutex has been released. The following | |
| 266 // code looks correct, but executes the Closure too early (before release): | |
| 267 // { | |
| 268 // MutexLock l(...); | |
| 269 // AutoClosureRunner r(run_after_unlock); | |
| 270 // ... | |
| 271 // } | |
| 272 // AutoClosureRunner is primarily intended for cleanup operations that | |
| 273 // are relatively independent from other code. | |
| 274 // | |
| 275 // The Reset() method replaces the callback with a new callback. The new | |
| 276 // callback can be supplied as NULL to disable the AutoClosureRunner. This is | |
| 277 // intended as part of a strategy to execute a callback at all exit points of a | |
| 278 // method except where Reset() was called. This method must be used only with | |
| 279 // non-permanent callbacks. The Release() method disables and returns the | |
| 280 // callback, instead of deleting it. | |
| 281 class AutoClosureRunner { | |
| 282 private: | |
| 283 Closure* closure_; | |
| 284 public: | |
| 285 explicit AutoClosureRunner(Closure* c) : closure_(c) {} | |
| 286 ~AutoClosureRunner() { if (closure_) closure_->Run(); } | |
| 287 void Reset(Closure *c) { delete closure_; closure_ = c; } | |
| 288 Closure* Release() { Closure* c = closure_; closure_ = NULL; return c; } | |
| 289 private: | |
| 290 DISALLOW_EVIL_CONSTRUCTORS(AutoClosureRunner); | |
| 291 }; | |
| 292 | |
| 293 // DeletePointerClosure can be used to create a closure that calls delete | |
| 294 // on a pointer. Here is an example: | |
| 295 // | |
| 296 // thread->Add(DeletePointerClosure(expensive_to_delete)); | |
| 297 // | |
| 298 template<typename T> | |
| 299 void DeletePointer(T* p) { | |
| 300 delete p; | |
| 301 } | |
| 302 | |
| 303 template<typename T> | |
| 304 Closure* DeletePointerClosure(T* p) { | |
| 305 return NewCallback(&DeletePointer<T>, p); | |
| 306 } | |
| 307 | |
| 308 #endif /* _CALLBACK_H_ */ | |
| OLD | NEW |