// Copyright (c) 2011 Marshall A. Greenblatt. Portions Copyright (c) // 2006-2011 Google Inc. All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: // // * Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // * Redistributions in binary form must reproduce the above // copyright notice, this list of conditions and the following disclaimer // in the documentation and/or other materials provided with the // distribution. // * Neither the name of Google Inc. nor the name Chromium Embedded // Framework nor the names of its contributors may be used to endorse // or promote products derived from this software without specific prior // written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // // The contents of this file are a modified extract of base/task.h #ifndef _CEF_RUNNABLE_H #define _CEF_RUNNABLE_H #pragma once #include "cef.h" #ifdef BUILDING_CEF_SHARED #include "base/tuple.h" #else #include "cef_tuple.h" #endif // CefRunnableMethodTraits ----------------------------------------------------- // // This traits-class is used by CefRunnableMethod to manage the lifetime of the // callee object. By default, it is assumed that the callee supports AddRef // and Release methods. A particular class can specialize this template to // define other lifetime management. For example, if the callee is known to // live longer than the CefRunnableMethod object, then a CefRunnableMethodTraits // struct could be defined with empty RetainCallee and ReleaseCallee methods. // // The DISABLE_RUNNABLE_METHOD_REFCOUNT macro is provided as a convenient way // for declaring a CefRunnableMethodTraits that disables refcounting. template struct CefRunnableMethodTraits { CefRunnableMethodTraits() { } ~CefRunnableMethodTraits() { } void RetainCallee(T* obj) { #ifndef NDEBUG // Catch NewCefRunnableMethod being called in an object's constructor. // This isn't safe since the method can be invoked before the constructor // completes, causing the object to be deleted. obj->AddRef(); obj->Release(); #endif obj->AddRef(); } void ReleaseCallee(T* obj) { obj->Release(); } }; // Convenience macro for declaring a CefRunnableMethodTraits that disables // refcounting of a class. This is useful if you know that the callee // will outlive the CefRunnableMethod object and thus do not need the ref // counts. // // The invocation of DISABLE_RUNNABLE_METHOD_REFCOUNT should be done at the // global namespace scope. Example: // // namespace foo { // class Bar { // ... // }; // } // namespace foo // // DISABLE_RUNNABLE_METHOD_REFCOUNT(foo::Bar); // // This is different from DISALLOW_COPY_AND_ASSIGN which is declared inside the // class. #define DISABLE_RUNNABLE_METHOD_REFCOUNT(TypeName) \ template <> \ struct CefRunnableMethodTraits { \ void RetainCallee(TypeName* manager) {} \ void ReleaseCallee(TypeName* manager) {} \ } // CefRunnableMethod and CefRunnableFunction ---------------------------------- // // CefRunnable methods are a type of task that call a function on an object // when they are run. We implement both an object and a set of // NewCefRunnableMethod and NewCefRunnableFunction functions for convenience. // These functions are overloaded and will infer the template types, // simplifying calling code. // // The template definitions all use the following names: // T - the class type of the object you're supplying // this is not needed for the Static version of the call // Method/Function - the signature of a pointer to the method or function you // want to call // Param - the parameter(s) to the method, possibly packed as a Tuple // A - the first parameter (if any) to the method // B - the second parameter (if any) to the method // // Put these all together and you get an object that can call a method whose // signature is: // R T::MyFunction([A[, B]]) // // Usage: // CefPostTask(TID_UI, NewCefRunnableMethod(object, &Object::method[, a[, b]]) // CefPostTask(TID_UI, NewCefRunnableFunction(&function[, a[, b]]) // CefRunnableMethod and NewCefRunnableMethod implementation ------------------ template class CefRunnableMethod : public CefThreadSafeBase { public: CefRunnableMethod(T* obj, Method meth, const Params& params) : obj_(obj), meth_(meth), params_(params) { traits_.RetainCallee(obj_); } ~CefRunnableMethod() { T* obj = obj_; obj_ = NULL; if (obj) traits_.ReleaseCallee(obj); } virtual void Execute(CefThreadId threadId) { if (obj_) DispatchToMethod(obj_, meth_, params_); } private: T* obj_; Method meth_; Params params_; CefRunnableMethodTraits traits_; }; template inline CefRefPtr NewCefRunnableMethod(T* object, Method method) { return new CefRunnableMethod(object, method, MakeTuple()); } template inline CefRefPtr NewCefRunnableMethod(T* object, Method method, const A& a) { return new CefRunnableMethod >(object, method, MakeTuple(a)); } template inline CefRefPtr NewCefRunnableMethod(T* object, Method method, const A& a, const B& b) { return new CefRunnableMethod >(object, method, MakeTuple(a, b)); } template inline CefRefPtr NewCefRunnableMethod(T* object, Method method, const A& a, const B& b, const C& c) { return new CefRunnableMethod >(object, method, MakeTuple(a, b, c)); } template inline CefRefPtr NewCefRunnableMethod(T* object, Method method, const A& a, const B& b, const C& c, const D& d) { return new CefRunnableMethod >(object, method, MakeTuple(a, b, c, d)); } template inline CefRefPtr NewCefRunnableMethod(T* object, Method method, const A& a, const B& b, const C& c, const D& d, const E& e) { return new CefRunnableMethod >(object, method, MakeTuple(a, b, c, d, e)); } template inline CefRefPtr NewCefRunnableMethod(T* object, Method method, const A& a, const B& b, const C& c, const D& d, const E& e, const F& f) { return new CefRunnableMethod >(object, method, MakeTuple(a, b, c, d, e, f)); } template inline CefRefPtr NewCefRunnableMethod(T* object, Method method, const A& a, const B& b, const C& c, const D& d, const E& e, const F& f, const G& g) { return new CefRunnableMethod >(object, method, MakeTuple(a, b, c, d, e, f, g)); } // CefRunnableFunction and NewCefRunnableFunction implementation -------------- template class CefRunnableFunction : public CefThreadSafeBase { public: CefRunnableFunction(Function function, const Params& params) : function_(function), params_(params) { } ~CefRunnableFunction() { } virtual void Execute(CefThreadId threadId) { if (function_) DispatchToFunction(function_, params_); } private: Function function_; Params params_; }; template inline CefRefPtr NewCefRunnableFunction(Function function) { return new CefRunnableFunction(function, MakeTuple()); } template inline CefRefPtr NewCefRunnableFunction(Function function, const A& a) { return new CefRunnableFunction >(function, MakeTuple(a)); } template inline CefRefPtr NewCefRunnableFunction(Function function, const A& a, const B& b) { return new CefRunnableFunction >(function, MakeTuple(a, b)); } template inline CefRefPtr NewCefRunnableFunction(Function function, const A& a, const B& b, const C& c) { return new CefRunnableFunction >(function, MakeTuple(a, b, c)); } template inline CefRefPtr NewCefRunnableFunction(Function function, const A& a, const B& b, const C& c, const D& d) { return new CefRunnableFunction >(function, MakeTuple(a, b, c, d)); } template inline CefRefPtr NewCefRunnableFunction(Function function, const A& a, const B& b, const C& c, const D& d, const E& e) { return new CefRunnableFunction >(function, MakeTuple(a, b, c, d, e)); } template inline CefRefPtr NewCefRunnableFunction(Function function, const A& a, const B& b, const C& c, const D& d, const E& e, const F& f) { return new CefRunnableFunction >(function, MakeTuple(a, b, c, d, e, f)); } template inline CefRefPtr NewCefRunnableFunction(Function function, const A& a, const B& b, const C& c, const D& d, const E& e, const F& f, const G& g) { return new CefRunnableFunction >( function, MakeTuple(a, b, c, d, e, f, g)); } template inline CefRefPtr NewCefRunnableFunction(Function function, const A& a, const B& b, const C& c, const D& d, const E& e, const F& f, const G& g, const H& h) { return new CefRunnableFunction >( function, MakeTuple(a, b, c, d, e, f, g, h)); } #endif // _CEF_RUNNABLE_H