Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(24)

Side by Side Diff: base/sta_call.h

Issue 624713003: Keep only base/extractor.[cc|h]. (Closed) Base URL: https://chromium.googlesource.com/external/omaha.git@master
Patch Set: Created 6 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « base/sta.cc ('k') | base/sta_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright 2003-2009 Google Inc.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 // ========================================================================
15 //
16 // sta_call.h generics for cross apartment calling.
17 //
18 // The code is using compile-time and run-time polymorphism to create
19 // type-safe call wrappers that can be used to cross call from a
20 // worker thread to an STA thread. The current implementation only
21 // supports calling the main STA.
22 //
23 // Functions as well as object methods can be called.
24 //
25 // Examples:
26 // class X {
27 // public:
28 // int Add(int i, int j) { return i + j; }
29 // };
30 //
31 //
32 // namespace {
33 // int Add(long i, long j) { return i + j; }
34 // }
35 //
36 // X x;
37 // int sum = CallMethod(&x, X::Add, 10, 20);
38 // int j = CallFunction(Add, -10, 10);
39 //
40 // The central piece of machinery is a hierarchy of functors. A functor is
41 // instantiated by a function template (CallFunction or CallMethod) and its
42 // 'Invoke' method gets called.
43 // Calling 'Invoke' will send the functor using 'SendMessage'
44 // to a window. The window message handler picks up the functor and
45 // calls the functor virtual operator().
46 // This virtual call is what actually calls the specified function or the
47 // method, the only difference being that the call is now made in a thread
48 // different than the thread that called 'Invoke'. There is a partial
49 // specialization of the templates for void, so that void type is supported
50 // as a return type.
51 //
52 //
53 // !!! Limitations !!!
54 //
55 // There are a few important design and implementation limitations. They are
56 // mostly related to template parameters ambiguities (T or T&) especially
57 // for overloaded names or const types. The limitations are significant although
58 // the code is useful enough as it is in most of the cases.
59 // However, when using the code it is frustrating to discover that it does not
60 // compile for obvious and useful cases, a constant reminder that a better
61 // solution is to be seeked.
62 //
63 //
64 // The implementation does not support calling all 'stdcall' calling convention.
65 //
66 // The design does not support calling functions or methods that use pass by
67 // reference arguments: f(std::string&) .
68 //
69 // The design does not support well calling functions or methods that take
70 // pointer to const types parameters : f(const std::string*) .
71 //
72 // The implementation does not support calling methods of const objects.
73 //
74 // To reduce the number of templates that get instantiated, the types of the
75 // arguments of the call must match exactly the types of parameters of the
76 // function or method . In some cases static_casts mey be required
77 // at the point of the call. Example: CallMethod(f, static_cast<long>(10));
78
79 #ifndef OMAHA_COMMON_STA_CALL_H__
80 #define OMAHA_COMMON_STA_CALL_H__
81
82 #include "base/scoped_ptr.h"
83 #include "omaha/base/debug.h"
84 #include "omaha/base/logging.h"
85
86 namespace omaha {
87
88 // C4347: 'function template' is called instead of 'function'
89 #pragma warning(disable : 4347)
90
91 // The Base Functor is the base of the functor hierarchy.
92 class BaseFunctor {
93 public:
94 explicit BaseFunctor(bool is_async) :
95 thread_id_(::GetCurrentThreadId()),
96 is_async_(is_async) {
97 CORE_LOG(L6, (_T("[BaseFunctor::BaseFunctor]")));
98 }
99
100 // Functors are polymorphic objects.
101 virtual ~BaseFunctor() {
102 CORE_LOG(L6, (_T("[BaseFunctor::~BaseFunctor]")));
103 }
104
105 // Abstract virtual function call operator. This is always called
106 // in the callee thread by the dispatcher of the apartment.
107 virtual void operator()(void* presult) = 0;
108
109 // The thread id of the calling thread.
110 DWORD thread_id() const { return thread_id_; }
111
112 bool is_async() const { return is_async_; }
113
114 protected:
115
116 // Invoke is called by each of the derived functors. This is how
117 // the cross thread invocation is made and the result of the invocation
118 // is retrieved. Invoke is always called in the caller thread.
119 template <typename R>
120 R Invoke() {
121 R r = R(); // ensure r is initialized even for primitive types.
122 if (!is_async_) {
123 DoInvoke(&r);
124 } else {
125 // We handle the async calls as if the call returns void.
126 DoInvoke(0);
127 }
128 return r;
129 }
130
131 // non-template method to be called by the derived functors
132 // specialized for void.
133 void Invoke() {
134 // When the argument of the invocation is 0, we are not
135 // interested in the result.
136 DoInvoke(0);
137 }
138
139 private:
140 void DoInvoke(void* presult); // Does the actual invocation.
141 DWORD thread_id_; // The thread id of the calling thread.
142 bool is_async_; // True for async calls.
143
144 DISALLOW_EVIL_CONSTRUCTORS(BaseFunctor);
145 };
146
147 //
148 // 0-ary method functor.
149 //
150 template <class T, typename R>
151 class MethodFunctor0 : public BaseFunctor {
152 public:
153 MethodFunctor0(bool is_async, T* pt, R (T::*pm)()) :
154 BaseFunctor(is_async), pobj_(pt), pm_(pm) {}
155
156 virtual void operator()(void* presult) {
157 ASSERT(pobj_, (_T("Null object.")));
158 if (presult) {
159 *static_cast<R*>(presult) = (pobj_->*pm_)();
160 } else {
161 (pobj_->*pm_)();
162 }
163 }
164
165 R Invoke() {
166 // Don't forget to call the base implementation.
167 return BaseFunctor::Invoke<R>();
168 }
169
170 private:
171 T* pobj_;
172 R (T::*pm_)();
173 };
174
175 //
176 // 0-ary partial specialization for void return types.
177 //
178 template <class T>
179 class MethodFunctor0<T, void> : public BaseFunctor {
180 public:
181 MethodFunctor0(bool is_async, T* pt, void (T::*pm)()) :
182 BaseFunctor(is_async), pobj_(pt), pm_(pm) {}
183
184 virtual void operator()(void* presult) {
185 ASSERT(pobj_, (_T("Null object.")));
186 ASSERT1(!presult);
187 presult; // unreferenced formal parameter
188
189 // the actual call. There is no return value when the return type is void.
190 (pobj_->*pm_)();
191 }
192
193 // Bring in the name from the Base
194 using BaseFunctor::Invoke;
195
196 private:
197 T* pobj_;
198 void (T::*pm_)();
199 };
200
201 //
202 // 0-ary functor and specialization for void.
203 //
204 template <typename R>
205 class Functor0 : public BaseFunctor {
206 public:
207 Functor0(bool is_async, R (*pf)()) :
208 BaseFunctor(is_async), pf_(pf) {}
209
210 virtual void operator()(void* presult) {
211 if (presult) {
212 *static_cast<R*>(presult) = (*pf_)();
213 } else {
214 (*pf_)();
215 }
216 }
217
218 R Invoke() {
219 return BaseFunctor::Invoke<R>();
220 }
221
222 private:
223 R (*pf_)();
224 };
225
226 template <>
227 class Functor0<void> : public BaseFunctor {
228 public:
229 Functor0(bool is_async, void (*pf)()) :
230 BaseFunctor(is_async), pf_(pf) {}
231
232 virtual void operator()(void* presult) {
233 ASSERT1(!presult);
234 presult; // unreferenced formal parameter
235
236 (*pf_)();
237 }
238
239 using BaseFunctor::Invoke;
240
241 private:
242 void (*pf_)();
243 };
244
245
246 //
247 // 1-ary
248 //
249 template <class T, typename R, typename P>
250 class MethodFunctor1 : public BaseFunctor {
251 public:
252 MethodFunctor1(bool is_async, T* pt, R (T::*pm)(P), P p) :
253 BaseFunctor(is_async), pobj_(pt), pm_(pm), p_(p) {}
254
255 virtual void operator()(void* presult) {
256 ASSERT(pobj_, (_T("Null object.")));
257 if (presult) {
258 *static_cast<R*>(presult) = (pobj_->*pm_)(p_);
259 } else {
260 (pobj_->*pm_)(p_);
261 }
262 }
263
264 R Invoke() {
265 return BaseFunctor::Invoke<R>();
266 }
267
268 private:
269 T* pobj_;
270 R (T::*pm_)(P);
271 P p_;
272 };
273
274 template <class T, typename P>
275 class MethodFunctor1<T, void, P> : public BaseFunctor {
276 public:
277 MethodFunctor1(bool is_async, T* pt, void (T::*pm)(P), P p) :
278 BaseFunctor(is_async), pobj_(pt), pm_(pm), p_(p) {}
279
280 virtual void operator()(void* presult) {
281 ASSERT(pobj_, (_T("Null object.")));
282 ASSERT1(!presult);
283 presult; // unreferenced formal parameter
284
285 (pobj_->*pm_)(p_);
286 }
287
288 using BaseFunctor::Invoke;
289
290 private:
291 T* pobj_;
292 void (T::*pm_)(P);
293 P p_;
294 };
295
296 template <typename R, typename P1>
297 class Functor1 : public BaseFunctor {
298 public:
299 Functor1(bool is_async, R (*pf)(P1), P1 p1) :
300 BaseFunctor(is_async), pf_(pf), p1_(p1) {}
301
302 virtual void operator()(void* presult) {
303 if (presult) {
304 *static_cast<R*>(presult) = (*pf_)(p1_);
305 } else {
306 (*pf_)(p1_);
307 }
308 }
309
310 R Invoke() {
311 return BaseFunctor::Invoke<R>();
312 }
313
314 private:
315 R (*pf_)(P1);
316 P1 p1_;
317 };
318
319 template <typename P1>
320 class Functor1<void, P1> : public BaseFunctor {
321 public:
322 Functor1(bool is_async, void (*pf)(P1), P1 p1) :
323 BaseFunctor(is_async), pf_(pf), p1_(p1) {}
324
325 virtual void operator()(void* presult) {
326 ASSERT1(!presult);
327 presult; // unreferenced formal parameter
328
329 (*pf_)(p1_);
330 }
331
332 using BaseFunctor::Invoke;
333
334 private:
335 void (*pf_)(P1);
336 P1 p1_;
337 };
338
339
340 //
341 // 2-ary
342 //
343 template <class T, typename R, typename P1, typename P2>
344 class MethodFunctor2 : public BaseFunctor {
345 public:
346 MethodFunctor2(bool is_async, T* pt, R (T::*pm)(P1, P2), P1 p1, P2 p2) :
347 BaseFunctor(is_async), pobj_(pt), pm_(pm), p1_(p1), p2_(p2) {}
348
349 virtual void operator()(void* presult) {
350 ASSERT(pobj_, (_T("Null object.")));
351 if (presult) {
352 *static_cast<R*>(presult) = (pobj_->*pm_)(p1_, p2_);
353 } else {
354 (pobj_->*pm_)(p1_, p2_);
355 }
356 }
357
358 R Invoke() {
359 return BaseFunctor::Invoke<R>();
360 }
361
362 private:
363 T* pobj_;
364 R (T::*pm_)(P1, P2);
365 P1 p1_;
366 P2 p2_;
367 };
368
369 template <class T, typename P1, typename P2>
370 class MethodFunctor2<T, void, P1, P2> : public BaseFunctor {
371 public:
372 MethodFunctor2(bool is_async, T* pt, void (T::*pm)(P1, P2), P1 p1, P2 p2) :
373 BaseFunctor(is_async), pobj_(pt), pm_(pm), p1_(p1), p2_(p2) {}
374
375 virtual void operator()(void* presult) {
376 ASSERT(pobj_, (_T("Null object.")));
377 ASSERT1(!presult);
378 presult; // unreferenced formal parameter
379
380 (pobj_->*pm_)(p1_, p2_);
381 }
382
383 using BaseFunctor::Invoke;
384
385 private:
386 T* pobj_;
387 void (T::*pm_)(P1, P2);
388 P1 p1_;
389 P2 p2_;
390 };
391
392 template <typename R, typename P1, typename P2>
393 class Functor2 : public BaseFunctor {
394 public:
395 Functor2(bool is_async, R (*pf)(P1, P2), P1 p1, P2 p2) :
396 BaseFunctor(is_async), pf_(pf), p1_(p1), p2_(p2) {}
397
398 virtual void operator()(void* presult) {
399 if (presult) {
400 *static_cast<R*>(presult) = pf_(p1_, p2_);
401 } else {
402 pf_(p1_, p2_);
403 }
404 }
405
406 R Invoke() {
407 return BaseFunctor::Invoke<R>();
408 }
409
410 private:
411 R (*pf_)(P1, P2);
412 P1 p1_;
413 P2 p2_;
414 };
415
416 template <typename P1, typename P2>
417 class Functor2<void, P1, P2> : public BaseFunctor {
418 public:
419 Functor2(bool is_async, void (*pf)(P1, P2), P1 p1, P2 p2) :
420 BaseFunctor(is_async), pf_(pf), p1_(p1), p2_(p2) {}
421
422 virtual void operator()(void* presult) {
423 ASSERT1(!presult);
424 presult; // unreferenced formal parameter
425
426 (*pf_)(p1_, p2_);
427 }
428
429 using BaseFunctor::Invoke;
430
431 private:
432 void (*pf_)(P1, P2);
433 P1 p1_;
434 P2 p2_;
435 };
436
437 //
438 // 3-ary
439 //
440 template <class T, typename R, typename P1, typename P2, typename P3>
441 class MethodFunctor3 : public BaseFunctor {
442 public:
443 MethodFunctor3(bool is_async,
444 T* pt,
445 R (T::*pm)(P1, P2, P3),
446 P1 p1,
447 P2 p2,
448 P3 p3) :
449 BaseFunctor(is_async), pobj_(pt), pm_(pm), p1_(p1), p2_(p2), p3_(p3) {}
450
451 virtual void operator()(void* presult) {
452 ASSERT(pobj_, (_T("Null object.")));
453 if (presult) {
454 *static_cast<R*>(presult) = (pobj_->*pm_)(p1_, p2_, p3_);
455 } else {
456 (pobj_->*pm_)(p1_, p2_, p3_);
457 }
458 }
459
460 R Invoke() {
461 return BaseFunctor::Invoke<R>();
462 }
463
464 private:
465 T* pobj_;
466 R (T::*pm_)(P1, P2, P3);
467 P1 p1_;
468 P2 p2_;
469 P3 p3_;
470 };
471
472 template <class T, typename P1, typename P2, typename P3>
473 class MethodFunctor3<T, void, P1, P2, P3> : public BaseFunctor {
474 public:
475 MethodFunctor3(bool is_async,
476 T* pt,
477 void (T::*pm)(P1, P2, P3),
478 P1 p1,
479 P2 p2,
480 P3 p3) :
481 BaseFunctor(is_async), pobj_(pt), pm_(pm), p1_(p1), p2_(p2), p3_(p3) {}
482
483 virtual void operator()(void* presult) {
484 ASSERT(pobj_, (_T("Null object.")));
485 ASSERT1(!presult);
486 presult; // unreferenced formal parameter
487
488 (pobj_->*pm_)(p1_, p2_, p3_);
489 }
490
491 using BaseFunctor::Invoke;
492
493 private:
494 T* pobj_;
495 void (T::*pm_)(P1, P2, P3);
496 P1 p1_;
497 P2 p2_;
498 P3 p3_;
499 };
500
501
502 template <typename R, typename P1, typename P2, typename P3>
503 class Functor3 : public BaseFunctor {
504 public:
505 Functor3(bool is_async, R (*pf)(P1, P2, P3), P1 p1, P2 p2, P3 p3) :
506 BaseFunctor(is_async), pf_(pf), p1_(p1), p2_(p2), p3_(p3) {}
507 virtual void operator()(void* presult) {
508 if (presult) {
509 *static_cast<R*>(presult) = (*pf_)(p1_, p2_, p3_);
510 } else {
511 (*pf_)(p1_, p2_, p3_);
512 }
513 }
514
515 R Invoke() {
516 return BaseFunctor::Invoke<R>();
517 }
518
519 private:
520 R (*pf_)(P1, P2, P3);
521 P1 p1_;
522 P2 p2_;
523 P3 p3_;
524 };
525
526 template <typename P1, typename P2, typename P3>
527 class Functor3<void, P1, P2, P3> : public BaseFunctor {
528 public:
529 Functor3(bool is_async, void (*pf)(P1, P2, P3), P1 p1, P2 p2, P3 p3) :
530 BaseFunctor(is_async), pf_(pf), p1_(p1), p2_(p2), p3_(p3) {}
531
532 virtual void operator()(void* presult) {
533 ASSERT1(!presult);
534 presult; // unreferenced formal parameter
535
536 (*pf_)(p1_, p2_, p3_);
537 }
538
539 using BaseFunctor::Invoke;
540
541 private:
542 void (*pf_)(P1, P2, P3);
543 P1 p1_;
544 P2 p2_;
545 P3 p3_;
546 };
547
548 //
549 // 4-ary
550 //
551 template <class T,
552 typename R,
553 typename P1,
554 typename P2,
555 typename P3,
556 typename P4>
557 class MethodFunctor4 : public BaseFunctor {
558 public:
559 MethodFunctor4(bool is_async,
560 T* pt,
561 R (T::*pm)(P1, P2, P3, P4),
562 P1 p1,
563 P2 p2,
564 P3 p3,
565 P4 p4) :
566 BaseFunctor(is_async),
567 pobj_(pt),
568 pm_(pm),
569 p1_(p1),
570 p2_(p2),
571 p3_(p3),
572 p4_(p4) {}
573
574 virtual void operator()(void* presult) {
575 ASSERT(pobj_, (_T("Null object.")));
576 if (presult) {
577 *static_cast<R*>(presult) = (pobj_->*pm_)(p1_, p2_, p3_, p4_);
578 } else {
579 (pobj_->*pm_)(p1_, p2_, p3_, p4_);
580 }
581 }
582
583 R Invoke() {
584 return BaseFunctor::Invoke<R>();
585 }
586
587 private:
588 T* pobj_;
589 R (T::*pm_)(P1, P2, P3, P4);
590 P1 p1_;
591 P2 p2_;
592 P3 p3_;
593 P4 p4_;
594 };
595
596 template <class T, typename P1, typename P2, typename P3, typename P4>
597 class MethodFunctor4<T, void, P1, P2, P3, P4> : public BaseFunctor {
598 public:
599 MethodFunctor4(bool is_async,
600 T* pt,
601 void (T::*pm)(P1, P2, P3, P4),
602 P1 p1,
603 P2 p2,
604 P3 p3,
605 P4 p4) :
606 BaseFunctor(is_async),
607 pobj_(pt),
608 pm_(pm),
609 p1_(p1),
610 p2_(p2),
611 p3_(p3),
612 p4_(p4) {}
613
614 virtual void operator()(void* presult) {
615 ASSERT(pobj_, (_T("Null object.")));
616 ASSERT1(!presult);
617 presult; // unreferenced formal parameter
618
619 (pobj_->*pm_)(p1_, p2_, p3_, p4_);
620 }
621
622 using BaseFunctor::Invoke;
623
624 private:
625 T* pobj_;
626 void (T::*pm_)(P1, P2, P3, P4);
627 P1 p1_;
628 P2 p2_;
629 P3 p3_;
630 P4 p4_;
631 };
632
633
634 template <typename R, typename P1, typename P2, typename P3, typename P4>
635 class Functor4 : public BaseFunctor {
636 public:
637 Functor4(bool is_async, R (*pf)(P1, P2, P3, P4), P1 p1, P2 p2, P3 p3, P4 p4) :
638 BaseFunctor(is_async), pf_(pf), p1_(p1), p2_(p2), p3_(p3), p4_(p4) {}
639
640 virtual void operator()(void* presult) {
641 if (presult) {
642 *static_cast<R*>(presult) = (*pf_)(p1_, p2_, p3_, p4_);
643 } else {
644 (*pf_)(p1_, p2_, p3_, p4_);
645 }
646 }
647
648 R Invoke() {
649 return BaseFunctor::Invoke<R>();
650 }
651
652 private:
653 R (*pf_)(P1, P2, P3, P4);
654 P1 p1_;
655 P2 p2_;
656 P3 p3_;
657 P4 p4_;
658 };
659
660 template <typename P1, typename P2, typename P3, typename P4>
661 class Functor4<void, P1, P2, P3, P4> : public BaseFunctor {
662 public:
663 Functor4(bool is_async,
664 void (*pf)(P1, P2, P3, P4),
665 P1 p1,
666 P2 p2,
667 P3 p3,
668 P4 p4) :
669 BaseFunctor(is_async), pf_(pf), p1_(p1), p2_(p2), p3_(p3), p4_(p4) {}
670
671 virtual void operator()(void* presult) {
672 ASSERT1(!presult);
673 presult; // unreferenced formal parameter
674
675 (*pf_)(p1_, p2_, p3_, p4_);
676 }
677
678 using BaseFunctor::Invoke;
679
680 private:
681 void (*pf_)(P1, P2, P3, P4);
682 P1 p1_;
683 P2 p2_;
684 P3 p3_;
685 P4 p4_;
686 };
687
688 //
689 // 5-ary
690 //
691 template <class T,
692 typename R,
693 typename P1,
694 typename P2,
695 typename P3,
696 typename P4,
697 typename P5>
698 class MethodFunctor5 : public BaseFunctor {
699 public:
700 MethodFunctor5(bool is_async,
701 T* pt,
702 R (T::*pm)(P1, P2, P3, P4, P5),
703 P1 p1,
704 P2 p2,
705 P3 p3,
706 P4 p4,
707 P5 p5) :
708 BaseFunctor(is_async),
709 pobj_(pt),
710 pm_(pm),
711 p1_(p1),
712 p2_(p2),
713 p3_(p3),
714 p4_(p4),
715 p5_(p5) {}
716
717 virtual void operator()(void* presult) {
718 ASSERT(pobj_, (_T("Null object.")));
719 if (presult) {
720 *static_cast<R*>(presult) = (pobj_->*pm_)(p1_, p2_, p3_, p4_, p5_);
721 } else {
722 (pobj_->*pm_)(p1_, p2_, p3_, p4_, p5_);
723 }
724 }
725
726 R Invoke() {
727 return BaseFunctor::Invoke<R>();
728 }
729
730 private:
731 T* pobj_;
732 R (T::*pm_)(P1, P2, P3, P4, P5);
733 P1 p1_;
734 P2 p2_;
735 P3 p3_;
736 P4 p4_;
737 P5 p5_;
738 };
739
740 template <class T,
741 typename P1,
742 typename P2,
743 typename P3,
744 typename P4,
745 typename P5>
746 class MethodFunctor5<T, void, P1, P2, P3, P4, P5> : public BaseFunctor {
747 public:
748 MethodFunctor5(bool is_async,
749 T* pt,
750 void (T::*pm)(P1, P2, P3, P4, P5),
751 P1 p1,
752 P2 p2,
753 P3 p3,
754 P4 p4,
755 P5 p5) :
756 BaseFunctor(is_async),
757 pobj_(pt),
758 pm_(pm),
759 p1_(p1),
760 p2_(p2),
761 p3_(p3),
762 p4_(p4),
763 p5_(p5) {}
764
765 virtual void operator()(void* presult) {
766 ASSERT(pobj_, (_T("Null object.")));
767 ASSERT1(!presult);
768 presult; // unreferenced formal parameter
769
770 (pobj_->*pm_)(p1_, p2_, p3_, p4_, p5_);
771 }
772
773 using BaseFunctor::Invoke;
774
775 private:
776 T* pobj_;
777 void (T::*pm_)(P1, P2, P3, P4, P5);
778 P1 p1_;
779 P2 p2_;
780 P3 p3_;
781 P4 p4_;
782 P5 p5_;
783 };
784
785 template <typename R,
786 typename P1,
787 typename P2,
788 typename P3,
789 typename P4,
790 typename P5>
791 class Functor5 : public BaseFunctor {
792 public:
793 Functor5(bool is_async,
794 R (*pf)(P1, P2, P3, P4, P5),
795 P1 p1,
796 P2 p2,
797 P3 p3,
798 P4 p4,
799 P5 p5) :
800 BaseFunctor(is_async),
801 pf_(pf),
802 p1_(p1),
803 p2_(p2),
804 p3_(p3),
805 p4_(p4),
806 p5_(p5) {}
807 virtual void operator()(void* presult) {
808 if (presult) {
809 *static_cast<R*>(presult) = (*pf_)(p1_, p2_, p3_, p4_, p5_);
810 } else {
811 (*pf_)(p1_, p2_, p3_, p4_, p5_);
812 }
813 }
814
815 R Invoke() {
816 return BaseFunctor::Invoke<R>();
817 }
818
819 private:
820 R (*pf_)(P1, P2, P3, P4, P5);
821 P1 p1_;
822 P2 p2_;
823 P3 p3_;
824 P4 p4_;
825 P5 p5_;
826 };
827
828 template <typename P1, typename P2, typename P3, typename P4, typename P5>
829 class Functor5<void, P1, P2, P3, P4, P5> : public BaseFunctor {
830 public:
831 Functor5(bool is_async,
832 void (*pf)(P1, P2, P3, P4, P5),
833 P1 p1,
834 P2 p2,
835 P3 p3,
836 P4 p4,
837 P5 p5) :
838 BaseFunctor(is_async),
839 pf_(pf),
840 p1_(p1),
841 p2_(p2),
842 p3_(p3),
843 p4_(p4),
844 p5_(p5) {}
845
846 virtual void operator()(void* presult) {
847 ASSERT1(!presult);
848 presult; // unreferenced formal parameter
849
850 (*pf_)(p1_, p2_, p3_, p4_, p5_);
851 }
852
853 using BaseFunctor::Invoke;
854
855 private:
856 void (*pf_)(P1, P2, P3, P4, P5);
857 P1 p1_;
858 P2 p2_;
859 P3 p3_;
860 P4 p4_;
861 P5 p5_;
862 };
863
864
865 // This is what the clients of the STA code instantiate and call.
866 //
867 // Synchronous Callers.
868 //
869 template <class T, typename R>
870 R CallMethod(T* object, R (T::*pm)()) {
871 return MethodFunctor0<T, R>(false, object, pm).Invoke();
872 }
873
874 template <typename R>
875 R CallFunction(R (*pf)()) {
876 return Functor0<R>(false, pf).Invoke();
877 }
878
879 template <class T, typename R, typename P>
880 R CallMethod(T* object, R (T::*pm)(P), P p) {
881 return MethodFunctor1<T, R, P>(false, object, pm, p).Invoke();
882 }
883
884 template <typename R, typename P>
885 R CallFunction(R (*pf)(P), P p) {
886 return Functor1<R, P>(false, pf, p).Invoke();
887 }
888
889 template <class T, typename R, typename P1, typename P2>
890 R CallMethod(T* object, R (T::*pm)(P1, P2), P1 p1, P2 p2) {
891 return MethodFunctor2<T, R, P1, P2>(false, object, pm, p1, p2).Invoke();
892 }
893
894 template <typename R, typename P1, typename P2>
895 R CallFunction(R (*pf)(P1, P2), P1 p1, P2 p2) {
896 return Functor2<R, P1, P2>(false, pf, p1, p2).Invoke();
897 }
898
899 template <class T, typename R, typename P1, typename P2, typename P3>
900 R CallMethod(T* object, R (T::*pm)(P1, P2, P3), P1 p1, P2 p2, P3 p3) {
901 return MethodFunctor3<T, R, P1, P2, P3>(false,
902 object, pm, p1, p2, p3).Invoke();
903 }
904
905 template <typename R, typename P1, typename P2, typename P3>
906 R CallFunction(R (*pf)(P1, P2, P3), P1 p1, P2 p2, P3 p3) {
907 return Functor3<R, P1, P2, P3>(false, pf, p1, p2, p3).Invoke();
908 }
909
910 template <class T,
911 typename R,
912 typename P1,
913 typename P2,
914 typename P3,
915 typename P4>
916 R CallMethod(T* object,
917 R (T::*pm)(P1, P2, P3, P4),
918 P1 p1,
919 P2 p2,
920 P3 p3,
921 P4 p4) {
922 return MethodFunctor4<T, R, P1, P2, P3, P4>(false,
923 object,
924 pm,
925 p1,
926 p2,
927 p3,
928 p4).Invoke();
929 }
930
931 template <typename R, typename P1, typename P2, typename P3, typename P4>
932 R CallFunction(R (*pf)(P1, P2, P3, P4), P1 p1, P2 p2, P3 p3, P4 p4) {
933 return Functor4<R, P1, P2, P3, P4>(false, pf, p1, p2, p3, p4).Invoke();
934 }
935
936 template <class T,
937 typename R,
938 typename P1,
939 typename P2,
940 typename P3,
941 typename P4,
942 typename P5>
943 R CallMethod(T* object,
944 R (T::*pm)(P1, P2, P3, P4, P5),
945 P1 p1,
946 P2 p2,
947 P3 p3,
948 P4 p4,
949 P5 p5) {
950 return MethodFunctor5<T, R, P1, P2, P3, P4, P5>(false,
951 object,
952 pm,
953 p1,
954 p2,
955 p3,
956 p4,
957 p5).Invoke();
958 }
959
960 template <typename R,
961 typename P1,
962 typename P2,
963 typename P3,
964 typename P4,
965 typename P5>
966 R CallFunction(R (*pf)(P1, P2, P3, P4, P5), P1 p1, P2 p2, P3 p3, P4 p4, P5 p5) {
967 return Functor5<R, P1, P2, P3, P4, P5>(false,
968 pf,
969 p1,
970 p2,
971 p3,
972 p4,
973 p5).Invoke();
974 }
975
976 //
977 // Asynchronous Callers.
978 //
979 template <class T, typename R>
980 void CallMethodAsync(T* object, R (T::*pm)()) {
981 scoped_ptr<MethodFunctor0<T, R> > fun(
982 new MethodFunctor0<T, R>(true, object, pm));
983 fun->Invoke();
984 fun.release();
985 }
986
987 template <typename R>
988 void CallFunctionAsync(R (*pf)()) {
989 scoped_ptr<Functor0<R> > fun(new Functor0<R>(true, pf));
990 fun->Invoke();
991 fun.release();
992 }
993
994 template <class T, typename R, typename P>
995 void CallMethodAsync(T* object, R (T::*pm)(P), P p) {
996 scoped_ptr<MethodFunctor1<T, R, P> > fun(
997 new MethodFunctor1<T, R, P>(true, object, pm, p));
998 fun->Invoke();
999 fun.release();
1000 }
1001
1002 template <typename R, typename P>
1003 void CallFunctionAsync(R (*pf)(P), P p) {
1004 scoped_ptr<Functor1<R, P> > fun(new Functor1<R, P>(true, pf, p));
1005 fun->Invoke();
1006 fun.release();
1007 }
1008
1009 template <class T, typename R, typename P1, typename P2>
1010 void CallMethodAsync(T* object, R (T::*pm)(P1, P2), P1 p1, P2 p2) {
1011 scoped_ptr<MethodFunctor2<T, R, P1, P2> > fun(
1012 new MethodFunctor2<T, R, P1, P2>(true, object, pm, p1, p2));
1013 fun->Invoke();
1014 fun.release();
1015 }
1016
1017 template <typename R, typename P1, typename P2>
1018 void CallFunctionAsync(R (*pf)(P1, P2), P1 p1, P2 p2) {
1019 scoped_ptr<Functor2<R, P1, P2> > fun(
1020 new Functor2<R, P1, P2>(true, pf, p1, p2));
1021 fun->Invoke();
1022 fun.release();
1023 }
1024
1025 template <class T, typename R, typename P1, typename P2, typename P3>
1026 void CallMethodAsync(T* object, R (T::*pm)(P1, P2, P3), P1 p1, P2 p2, P3 p3) {
1027 scoped_ptr<MethodFunctor3<T, R, P1, P2, P3> > fun(
1028 new MethodFunctor3<T, R, P1, P2, P3>(true, object, pm, p1, p2, p3));
1029 fun->Invoke();
1030 fun.release();
1031 }
1032
1033 template <typename R, typename P1, typename P2, typename P3>
1034 void CallFunctionAsync(R (*pf)(P1, P2, P3), P1 p1, P2 p2, P3 p3) {
1035 scoped_ptr<Functor3<R, P1, P2, P3> > fun(
1036 new Functor3<R, P1, P2, P3>(true, pf, p1, p2, p3));
1037 fun->Invoke();
1038 fun.release();
1039 }
1040
1041 template <class T,
1042 typename R,
1043 typename P1,
1044 typename P2,
1045 typename P3,
1046 typename P4>
1047 void CallMethodAsync(T* obj,
1048 R (T::*pm)(P1, P2, P3, P4),
1049 P1 p1,
1050 P2 p2,
1051 P3 p3,
1052 P4 p4) {
1053 scoped_ptr<MethodFunctor4<T, R, P1, P2, P3, P4> > fun(
1054 new MethodFunctor4<T, R, P1, P2, P3, P4>(true, obj, pm, p1, p2, p3, p4));
1055 fun->Invoke();
1056 fun.release();
1057 }
1058
1059 template <typename R, typename P1, typename P2, typename P3, typename P4>
1060 void CallFunctionAsync(R (*pf)(P1, P2, P3, P4), P1 p1, P2 p2, P3 p3, P4 p4) {
1061 scoped_ptr<Functor4<R, P1, P2, P3, P4> > fun(
1062 new Functor4<R, P1, P2, P3, P4>(true, pf, p1, p2, p3, p4));
1063 fun->Invoke();
1064 fun.release();
1065 }
1066
1067 template <class T,
1068 typename R,
1069 typename P1,
1070 typename P2,
1071 typename P3,
1072 typename P4,
1073 typename P5>
1074 void CallMethodAsync(T* object,
1075 R (T::*pm)(P1, P2, P3, P4, P5),
1076 P1 p1,
1077 P2 p2,
1078 P3 p3,
1079 P4 p4,
1080 P5 p5) {
1081 scoped_ptr<MethodFunctor5<T, R, P1, P2, P3, P4, P5> > fun(
1082 new MethodFunctor5<T, R, P1, P2, P3, P4, P5>(true,
1083 object,
1084 pm,
1085 p1,
1086 p2,
1087 p3,
1088 p4,
1089 p5));
1090 fun->Invoke();
1091 fun.release();
1092 }
1093
1094 template <typename R,
1095 typename P1,
1096 typename P2,
1097 typename P3,
1098 typename P4,
1099 typename P5>
1100 void CallFunctionAsync(R (*pf)(P1, P2, P3, P4, P5),
1101 P1 p1,
1102 P2 p2,
1103 P3 p3,
1104 P4 p4,
1105 P5 p5) {
1106 scoped_ptr<Functor5<R, P1, P2, P3, P4, P5> > fun(
1107 new Functor5<R, P1, P2, P3, P4, P5>(true, pf, p1, p2, p3, p4, p5));
1108 fun->Invoke();
1109 fun.release();
1110 }
1111
1112 #pragma warning(default : 4347)
1113
1114 } // namespace omaha
1115
1116 #endif // OMAHA_COMMON_STA_CALL_H__
1117
OLDNEW
« no previous file with comments | « base/sta.cc ('k') | base/sta_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698