2
* Copyright 2011 Google Inc.
4
* Licensed under the Apache License, Version 2.0 (the "License");
5
* you may not use this file except in compliance with the License.
6
* You may obtain a copy of the License at
8
* http://www.apache.org/licenses/LICENSE-2.0
10
* Unless required by applicable law or agreed to in writing, software
11
* distributed under the License is distributed on an "AS IS" BASIS,
12
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
* See the License for the specific language governing permissions and
14
* limitations under the License.
17
// Author: jmarantz@google.com (Joshua Marantz)
19
#ifndef PAGESPEED_KERNEL_BASE_FUNCTION_H_
20
#define PAGESPEED_KERNEL_BASE_FUNCTION_H_
22
#include "pagespeed/kernel/base/atomic_bool.h"
23
#include "pagespeed/kernel/base/basictypes.h"
25
namespace net_instaweb {
27
// Encapsulates a task to be run in response to some event, such as
28
// a Timer callback, an fetch, or a cache lookup.
30
// Users of interfaces requiring a Function* can either derive a new
31
// class from Function, or use one of the helper template-classes or
32
// MakeFunction variants below, which create delayed calls to class
35
// Note that Functions by default are self-deleting after call, but
36
// you can override that with set_delete_after_callback(false).
38
// A Function will always have its Run method or its Cancel method
39
// called, never both. A Function should never be deleted without its
40
// Run/Cancel method being called (except if
41
// set_delete_after_callback(false)).
43
// Note that classes calling Functions use the CallRun or CallCancel methods,
44
// rather than calling Run or Cancel directly. This allows the Function class
45
// to enforce policy on making run & cancel mutually exclusive and implement
52
// Functions used as Worker tasks can help the system shut down cleanly
53
// by calling quit_requested() periodically. To support this, Worker
54
// calls set_quit_requested_pointer so the Function object can access
57
// Note that a strategy of allocating the AtomicBool inside the Function
58
// object exposes a shutdown race when the function completes and deletes
60
void set_quit_requested_pointer(AtomicBool* x) { quit_requested_ = x; }
62
// Allows an infrastructure (e.g. Worker or Alarm) to request that
63
// a running Function stop soon, as it is being shut down.
65
// This can should only be called during the Run() method.
66
bool quit_requested() const {
67
return (quit_requested_ != NULL) && quit_requested_->value();
70
// Implementors of Function interfaces should call via these helper methods
71
// to initate Run and Cancel callbacks. This helps centralize deletion of
72
// callbacks after they are called.
76
// By default, Functions delete themselves after being called. Call
77
// this method to override. If the Function is going to be re-called,
78
// Reset() must be called on it first. Will not take effect if called
79
// within Run() or Cancel().
80
void set_delete_after_callback(bool x) { delete_after_callback_ = x; }
82
// Clears the state of the function so that it can be called or cancelled
83
// again. This only makes sense to call if set_delete_after_callback(false)
88
// Callers must override this to define the action to take when a closure
89
// is run. If this is called, Cancel() should not be called. This is
90
// a convention that's expected of callers of Function objects, but is
91
// not enforced by the Function implementation.
92
virtual void Run() = 0;
94
// Informs a the Function that it is being shut down. If this is
95
// called, Run() should not be called. This should never be called
96
// while a function is running. See also set_quit_requested(),
97
// which can be called during Run(), so that Run() implementations
98
// can check quit_requested() at their convenience to stop the
99
// operation in progress.
100
virtual void Cancel() {}
103
AtomicBool* quit_requested_;
106
bool delete_after_callback_;
108
DISALLOW_COPY_AND_ASSIGN(Function);
111
// A Macro is recommended for making a readable call to a pointer-to-member
112
// function per section 33.6 of
113
// http://www.parashift.com/c++-faq-lite/pointers-to-members.html
114
#define CALL_MEMBER_FN(object, ptrToMember) ((this->object)->*(ptrToMember))
116
// Base class for a MemberFunctionN classes, implementing an optional Cancel
117
// via a Member function.
119
class MemberFunctionBase : public Function {
121
explicit MemberFunctionBase(C* c) : object_(c) {}
127
// Captures a delayed call to a 0-arg member function as a closure.
129
class MemberFunction0 : public MemberFunctionBase<C> {
131
typedef void (C::*Func)();
133
// Constructor supplying a Run method, but no Cancel method.
134
MemberFunction0(Func f, C* c) : MemberFunctionBase<C>(c), run_(f),
138
// Constructor supplying a Run method and a Cancel method.
139
MemberFunction0(Func f, Func cancel, C* c)
140
: MemberFunctionBase<C>(c), run_(f), cancel_(cancel) {}
143
virtual void Run() { CALL_MEMBER_FN(object_, run_)(); }
144
virtual void Cancel() {
145
if (cancel_ != NULL) {
146
CALL_MEMBER_FN(object_, cancel_)();
155
// Captures a delayed call to a 1-arg member function as a closure.
156
template<class C, typename T1>
157
class MemberFunction1 : public MemberFunctionBase<C> {
159
typedef void (C::*Func)(T1);
161
// Constructor supplying a Run method, but no Cancel method.
162
MemberFunction1(Func f, C* c, T1 v1)
163
: MemberFunctionBase<C>(c), run_(f), cancel_(NULL), v1_(v1) {}
165
// Constructor supplying a Run method and a Cancel method.
166
MemberFunction1(Func f, Func cancel,
168
: MemberFunctionBase<C>(c), run_(f), cancel_(cancel), v1_(v1) {}
171
virtual void Run() { CALL_MEMBER_FN(object_, run_)(v1_); }
172
virtual void Cancel() {
173
if (cancel_ != NULL) {
174
CALL_MEMBER_FN(object_, cancel_)(v1_);
184
// Captures a delayed call to a 2-arg member function as a closure.
185
template<class C, typename T1, typename T2>
186
class MemberFunction2 : public MemberFunctionBase<C> {
188
typedef void (C::*Func)(T1, T2);
190
// Constructor supplying a Run method, but no Cancel method.
191
MemberFunction2(Func f, C* c, T1 v1, T2 v2)
192
: MemberFunctionBase<C>(c), run_(f), cancel_(NULL), v1_(v1), v2_(v2) {}
194
// Constructor supplying a Run method and a Cancel method.
195
MemberFunction2(Func f, Func cancel,
197
: MemberFunctionBase<C>(c),
198
run_(f), cancel_(cancel),
202
virtual void Run() { CALL_MEMBER_FN(object_, run_)(v1_, v2_); }
203
virtual void Cancel() {
204
if (cancel_ != NULL) {
205
CALL_MEMBER_FN(object_, cancel_)(v1_, v2_);
216
// Captures a delayed call to a 3-arg member function as a closure.
217
template<class C, typename T1, typename T2, typename T3>
218
class MemberFunction3 : public MemberFunctionBase<C> {
220
typedef void (C::*Func)(T1, T2, T3);
222
// Constructor supplying a Run method, but no Cancel method.
223
MemberFunction3(Func f, C* c, T1 v1, T2 v2, T3 v3)
224
: MemberFunctionBase<C>(c), run_(f), cancel_(NULL), v1_(v1), v2_(v2),
228
// Constructor supplying a Run method and a Cancel method.
229
MemberFunction3(Func f, Func cancel,
230
C* c, T1 v1, T2 v2, T3 v3)
231
: MemberFunctionBase<C>(c),
232
run_(f), cancel_(cancel),
233
v1_(v1), v2_(v2), v3_(v3) {}
236
virtual void Run() { CALL_MEMBER_FN(object_, run_)(v1_, v2_, v3_); }
237
virtual void Cancel() {
238
if (cancel_ != NULL) {
239
CALL_MEMBER_FN(object_, cancel_)(v1_, v2_, v3_);
251
// Captures a delayed call to a 4-arg member function as a closure.
252
template<class C, typename T1, typename T2, typename T3, typename T4>
253
class MemberFunction4 : public MemberFunctionBase<C> {
255
typedef void (C::*Func)(T1, T2, T3, T4);
257
// Constructor supplying a Run method, but no Cancel method.
258
MemberFunction4(Func f, C* c, T1 v1, T2 v2, T3 v3, T4 v4)
259
: MemberFunctionBase<C>(c), run_(f), cancel_(NULL), v1_(v1), v2_(v2),
263
// Constructor supplying a Run method and a Cancel method.
264
MemberFunction4(Func f, Func cancel,
265
C* c, T1 v1, T2 v2, T3 v3, T4 v4)
266
: MemberFunctionBase<C>(c),
267
run_(f), cancel_(cancel),
268
v1_(v1), v2_(v2), v3_(v3), v4_(v4) {}
271
virtual void Run() { CALL_MEMBER_FN(object_, run_)(v1_, v2_, v3_, v4_); }
272
virtual void Cancel() {
273
if (cancel_ != NULL) {
274
CALL_MEMBER_FN(object_, cancel_)(v1_, v2_, v3_, v4_);
287
#undef CALL_MEMBER_FN
289
// Makes a Function* that calls a 0-arg class method.
291
Function* MakeFunction(C* object, void (C::*run)()) {
292
return new MemberFunction0<C>(run, object);
295
// Makes a Function* that calls a 0-arg class method, or a 0-arg cancel
298
Function* MakeFunction(C* object, void (C::*run)(), void (C::*cancel)()) {
299
return new MemberFunction0<C>(run, cancel, object);
302
// Makes a Function* that calls a 1-arg class method.
303
template<class C, class T>
304
Function* MakeFunction(C* object, void (C::*run)(T), T t) {
305
return new MemberFunction1<C, T>(run, object, t);
308
// Makes a Function* that calls a 1-arg class method, or a 1-arg cancel
310
template<class C, class T>
311
Function* MakeFunction(C* object,
313
void (C::*cancel)(T), T t) {
314
return new MemberFunction1<C, T>(run, cancel, object, t);
317
// Makes a Function* that calls a 2-arg class method.
318
template<class C, class T, class U>
319
Function* MakeFunction(C* object, void (C::*run)(T, U), T t, U u) {
320
return new MemberFunction2<C, T, U>(run, object, t, u);
323
// Makes a Function* that calls a 2-arg class method, or a 2-arg cancel
325
template<class C, class T, class U>
326
Function* MakeFunction(C* object,
327
void (C::*run)(T, U),
328
void (C::*cancel)(T, U),
330
return new MemberFunction2<C, T, U>(run, cancel, object, t, u);
333
// Makes a Function* that calls a 3-arg class method.
334
template<class C, class T, class U, class V>
335
Function* MakeFunction(C* object,
336
void (C::*run)(T, U, V),
338
return new MemberFunction3<C, T, U, V>(run, object, t, u, v);
341
// Makes a Function* that calls a 3-arg class method, or a 3-arg cancel
343
template<class C, class T, class U, class V>
344
Function* MakeFunction(C* object,
345
void (C::*run)(T, U, V),
346
void (C::*cancel)(T, U, V),
348
return new MemberFunction3<C, T, U, V>(run, cancel, object, t, u, v);
351
// Makes a Function* that calls a 4-arg class method.
352
template<class C, class T, class U, class V, class W>
353
Function* MakeFunction(C* object,
354
void (C::*run)(T, U, V, W),
355
T t, U u, V v, W w) {
356
return new MemberFunction4<C, T, U, V, W>(run, object, t, u, v, w);
359
// Makes a Function* that calls a 4-arg class method, or a 4-arg cancel
361
template<class C, class T, class U, class V, class W>
362
Function* MakeFunction(C* object,
363
void (C::*run)(T, U, V, W),
364
void (C::*cancel)(T, U, V, W),
365
T t, U u, V v, W w) {
366
return new MemberFunction4<C, T, U, V, W>(run, cancel, object, t, u, v, w);
369
} // namespace net_instaweb
371
#endif // PAGESPEED_KERNEL_BASE_FUNCTION_H_