author | Sebastian Hengst <archaeopteryx@coole-files.de> |
Sun, 08 Nov 2015 21:25:22 +0100 | |
changeset 271691 | f620224aae8f209bc54bb57f5303e08d1f1055fe |
parent 271690 | 5b50bd85e4a347e9f309a177e1a93082a0916da0 |
child 271692 | b7fb037c6899a58b024117475c8e420f76015986 |
push id | 29650 |
push user | cbook@mozilla.com |
push date | Mon, 09 Nov 2015 13:56:12 +0000 |
treeherder | mozilla-central@e1ef2be156de [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | backout |
bugs | 1221368, 1221371 |
milestone | 45.0a1 |
backs out | a50c676caf7f12198f892e01ca1fb74fe0753df6 bd99e5060e1e3ecf627a7d5419dda8620c6b5fa6 3a22461c8ce8ee33cd7b37328c774296acc7ee2c |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
--- a/dom/media/gmp/GMPDecryptorChild.cpp +++ b/dom/media/gmp/GMPDecryptorChild.cpp @@ -56,17 +56,17 @@ GMPDecryptorChild::CallOnGMPThread(Metho { if (ON_GMP_THREAD()) { // Use forwarding reference when we can. CallMethod(aMethod, Forward<ParamType>(aParams)...); } else { // Use const reference when we have to. auto m = &GMPDecryptorChild::CallMethod< decltype(aMethod), typename AddConstReference<ParamType>::Type...>; - auto t = NewRunnableMethod(this, m, aMethod, Forward<ParamType>(aParams)...); + auto t = NewRunnableMethod(this, m, aMethod, aParams...); mPlugin->GMPMessageLoop()->PostTask(FROM_HERE, t); } } void GMPDecryptorChild::Init(GMPDecryptor* aSession) { MOZ_ASSERT(aSession); @@ -111,17 +111,17 @@ GMPDecryptorChild::SessionMessage(const GMPSessionMessageType aMessageType, const uint8_t* aMessage, uint32_t aMessageLength) { nsTArray<uint8_t> msg; msg.AppendElements(aMessage, aMessageLength); CALL_ON_GMP_THREAD(SendSessionMessage, nsAutoCString(aSessionId, aSessionIdLength), - aMessageType, Move(msg)); + aMessageType, msg); } void GMPDecryptorChild::ExpirationChange(const char* aSessionId, uint32_t aSessionIdLength, GMPTimestamp aExpiryTime) { CALL_ON_GMP_THREAD(SendExpirationChange,
--- a/dom/plugins/ipc/PluginInstanceChild.cpp +++ b/dom/plugins/ipc/PluginInstanceChild.cpp @@ -2559,17 +2559,17 @@ PluginInstanceChild::RecvAsyncSetWindow( } // We shouldn't process this now because it may be received within a nested // RPC call, and both Flash and Java don't expect to receive setwindow calls // at arbitrary times. mCurrentAsyncSetWindowTask = NewRunnableMethod<PluginInstanceChild, void (PluginInstanceChild::*)(const gfxSurfaceType&, const NPRemoteWindow&, bool), - const gfxSurfaceType&, const NPRemoteWindow&, bool> + gfxSurfaceType, NPRemoteWindow, bool> (this, &PluginInstanceChild::DoAsyncSetWindow, aSurfaceType, aWindow, true); MessageLoop::current()->PostTask(FROM_HERE, mCurrentAsyncSetWindowTask); return true; } void
--- a/gfx/layers/ipc/ImageBridgeChild.cpp +++ b/gfx/layers/ipc/ImageBridgeChild.cpp @@ -453,17 +453,17 @@ void ImageBridgeChild::DispatchReleaseTe return; } sImageBridgeChildSingleton->GetMessageLoop()->PostTask( FROM_HERE, NewRunnableFunction(&ReleaseTextureClientNow, aClient)); } -static void UpdateImageClientNow(ImageClient* aClient, RefPtr<ImageContainer>&& aContainer) +static void UpdateImageClientNow(ImageClient* aClient, ImageContainer* aContainer) { if (!ImageBridgeChild::IsCreated()) { NS_WARNING("Something is holding on to graphics resources after the shutdown" "of the graphics subsystem!"); return; } MOZ_ASSERT(aClient); MOZ_ASSERT(aContainer); @@ -486,17 +486,20 @@ void ImageBridgeChild::DispatchImageClie } if (InImageBridgeChildThread()) { UpdateImageClientNow(aClient, aContainer); return; } sImageBridgeChildSingleton->GetMessageLoop()->PostTask( FROM_HERE, - NewRunnableFunction(&UpdateImageClientNow, aClient, RefPtr<ImageContainer>(aContainer))); + NewRunnableFunction< + void (*)(ImageClient*, ImageContainer*), + ImageClient*, + RefPtr<ImageContainer> >(&UpdateImageClientNow, aClient, aContainer)); } static void UpdateAsyncCanvasRendererSync(AsyncCanvasRenderer* aWrapper, ReentrantMonitor* aBarrier, bool* const outDone) { ImageBridgeChild::UpdateAsyncCanvasRendererNow(aWrapper); @@ -535,17 +538,17 @@ void ImageBridgeChild::UpdateAsyncCanvas { MOZ_ASSERT(aWrapper); sImageBridgeChildSingleton->BeginTransaction(); aWrapper->GetCanvasClient()->Updated(); sImageBridgeChildSingleton->EndTransaction(); } static void FlushAllImagesSync(ImageClient* aClient, ImageContainer* aContainer, - RefPtr<AsyncTransactionWaiter>&& aWaiter) + AsyncTransactionWaiter* aWaiter) { if (!ImageBridgeChild::IsCreated()) { // How sad. If we get into this branch it means that the ImageBridge // got destroyed between the time we ImageBridgeChild::FlushAllImage // was called on some thread, and the time this function was proxied // to the ImageBridge thread. ImageBridge gets destroyed way to late // in the shutdown of gecko for this to be happening for a good reason. NS_WARNING("Something is holding on to graphics resources after the shutdown"
--- a/ipc/chromium/src/base/task.h +++ b/ipc/chromium/src/base/task.h @@ -1,64 +1,19 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #ifndef BASE_TASK_H_ #define BASE_TASK_H_ #include "base/non_thread_safe.h" #include "base/revocable_store.h" #include "base/tracked.h" #include "base/tuple.h" -#include "mozilla/IndexSequence.h" -#include "mozilla/Tuple.h" - -// Helper functions so that we can call a function a pass it arguments that come -// from a Tuple. - -namespace details { - -// Call the given method on the given object. Arguments are passed by move -// semantics from the given tuple. If the tuple has length N, the sequence must -// be IndexSequence<0, 1, ..., N-1>. -template<size_t... Indices, class ObjT, class Method, typename... Args> -void CallMethod(mozilla::IndexSequence<Indices...>, ObjT* obj, Method method, - mozilla::Tuple<Args...>& arg) -{ - (obj->*method)(mozilla::Move(mozilla::Get<Indices>(arg))...); -} - -// Same as above, but call a function. -template<size_t... Indices, typename Function, typename... Args> -void CallFunction(mozilla::IndexSequence<Indices...>, Function function, - mozilla::Tuple<Args...>& arg) -{ - (*function)(mozilla::Move(mozilla::Get<Indices>(arg))...); -} - -} // namespace details - -// Call a method on the given object. Arguments are passed by move semantics -// from the given tuple. -template<class ObjT, class Method, typename... Args> -void DispatchTupleToMethod(ObjT* obj, Method method, mozilla::Tuple<Args...>& arg) -{ - details::CallMethod(typename mozilla::IndexSequenceFor<Args...>::Type(), - obj, method, arg); -} - -// Same as above, but call a function. -template<typename Function, typename... Args> -void DispatchTupleToFunction(Function function, mozilla::Tuple<Args...>& arg) -{ - details::CallFunction(typename mozilla::IndexSequenceFor<Args...>::Type(), - function, arg); -} // Task ------------------------------------------------------------------------ // // A task is a generic runnable thingy, usually used for running code on a // different thread or for scheduling future tasks off of the message loop. class Task : public tracked_objects::Tracked { public: @@ -150,40 +105,101 @@ class ScopedTaskFactory : public Revocab // A ScopedRunnableMethodFactory creates runnable methods for a specified // object. This is particularly useful for generating callbacks for // non-reference counted objects when the factory is a member of the object. template<class T> class ScopedRunnableMethodFactory : public RevocableStore { public: explicit ScopedRunnableMethodFactory(T* object) : object_(object) { } - template <class Method, typename... Elements> - inline Task* NewRunnableMethod(Method method, Elements&&... elements) { - typedef mozilla::Tuple<typename mozilla::Decay<Elements>::Type...> ArgsTuple; - typedef RunnableMethod<Method, ArgsTuple> Runnable; - typedef typename ScopedTaskFactory<Runnable>::TaskWrapper TaskWrapper; + template <class Method> + inline Task* NewRunnableMethod(Method method) { + typedef typename ScopedTaskFactory<RunnableMethod< + Method, Tuple0> >::TaskWrapper TaskWrapper; + + TaskWrapper* task = new TaskWrapper(this); + task->Init(object_, method, base::MakeTuple()); + return task; + } + + template <class Method, class A> + inline Task* NewRunnableMethod(Method method, const A& a) { + typedef typename ScopedTaskFactory<RunnableMethod< + Method, Tuple1<A> > >::TaskWrapper TaskWrapper; + + TaskWrapper* task = new TaskWrapper(this); + task->Init(object_, method, base::MakeTuple(a)); + return task; + } + + template <class Method, class A, class B> + inline Task* NewRunnableMethod(Method method, const A& a, const B& b) { + typedef typename ScopedTaskFactory<RunnableMethod< + Method, Tuple2<A, B> > >::TaskWrapper TaskWrapper; TaskWrapper* task = new TaskWrapper(this); - task->Init(object_, method, mozilla::MakeTuple(mozilla::Forward<Elements>(elements)...)); + task->Init(object_, method, base::MakeTuple(a, b)); + return task; + } + + template <class Method, class A, class B, class C> + inline Task* NewRunnableMethod(Method method, + const A& a, + const B& b, + const C& c) { + typedef typename ScopedTaskFactory<RunnableMethod< + Method, Tuple3<A, B, C> > >::TaskWrapper TaskWrapper; + + TaskWrapper* task = new TaskWrapper(this); + task->Init(object_, method, base::MakeTuple(a, b, c)); + return task; + } + + template <class Method, class A, class B, class C, class D> + inline Task* NewRunnableMethod(Method method, + const A& a, + const B& b, + const C& c, + const D& d) { + typedef typename ScopedTaskFactory<RunnableMethod< + Method, Tuple4<A, B, C, D> > >::TaskWrapper TaskWrapper; + + TaskWrapper* task = new TaskWrapper(this); + task->Init(object_, method, base::MakeTuple(a, b, c, d)); + return task; + } + + template <class Method, class A, class B, class C, class D, class E> + inline Task* NewRunnableMethod(Method method, + const A& a, + const B& b, + const C& c, + const D& d, + const E& e) { + typedef typename ScopedTaskFactory<RunnableMethod< + Method, Tuple5<A, B, C, D, E> > >::TaskWrapper TaskWrapper; + + TaskWrapper* task = new TaskWrapper(this); + task->Init(object_, method, base::MakeTuple(a, b, c, d, e)); return task; } protected: template <class Method, class Params> class RunnableMethod : public Task { public: RunnableMethod() { } - void Init(T* obj, Method meth, Params&& params) { + void Init(T* obj, Method meth, const Params& params) { obj_ = obj; meth_ = meth; - params_ = mozilla::Forward<Params>(params); + params_ = params; } - virtual void Run() { DispatchTupleToMethod(obj_, meth_, params_); } + virtual void Run() { DispatchToMethod(obj_, meth_, params_); } private: T* MOZ_UNSAFE_REF("The validity of this pointer must be enforced by " "external factors.") obj_; Method meth_; Params params_; DISALLOW_EVIL_CONSTRUCTORS(RunnableMethod); @@ -289,80 +305,385 @@ struct RunnableMethodTraits<const T> { // PostTask(FROM_HERE, NewRunnableFunction(&function[, a[, b]]) // RunnableMethod and NewRunnableMethod implementation ------------------------- template <class T, class Method, class Params> class RunnableMethod : public CancelableTask, public RunnableMethodTraits<T> { public: - RunnableMethod(T* obj, Method meth, Params&& params) - : obj_(obj), meth_(meth), params_(mozilla::Forward<Params>(params)) { + RunnableMethod(T* obj, Method meth, const Params& params) + : obj_(obj), meth_(meth), params_(params) { this->RetainCallee(obj_); } ~RunnableMethod() { ReleaseCallee(); } virtual void Run() { if (obj_) - DispatchTupleToMethod(obj_, meth_, params_); + DispatchToMethod(obj_, meth_, params_); } virtual void Cancel() { ReleaseCallee(); } private: void ReleaseCallee() { if (obj_) { RunnableMethodTraits<T>::ReleaseCallee(obj_); - obj_ = nullptr; + obj_ = NULL; } } // This is owning because of the RetainCallee and ReleaseCallee calls in the // constructor and destructor. T* MOZ_OWNING_REF obj_; Method meth_; Params params_; }; -template <class T, class Method, typename... Args> -inline CancelableTask* NewRunnableMethod(T* object, Method method, Args&&... args) { - typedef mozilla::Tuple<typename mozilla::Decay<Args>::Type...> ArgsTuple; - return new RunnableMethod<T, Method, ArgsTuple>( - object, method, mozilla::MakeTuple(mozilla::Forward<Args>(args)...)); +template <class T, class Method> +inline CancelableTask* NewRunnableMethod(T* object, Method method) { + return new RunnableMethod<T, Method, Tuple0>(object, method, base::MakeTuple()); +} + +template <class T, class Method, class A> +inline CancelableTask* NewRunnableMethod(T* object, Method method, const A& a) { + return new RunnableMethod<T, Method, Tuple1<A> >(object, + method, + base::MakeTuple(a)); +} + +template <class T, class Method, class A, class B> +inline CancelableTask* NewRunnableMethod(T* object, Method method, +const A& a, const B& b) { + return new RunnableMethod<T, Method, Tuple2<A, B> >(object, method, + base::MakeTuple(a, b)); +} + +template <class T, class Method, class A, class B, class C> +inline CancelableTask* NewRunnableMethod(T* object, Method method, + const A& a, const B& b, const C& c) { + return new RunnableMethod<T, Method, Tuple3<A, B, C> >(object, method, + base::MakeTuple(a, b, c)); +} + +template <class T, class Method, class A, class B, class C, class D> +inline CancelableTask* NewRunnableMethod(T* object, Method method, + const A& a, const B& b, + const C& c, const D& d) { + return new RunnableMethod<T, Method, Tuple4<A, B, C, D> >(object, method, + base::MakeTuple(a, b, + c, d)); +} + +template <class T, class Method, class A, class B, class C, class D, class E> +inline CancelableTask* NewRunnableMethod(T* object, Method method, + const A& a, const B& b, + const C& c, const D& d, const E& e) { + return new RunnableMethod<T, + Method, + Tuple5<A, B, C, D, E> >(object, + method, + base::MakeTuple(a, b, c, d, e)); +} + +template <class T, class Method, class A, class B, class C, class D, class E, + class F> +inline CancelableTask* NewRunnableMethod(T* object, Method method, + const A& a, const B& b, + const C& c, const D& d, const E& e, + const F& f) { + return new RunnableMethod<T, + Method, + Tuple6<A, B, C, D, E, F> >(object, + method, + base::MakeTuple(a, b, c, d, e, + f)); +} + +template <class T, class Method, class A, class B, class C, class D, class E, + class F, class G> +inline CancelableTask* NewRunnableMethod(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 RunnableMethod<T, + Method, + Tuple7<A, B, C, D, E, F, G> >(object, + method, + base::MakeTuple(a, b, c, d, + e, f, g)); } // RunnableFunction and NewRunnableFunction implementation --------------------- template <class Function, class Params> class RunnableFunction : public CancelableTask { public: - RunnableFunction(Function function, Params&& params) - : function_(function), params_(mozilla::Forward<Params>(params)) { + RunnableFunction(Function function, const Params& params) + : function_(function), params_(params) { } ~RunnableFunction() { } virtual void Run() { if (function_) - DispatchTupleToFunction(function_, params_); + DispatchToFunction(function_, params_); } virtual void Cancel() { - function_ = nullptr; + function_ = NULL; } + private: Function function_; Params params_; }; -template <class Function, typename... Args> -inline CancelableTask* NewRunnableFunction(Function function, Args&&... args) { - typedef mozilla::Tuple<typename mozilla::Decay<Args>::Type...> ArgsTuple; - return new RunnableFunction<Function, ArgsTuple>( - function, mozilla::MakeTuple(mozilla::Forward<Args>(args)...)); +template <class Function> +inline CancelableTask* NewRunnableFunction(Function function) { + return new RunnableFunction<Function, Tuple0>(function, base::MakeTuple()); +} + +template <class Function, class A> +inline CancelableTask* NewRunnableFunction(Function function, const A& a) { + return new RunnableFunction<Function, Tuple1<A> >(function, base::MakeTuple(a)); +} + +template <class Function, class A, class B> +inline CancelableTask* NewRunnableFunction(Function function, + const A& a, const B& b) { + return new RunnableFunction<Function, Tuple2<A, B> >(function, + base::MakeTuple(a, b)); +} + +template <class Function, class A, class B, class C> +inline CancelableTask* NewRunnableFunction(Function function, + const A& a, const B& b, + const C& c) { + return new RunnableFunction<Function, Tuple3<A, B, C> >(function, + base::MakeTuple(a, b, c)); +} + +template <class Function, class A, class B, class C, class D> +inline CancelableTask* NewRunnableFunction(Function function, + const A& a, const B& b, + const C& c, const D& d) { + return new RunnableFunction<Function, Tuple4<A, B, C, D> >(function, + base::MakeTuple(a, b, + c, d)); +} + +template <class Function, class A, class B, class C, class D, class E> +inline CancelableTask* NewRunnableFunction(Function function, + const A& a, const B& b, + const C& c, const D& d, + const E& e) { + return new RunnableFunction<Function, Tuple5<A, B, C, D, E> >(function, + base::MakeTuple(a, b, + c, d, + e)); } +// Callback -------------------------------------------------------------------- +// +// A Callback is like a Task but with unbound parameters. It is basically an +// object-oriented function pointer. +// +// Callbacks are designed to work with Tuples. A set of helper functions and +// classes is provided to hide the Tuple details from the consumer. Client +// code will generally work with the CallbackRunner base class, which merely +// provides a Run method and is returned by the New* functions. This allows +// users to not care which type of class implements the callback, only that it +// has a certain number and type of arguments. +// +// The implementation of this is done by CallbackImpl, which inherits +// CallbackStorage to store the data. This allows the storage of the data +// (requiring the class type T) to be hidden from users, who will want to call +// this regardless of the implementor's type T. +// +// Note that callbacks currently have no facility for cancelling or abandoning +// them. We currently handle this at a higher level for cases where this is +// necessary. The pointer in a callback must remain valid until the callback +// is made. +// +// Like Task, the callback executor is responsible for deleting the callback +// pointer once the callback has executed. +// +// Example client usage: +// void Object::DoStuff(int, string); +// Callback2<int, string>::Type* callback = +// NewCallback(obj, &Object::DoStuff); +// callback->Run(5, string("hello")); +// delete callback; +// or, equivalently, using tuples directly: +// CallbackRunner<Tuple2<int, string> >* callback = +// NewCallback(obj, &Object::DoStuff); +// callback->RunWithParams(base::MakeTuple(5, string("hello"))); + +// Base for all Callbacks that handles storage of the pointers. +template <class T, typename Method> +class CallbackStorage { + public: + CallbackStorage(T* obj, Method meth) : obj_(obj), meth_(meth) { + } + + protected: + T* MOZ_UNSAFE_REF("The validity of this pointer must be enforced by " + "external factors.") obj_; + Method meth_; +}; + +// Interface that is exposed to the consumer, that does the actual calling +// of the method. +template <typename Params> +class CallbackRunner { + public: + typedef Params TupleType; + + virtual ~CallbackRunner() {} + virtual void RunWithParams(const Params& params) = 0; + + // Convenience functions so callers don't have to deal with Tuples. + inline void Run() { + RunWithParams(Tuple0()); + } + + template <typename Arg1> + inline void Run(const Arg1& a) { + RunWithParams(Params(a)); + } + + template <typename Arg1, typename Arg2> + inline void Run(const Arg1& a, const Arg2& b) { + RunWithParams(Params(a, b)); + } + + template <typename Arg1, typename Arg2, typename Arg3> + inline void Run(const Arg1& a, const Arg2& b, const Arg3& c) { + RunWithParams(Params(a, b, c)); + } + + template <typename Arg1, typename Arg2, typename Arg3, typename Arg4> + inline void Run(const Arg1& a, const Arg2& b, const Arg3& c, const Arg4& d) { + RunWithParams(Params(a, b, c, d)); + } + + template <typename Arg1, typename Arg2, typename Arg3, + typename Arg4, typename Arg5> + inline void Run(const Arg1& a, const Arg2& b, const Arg3& c, + const Arg4& d, const Arg5& e) { + RunWithParams(Params(a, b, c, d, e)); + } +}; + +template <class T, typename Method, typename Params> +class CallbackImpl : public CallbackStorage<T, Method>, + public CallbackRunner<Params> { + public: + CallbackImpl(T* obj, Method meth) : CallbackStorage<T, Method>(obj, meth) { + } + virtual void RunWithParams(const Params& params) { + // use "this->" to force C++ to look inside our templatized base class; see + // Effective C++, 3rd Ed, item 43, p210 for details. + DispatchToMethod(this->obj_, this->meth_, params); + } +}; + +// 0-arg implementation +struct Callback0 { + typedef CallbackRunner<Tuple0> Type; +}; + +template <class T> +typename Callback0::Type* NewCallback(T* object, void (T::*method)()) { + return new CallbackImpl<T, void (T::*)(), Tuple0 >(object, method); +} + +// 1-arg implementation +template <typename Arg1> +struct Callback1 { + typedef CallbackRunner<Tuple1<Arg1> > Type; +}; + +template <class T, typename Arg1> +typename Callback1<Arg1>::Type* NewCallback(T* object, + void (T::*method)(Arg1)) { + return new CallbackImpl<T, void (T::*)(Arg1), Tuple1<Arg1> >(object, method); +} + +// 2-arg implementation +template <typename Arg1, typename Arg2> +struct Callback2 { + typedef CallbackRunner<Tuple2<Arg1, Arg2> > Type; +}; + +template <class T, typename Arg1, typename Arg2> +typename Callback2<Arg1, Arg2>::Type* NewCallback( + T* object, + void (T::*method)(Arg1, Arg2)) { + return new CallbackImpl<T, void (T::*)(Arg1, Arg2), + Tuple2<Arg1, Arg2> >(object, method); +} + +// 3-arg implementation +template <typename Arg1, typename Arg2, typename Arg3> +struct Callback3 { + typedef CallbackRunner<Tuple3<Arg1, Arg2, Arg3> > Type; +}; + +template <class T, typename Arg1, typename Arg2, typename Arg3> +typename Callback3<Arg1, Arg2, Arg3>::Type* NewCallback( + T* object, + void (T::*method)(Arg1, Arg2, Arg3)) { + return new CallbackImpl<T, void (T::*)(Arg1, Arg2, Arg3), + Tuple3<Arg1, Arg2, Arg3> >(object, method); +} + +// 4-arg implementation +template <typename Arg1, typename Arg2, typename Arg3, typename Arg4> +struct Callback4 { + typedef CallbackRunner<Tuple4<Arg1, Arg2, Arg3, Arg4> > Type; +}; + +template <class T, typename Arg1, typename Arg2, typename Arg3, typename Arg4> +typename Callback4<Arg1, Arg2, Arg3, Arg4>::Type* NewCallback( + T* object, + void (T::*method)(Arg1, Arg2, Arg3, Arg4)) { + return new CallbackImpl<T, void (T::*)(Arg1, Arg2, Arg3, Arg4), + Tuple4<Arg1, Arg2, Arg3, Arg4> >(object, method); +} + +// 5-arg implementation +template <typename Arg1, typename Arg2, typename Arg3, + typename Arg4, typename Arg5> +struct Callback5 { + typedef CallbackRunner<Tuple5<Arg1, Arg2, Arg3, Arg4, Arg5> > Type; +}; + +template <class T, typename Arg1, typename Arg2, + typename Arg3, typename Arg4, typename Arg5> +typename Callback5<Arg1, Arg2, Arg3, Arg4, Arg5>::Type* NewCallback( + T* object, + void (T::*method)(Arg1, Arg2, Arg3, Arg4, Arg5)) { + return new CallbackImpl<T, void (T::*)(Arg1, Arg2, Arg3, Arg4, Arg5), + Tuple5<Arg1, Arg2, Arg3, Arg4, Arg5> >(object, method); +} + +// An UnboundMethod is a wrapper for a method where the actual object is +// provided at Run dispatch time. +template <class T, class Method, class Params> +class UnboundMethod { + public: + UnboundMethod(Method m, Params p) : m_(m), p_(p) {} + void Run(T* obj) const { + DispatchToMethod(obj, m_, p_); + } + private: + Method m_; + Params p_; +}; + #endif // BASE_TASK_H_
--- a/ipc/chromium/src/chrome/common/ipc_message_utils.h +++ b/ipc/chromium/src/chrome/common/ipc_message_utils.h @@ -7,16 +7,17 @@ #include <string> #include <vector> #include <map> #include "base/file_path.h" #include "base/string_util.h" #include "base/string16.h" +#include "base/tuple.h" #include "base/time.h" #if defined(OS_POSIX) #include "chrome/common/file_descriptor_set_posix.h" #endif #include "chrome/common/ipc_sync_message.h" #include "chrome/common/transport_dib.h"
--- a/layout/ipc/RenderFrameParent.cpp +++ b/layout/ipc/RenderFrameParent.cpp @@ -562,28 +562,28 @@ RenderFrameParent::SetTargetAPZC(uint64_ } } if (GetApzcTreeManager()) { // need a local var to disambiguate between the SetTargetAPZC overloads. void (APZCTreeManager::*setTargetApzcFunc)(uint64_t, const nsTArray<ScrollableLayerGuid>&) = &APZCTreeManager::SetTargetAPZC; APZThreadUtils::RunOnControllerThread(NewRunnableMethod( GetApzcTreeManager(), setTargetApzcFunc, - aInputBlockId, nsTArray<ScrollableLayerGuid>(aTargets))); + aInputBlockId, aTargets)); } } void RenderFrameParent::SetAllowedTouchBehavior(uint64_t aInputBlockId, const nsTArray<TouchBehaviorFlags>& aFlags) { if (GetApzcTreeManager()) { APZThreadUtils::RunOnControllerThread(NewRunnableMethod( GetApzcTreeManager(), &APZCTreeManager::SetAllowedTouchBehavior, - aInputBlockId, nsTArray<TouchBehaviorFlags>(aFlags))); + aInputBlockId, aFlags)); } } void RenderFrameParent::UpdateZoomConstraints(uint32_t aPresShellId, ViewID aViewId, const Maybe<ZoomConstraints>& aConstraints) {
--- a/mfbt/Assertions.h +++ b/mfbt/Assertions.h @@ -331,16 +331,28 @@ MOZ_ReportCrash(const char* aStr, const */ #ifdef __cplusplus # include "mozilla/TypeTraits.h" namespace mozilla { namespace detail { template<typename T> +struct IsFunction +{ + static const bool value = false; +}; + +template<typename R, typename... A> +struct IsFunction<R(A...)> +{ + static const bool value = true; +}; + +template<typename T> struct AssertionConditionType { typedef typename RemoveReference<T>::Type ValueT; static_assert(!IsArray<ValueT>::value, "Expected boolean assertion condition, got an array or a " "string!"); static_assert(!IsFunction<ValueT>::value, "Expected boolean assertion condition, got a function! Did "
--- a/mfbt/Tuple.h +++ b/mfbt/Tuple.h @@ -412,37 +412,35 @@ auto Get(Tuple<Elements...>&& aTuple) * values without specifying the type of the tuple. * The type of the tuple is deduced from the types of its elements. * * Example: * * auto tuple = MakeTuple(42, 0.5f, 'c'); // has type Tuple<int, float, char> */ template<typename... Elements> -inline Tuple<typename Decay<Elements>::Type...> -MakeTuple(Elements&&... aElements) +Tuple<Elements...> MakeTuple(Elements&&... aElements) { - return Tuple<typename Decay<Elements>::Type...>(Forward<Elements>(aElements)...); + return Tuple<Elements...>(Forward<Elements>(aElements)...); } /** * A convenience function for constructing a tuple of references to a * sequence of variables. Since assignments to the elements of the tuple * "go through" to the referenced variables, this can be used to "unpack" * a tuple into individual variables. * * Example: * * int i; * float f; * char c; * Tie(i, f, c) = FunctionThatReturnsATuple(); */ template<typename... Elements> -inline Tuple<Elements&...> -Tie(Elements&... aVariables) +Tuple<Elements&...> Tie(Elements&... aVariables) { return Tuple<Elements&...>(aVariables...); } } // namespace mozilla #endif /* mozilla_Tuple_h */
--- a/mfbt/TypeTraits.h +++ b/mfbt/TypeTraits.h @@ -160,50 +160,16 @@ struct IsArrayHelper<T[]> : TrueType {}; */ template<typename T> struct IsArray : detail::IsArrayHelper<typename RemoveCV<T>::Type> {}; namespace detail { template<typename T> -struct IsFunPtr; - -template<typename> -struct IsFunPtr - : public FalseType -{}; - -template<typename Result, typename... ArgTypes> -struct IsFunPtr<Result(*)(ArgTypes...)> - : public TrueType -{}; - -}; // namespace detail - -/** - * IsFunction determines whether a type is a function type. Function pointers - * don't qualify here--only the type of an actual function symbol. We do not - * correctly handle varags function types because of a bug in MSVC. - * - * Given the function: - * void f(int) {} - * - * mozilla::IsFunction<void(int)> is true; - * mozilla::IsFunction<void(*)(int)> is false; - * mozilla::IsFunction<decltype(f)> is true. - */ -template<typename T> -struct IsFunction - : public detail::IsFunPtr<typename RemoveCV<T>::Type *> -{}; - -namespace detail { - -template<typename T> struct IsPointerHelper : FalseType {}; template<typename T> struct IsPointerHelper<T*> : TrueType {}; } // namespace detail /** @@ -1092,32 +1058,16 @@ struct RemovePointerHelper<T, Pointee*> * mozilla::RemovePointer<void (*)()>::Type is void(); * mozilla::RemovePointer<bool S::*>::Type is bool S::*. */ template<typename T> struct RemovePointer : detail::RemovePointerHelper<T, typename RemoveCV<T>::Type> {}; -/** - * Converts T& to T*. Otherwise returns T* given T. Note that C++17 wants - * std::add_pointer to work differently for function types. We don't implement - * that behavior here. - * - * mozilla::AddPointer<int> is int*; - * mozilla::AddPointer<int*> is int**; - * mozilla::AddPointer<int&> is int*; - * mozilla::AddPointer<int* const> is int** const. - */ -template<typename T> -struct AddPointer -{ - typedef typename RemoveReference<T>::Type* Type; -}; - /* 20.9.7.6 Other transformations [meta.trans.other] */ /** * EnableIf is a struct containing a typedef of T if and only if B is true. * * mozilla::EnableIf<true, int>::Type is int; * mozilla::EnableIf<false, int>::Type is a compile-time error. * @@ -1156,56 +1106,11 @@ struct Conditional }; template<class A, class B> struct Conditional<false, A, B> { typedef B Type; }; -namespace detail { - -template<typename U, - bool IsArray = IsArray<U>::value, - bool IsFunction = IsFunction<U>::value> -struct DecaySelector; - -template<typename U> -struct DecaySelector<U, false, false> -{ - typedef typename RemoveCV<U>::Type Type; -}; - -template<typename U> -struct DecaySelector<U, true, false> -{ - typedef typename RemoveExtent<U>::Type* Type; -}; - -template<typename U> -struct DecaySelector<U, false, true> -{ - typedef typename AddPointer<U>::Type Type; -}; - -}; // namespace detail - -/** - * Strips const/volatile off a type and decays it from an lvalue to an - * rvalue. So function types are converted to function pointers, arrays to - * pointers, and references are removed. - * - * mozilla::Decay<int>::Type is int - * mozilla::Decay<int&>::Type is int - * mozilla::Decay<int&&>::Type is int - * mozilla::Decay<const int&>::Type is int - * mozilla::Decay<int[2]>::Type is int* - * mozilla::Decay<int(int)>::Type is int(*)(int) - */ -template<typename T> -class Decay - : public detail::DecaySelector<typename RemoveReference<T>::Type> -{ -}; - } /* namespace mozilla */ #endif /* mozilla_TypeTraits_h */
--- a/mfbt/tests/TestTuple.cpp +++ b/mfbt/tests/TestTuple.cpp @@ -231,31 +231,25 @@ TestGet() CHECK(Get<0>(tuple) == 41); // Writing through reference elements Get<1>(tuple) = 42; CHECK(Get<1>(tuple) == 42); CHECK(y == 42); } -static void +static bool TestMakeTuple() { auto tuple = MakeTuple(42, 0.5f, 'c'); CHECK_TYPE(tuple, Tuple<int, float, char>); CHECK(Get<0>(tuple) == 42); CHECK(Get<1>(tuple) == 0.5f); CHECK(Get<2>(tuple) == 'c'); - - // Make sure we don't infer the type to be Tuple<int&>. - int x = 1; - auto tuple2 = MakeTuple(x); - CHECK_TYPE(tuple2, Tuple<int>); - x = 2; - CHECK(Get<0>(tuple2) == 1); + return true; } static bool TestTie() { int i; float f; char c;
--- a/mfbt/tests/TestTypeTraits.cpp +++ b/mfbt/tests/TestTypeTraits.cpp @@ -3,21 +3,18 @@ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this file, * You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "mozilla/Assertions.h" #include "mozilla/TypeTraits.h" using mozilla::AddLvalueReference; -using mozilla::AddPointer; using mozilla::AddRvalueReference; -using mozilla::Decay; using mozilla::DeclVal; -using mozilla::IsFunction; using mozilla::IsArray; using mozilla::IsBaseOf; using mozilla::IsClass; using mozilla::IsConvertible; using mozilla::IsEmpty; using mozilla::IsLvalueReference; using mozilla::IsPointer; using mozilla::IsReference; @@ -25,23 +22,16 @@ using mozilla::IsRvalueReference; using mozilla::IsSame; using mozilla::IsSigned; using mozilla::IsUnsigned; using mozilla::MakeSigned; using mozilla::MakeUnsigned; using mozilla::RemoveExtent; using mozilla::RemovePointer; -static_assert(!IsFunction<int>::value, - "int is not a function type"); -static_assert(IsFunction<void(int)>::value, - "void(int) is a function type"); -static_assert(!IsFunction<void(*)(int)>::value, - "void(*)(int) is not a function type"); - static_assert(!IsArray<bool>::value, "bool not an array"); static_assert(IsArray<bool[]>::value, "bool[] is an array"); static_assert(IsArray<bool[5]>::value, "bool[5] is an array"); static_assert(!IsPointer<bool>::value, @@ -494,46 +484,16 @@ static_assert(IsSame<RemovePointer<void void (TestRemovePointer::*)()>::value, "removing pointer from void (S::*)() must return void (S::*)()"); static_assert(IsSame<RemovePointer<void (*)()>::Type, void()>::value, "removing pointer from void (*)() must return void()"); static_assert(IsSame<RemovePointer<bool TestRemovePointer::*>::Type, bool TestRemovePointer::*>::value, "removing pointer from bool S::* must return bool S::*"); -static_assert(IsSame<AddPointer<int>::Type, int*>::value, - "adding pointer to int must return int*"); -static_assert(IsSame<AddPointer<int*>::Type, int**>::value, - "adding pointer to int* must return int**"); -static_assert(IsSame<AddPointer<int&>::Type, int*>::value, - "adding pointer to int& must return int*"); -static_assert(IsSame<AddPointer<int* const>::Type, int* const*>::value, - "adding pointer to int* const must return int* const*"); -static_assert(IsSame<AddPointer<int* volatile>::Type, int* volatile*>::value, - "adding pointer to int* volatile must return int* volatile*"); - -static_assert(IsSame<Decay<int>::Type, int>::value, - "decaying int must return int"); -static_assert(IsSame<Decay<int*>::Type, int*>::value, - "decaying int* must return int*"); -static_assert(IsSame<Decay<int* const>::Type, int*>::value, - "decaying int* const must return int*"); -static_assert(IsSame<Decay<int* volatile>::Type, int*>::value, - "decaying int* volatile must return int*"); -static_assert(IsSame<Decay<int&>::Type, int>::value, - "decaying int& must return int"); -static_assert(IsSame<Decay<const int&>::Type, int>::value, - "decaying const int& must return int"); -static_assert(IsSame<Decay<int&&>::Type, int>::value, - "decaying int&& must return int"); -static_assert(IsSame<Decay<int[1]>::Type, int*>::value, - "decaying int[1] must return int*"); -static_assert(IsSame<Decay<void(int)>::Type, void(*)(int)>::value, - "decaying void(int) must return void(*)(int)"); - /* * Android's broken [u]intptr_t inttype macros are broken because its PRI*PTR * macros are defined as "ld", but sizeof(long) is 8 and sizeof(intptr_t) * is 4 on 32-bit Android. We redefine Android's PRI*PTR macros in * IntegerPrintfMacros.h and assert here that our new definitions match the * actual type sizes seen at compile time. */ #if defined(ANDROID) && !defined(__LP64__)
--- a/widget/nsBaseWidget.cpp +++ b/widget/nsBaseWidget.cpp @@ -897,17 +897,17 @@ void nsBaseWidget::ConfigureAPZCTreeMana mAPZEventState = new APZEventState(this, mozilla::Move(callback)); mSetAllowedTouchBehaviorCallback = [treeManager](uint64_t aInputBlockId, const nsTArray<TouchBehaviorFlags>& aFlags) { MOZ_ASSERT(NS_IsMainThread()); APZThreadUtils::RunOnControllerThread(NewRunnableMethod( treeManager.get(), &APZCTreeManager::SetAllowedTouchBehavior, - aInputBlockId, nsTArray<TouchBehaviorFlags>(aFlags))); + aInputBlockId, aFlags)); }; RefPtr<GeckoContentController> controller = CreateRootContentController(); if (controller) { uint64_t rootLayerTreeId = mCompositorParent->RootLayerTreeId(); CompositorParent::SetControllerForLayerTree(rootLayerTreeId, controller); } @@ -929,17 +929,17 @@ void nsBaseWidget::ConfigureAPZControlle void nsBaseWidget::SetConfirmedTargetAPZC(uint64_t aInputBlockId, const nsTArray<ScrollableLayerGuid>& aTargets) const { // Need to specifically bind this since it's overloaded. void (APZCTreeManager::*setTargetApzcFunc)(uint64_t, const nsTArray<ScrollableLayerGuid>&) = &APZCTreeManager::SetTargetAPZC; APZThreadUtils::RunOnControllerThread(NewRunnableMethod( - mAPZC.get(), setTargetApzcFunc, aInputBlockId, nsTArray<ScrollableLayerGuid>(aTargets))); + mAPZC.get(), setTargetApzcFunc, aInputBlockId, mozilla::Move(aTargets))); } void nsBaseWidget::UpdateZoomConstraints(const uint32_t& aPresShellId, const FrameMetrics::ViewID& aViewId, const Maybe<ZoomConstraints>& aConstraints) { if (!mCompositorParent || !mAPZC) {