1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/security/sandbox/chromium/base/bind_helpers.h Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,544 @@ 1.4 +// Copyright (c) 2011 The Chromium Authors. All rights reserved. 1.5 +// Use of this source code is governed by a BSD-style license that can be 1.6 +// found in the LICENSE file. 1.7 + 1.8 +// This defines a set of argument wrappers and related factory methods that 1.9 +// can be used specify the refcounting and reference semantics of arguments 1.10 +// that are bound by the Bind() function in base/bind.h. 1.11 +// 1.12 +// It also defines a set of simple functions and utilities that people want 1.13 +// when using Callback<> and Bind(). 1.14 +// 1.15 +// 1.16 +// ARGUMENT BINDING WRAPPERS 1.17 +// 1.18 +// The wrapper functions are base::Unretained(), base::Owned(), bass::Passed(), 1.19 +// base::ConstRef(), and base::IgnoreResult(). 1.20 +// 1.21 +// Unretained() allows Bind() to bind a non-refcounted class, and to disable 1.22 +// refcounting on arguments that are refcounted objects. 1.23 +// 1.24 +// Owned() transfers ownership of an object to the Callback resulting from 1.25 +// bind; the object will be deleted when the Callback is deleted. 1.26 +// 1.27 +// Passed() is for transferring movable-but-not-copyable types (eg. scoped_ptr) 1.28 +// through a Callback. Logically, this signifies a destructive transfer of 1.29 +// the state of the argument into the target function. Invoking 1.30 +// Callback::Run() twice on a Callback that was created with a Passed() 1.31 +// argument will CHECK() because the first invocation would have already 1.32 +// transferred ownership to the target function. 1.33 +// 1.34 +// ConstRef() allows binding a constant reference to an argument rather 1.35 +// than a copy. 1.36 +// 1.37 +// IgnoreResult() is used to adapt a function or Callback with a return type to 1.38 +// one with a void return. This is most useful if you have a function with, 1.39 +// say, a pesky ignorable bool return that you want to use with PostTask or 1.40 +// something else that expect a Callback with a void return. 1.41 +// 1.42 +// EXAMPLE OF Unretained(): 1.43 +// 1.44 +// class Foo { 1.45 +// public: 1.46 +// void func() { cout << "Foo:f" << endl; } 1.47 +// }; 1.48 +// 1.49 +// // In some function somewhere. 1.50 +// Foo foo; 1.51 +// Closure foo_callback = 1.52 +// Bind(&Foo::func, Unretained(&foo)); 1.53 +// foo_callback.Run(); // Prints "Foo:f". 1.54 +// 1.55 +// Without the Unretained() wrapper on |&foo|, the above call would fail 1.56 +// to compile because Foo does not support the AddRef() and Release() methods. 1.57 +// 1.58 +// 1.59 +// EXAMPLE OF Owned(): 1.60 +// 1.61 +// void foo(int* arg) { cout << *arg << endl } 1.62 +// 1.63 +// int* pn = new int(1); 1.64 +// Closure foo_callback = Bind(&foo, Owned(pn)); 1.65 +// 1.66 +// foo_callback.Run(); // Prints "1" 1.67 +// foo_callback.Run(); // Prints "1" 1.68 +// *n = 2; 1.69 +// foo_callback.Run(); // Prints "2" 1.70 +// 1.71 +// foo_callback.Reset(); // |pn| is deleted. Also will happen when 1.72 +// // |foo_callback| goes out of scope. 1.73 +// 1.74 +// Without Owned(), someone would have to know to delete |pn| when the last 1.75 +// reference to the Callback is deleted. 1.76 +// 1.77 +// 1.78 +// EXAMPLE OF ConstRef(): 1.79 +// 1.80 +// void foo(int arg) { cout << arg << endl } 1.81 +// 1.82 +// int n = 1; 1.83 +// Closure no_ref = Bind(&foo, n); 1.84 +// Closure has_ref = Bind(&foo, ConstRef(n)); 1.85 +// 1.86 +// no_ref.Run(); // Prints "1" 1.87 +// has_ref.Run(); // Prints "1" 1.88 +// 1.89 +// n = 2; 1.90 +// no_ref.Run(); // Prints "1" 1.91 +// has_ref.Run(); // Prints "2" 1.92 +// 1.93 +// Note that because ConstRef() takes a reference on |n|, |n| must outlive all 1.94 +// its bound callbacks. 1.95 +// 1.96 +// 1.97 +// EXAMPLE OF IgnoreResult(): 1.98 +// 1.99 +// int DoSomething(int arg) { cout << arg << endl; } 1.100 +// 1.101 +// // Assign to a Callback with a void return type. 1.102 +// Callback<void(int)> cb = Bind(IgnoreResult(&DoSomething)); 1.103 +// cb->Run(1); // Prints "1". 1.104 +// 1.105 +// // Prints "1" on |ml|. 1.106 +// ml->PostTask(FROM_HERE, Bind(IgnoreResult(&DoSomething), 1); 1.107 +// 1.108 +// 1.109 +// EXAMPLE OF Passed(): 1.110 +// 1.111 +// void TakesOwnership(scoped_ptr<Foo> arg) { } 1.112 +// scoped_ptr<Foo> CreateFoo() { return scoped_ptr<Foo>(new Foo()); } 1.113 +// 1.114 +// scoped_ptr<Foo> f(new Foo()); 1.115 +// 1.116 +// // |cb| is given ownership of Foo(). |f| is now NULL. 1.117 +// // You can use f.Pass() in place of &f, but it's more verbose. 1.118 +// Closure cb = Bind(&TakesOwnership, Passed(&f)); 1.119 +// 1.120 +// // Run was never called so |cb| still owns Foo() and deletes 1.121 +// // it on Reset(). 1.122 +// cb.Reset(); 1.123 +// 1.124 +// // |cb| is given a new Foo created by CreateFoo(). 1.125 +// cb = Bind(&TakesOwnership, Passed(CreateFoo())); 1.126 +// 1.127 +// // |arg| in TakesOwnership() is given ownership of Foo(). |cb| 1.128 +// // no longer owns Foo() and, if reset, would not delete Foo(). 1.129 +// cb.Run(); // Foo() is now transferred to |arg| and deleted. 1.130 +// cb.Run(); // This CHECK()s since Foo() already been used once. 1.131 +// 1.132 +// Passed() is particularly useful with PostTask() when you are transferring 1.133 +// ownership of an argument into a task, but don't necessarily know if the 1.134 +// task will always be executed. This can happen if the task is cancellable 1.135 +// or if it is posted to a MessageLoopProxy. 1.136 +// 1.137 +// 1.138 +// SIMPLE FUNCTIONS AND UTILITIES. 1.139 +// 1.140 +// DoNothing() - Useful for creating a Closure that does nothing when called. 1.141 +// DeletePointer<T>() - Useful for creating a Closure that will delete a 1.142 +// pointer when invoked. Only use this when necessary. 1.143 +// In most cases MessageLoop::DeleteSoon() is a better 1.144 +// fit. 1.145 + 1.146 +#ifndef BASE_BIND_HELPERS_H_ 1.147 +#define BASE_BIND_HELPERS_H_ 1.148 + 1.149 +#include "base/basictypes.h" 1.150 +#include "base/callback.h" 1.151 +#include "base/memory/weak_ptr.h" 1.152 +#include "base/template_util.h" 1.153 + 1.154 +namespace base { 1.155 +namespace internal { 1.156 + 1.157 +// Use the Substitution Failure Is Not An Error (SFINAE) trick to inspect T 1.158 +// for the existence of AddRef() and Release() functions of the correct 1.159 +// signature. 1.160 +// 1.161 +// http://en.wikipedia.org/wiki/Substitution_failure_is_not_an_error 1.162 +// http://stackoverflow.com/questions/257288/is-it-possible-to-write-a-c-template-to-check-for-a-functions-existence 1.163 +// http://stackoverflow.com/questions/4358584/sfinae-approach-comparison 1.164 +// http://stackoverflow.com/questions/1966362/sfinae-to-check-for-inherited-member-functions 1.165 +// 1.166 +// The last link in particular show the method used below. 1.167 +// 1.168 +// For SFINAE to work with inherited methods, we need to pull some extra tricks 1.169 +// with multiple inheritance. In the more standard formulation, the overloads 1.170 +// of Check would be: 1.171 +// 1.172 +// template <typename C> 1.173 +// Yes NotTheCheckWeWant(Helper<&C::TargetFunc>*); 1.174 +// 1.175 +// template <typename C> 1.176 +// No NotTheCheckWeWant(...); 1.177 +// 1.178 +// static const bool value = sizeof(NotTheCheckWeWant<T>(0)) == sizeof(Yes); 1.179 +// 1.180 +// The problem here is that template resolution will not match 1.181 +// C::TargetFunc if TargetFunc does not exist directly in C. That is, if 1.182 +// TargetFunc in inherited from an ancestor, &C::TargetFunc will not match, 1.183 +// |value| will be false. This formulation only checks for whether or 1.184 +// not TargetFunc exist directly in the class being introspected. 1.185 +// 1.186 +// To get around this, we play a dirty trick with multiple inheritance. 1.187 +// First, We create a class BaseMixin that declares each function that we 1.188 +// want to probe for. Then we create a class Base that inherits from both T 1.189 +// (the class we wish to probe) and BaseMixin. Note that the function 1.190 +// signature in BaseMixin does not need to match the signature of the function 1.191 +// we are probing for; thus it's easiest to just use void(void). 1.192 +// 1.193 +// Now, if TargetFunc exists somewhere in T, then &Base::TargetFunc has an 1.194 +// ambiguous resolution between BaseMixin and T. This lets us write the 1.195 +// following: 1.196 +// 1.197 +// template <typename C> 1.198 +// No GoodCheck(Helper<&C::TargetFunc>*); 1.199 +// 1.200 +// template <typename C> 1.201 +// Yes GoodCheck(...); 1.202 +// 1.203 +// static const bool value = sizeof(GoodCheck<Base>(0)) == sizeof(Yes); 1.204 +// 1.205 +// Notice here that the variadic version of GoodCheck() returns Yes here 1.206 +// instead of No like the previous one. Also notice that we calculate |value| 1.207 +// by specializing GoodCheck() on Base instead of T. 1.208 +// 1.209 +// We've reversed the roles of the variadic, and Helper overloads. 1.210 +// GoodCheck(Helper<&C::TargetFunc>*), when C = Base, fails to be a valid 1.211 +// substitution if T::TargetFunc exists. Thus GoodCheck<Base>(0) will resolve 1.212 +// to the variadic version if T has TargetFunc. If T::TargetFunc does not 1.213 +// exist, then &C::TargetFunc is not ambiguous, and the overload resolution 1.214 +// will prefer GoodCheck(Helper<&C::TargetFunc>*). 1.215 +// 1.216 +// This method of SFINAE will correctly probe for inherited names, but it cannot 1.217 +// typecheck those names. It's still a good enough sanity check though. 1.218 +// 1.219 +// Works on gcc-4.2, gcc-4.4, and Visual Studio 2008. 1.220 +// 1.221 +// TODO(ajwong): Move to ref_counted.h or template_util.h when we've vetted 1.222 +// this works well. 1.223 +// 1.224 +// TODO(ajwong): Make this check for Release() as well. 1.225 +// See http://crbug.com/82038. 1.226 +template <typename T> 1.227 +class SupportsAddRefAndRelease { 1.228 + typedef char Yes[1]; 1.229 + typedef char No[2]; 1.230 + 1.231 + struct BaseMixin { 1.232 + void AddRef(); 1.233 + }; 1.234 + 1.235 +// MSVC warns when you try to use Base if T has a private destructor, the 1.236 +// common pattern for refcounted types. It does this even though no attempt to 1.237 +// instantiate Base is made. We disable the warning for this definition. 1.238 +#if defined(OS_WIN) 1.239 +#pragma warning(push) 1.240 +#pragma warning(disable:4624) 1.241 +#endif 1.242 + struct Base : public T, public BaseMixin { 1.243 + }; 1.244 +#if defined(OS_WIN) 1.245 +#pragma warning(pop) 1.246 +#endif 1.247 + 1.248 + template <void(BaseMixin::*)(void)> struct Helper {}; 1.249 + 1.250 + template <typename C> 1.251 + static No& Check(Helper<&C::AddRef>*); 1.252 + 1.253 + template <typename > 1.254 + static Yes& Check(...); 1.255 + 1.256 + public: 1.257 + static const bool value = sizeof(Check<Base>(0)) == sizeof(Yes); 1.258 +}; 1.259 + 1.260 +// Helpers to assert that arguments of a recounted type are bound with a 1.261 +// scoped_refptr. 1.262 +template <bool IsClasstype, typename T> 1.263 +struct UnsafeBindtoRefCountedArgHelper : false_type { 1.264 +}; 1.265 + 1.266 +template <typename T> 1.267 +struct UnsafeBindtoRefCountedArgHelper<true, T> 1.268 + : integral_constant<bool, SupportsAddRefAndRelease<T>::value> { 1.269 +}; 1.270 + 1.271 +template <typename T> 1.272 +struct UnsafeBindtoRefCountedArg : false_type { 1.273 +}; 1.274 + 1.275 +template <typename T> 1.276 +struct UnsafeBindtoRefCountedArg<T*> 1.277 + : UnsafeBindtoRefCountedArgHelper<is_class<T>::value, T> { 1.278 +}; 1.279 + 1.280 +template <typename T> 1.281 +class HasIsMethodTag { 1.282 + typedef char Yes[1]; 1.283 + typedef char No[2]; 1.284 + 1.285 + template <typename U> 1.286 + static Yes& Check(typename U::IsMethod*); 1.287 + 1.288 + template <typename U> 1.289 + static No& Check(...); 1.290 + 1.291 + public: 1.292 + static const bool value = sizeof(Check<T>(0)) == sizeof(Yes); 1.293 +}; 1.294 + 1.295 +template <typename T> 1.296 +class UnretainedWrapper { 1.297 + public: 1.298 + explicit UnretainedWrapper(T* o) : ptr_(o) {} 1.299 + T* get() const { return ptr_; } 1.300 + private: 1.301 + T* ptr_; 1.302 +}; 1.303 + 1.304 +template <typename T> 1.305 +class ConstRefWrapper { 1.306 + public: 1.307 + explicit ConstRefWrapper(const T& o) : ptr_(&o) {} 1.308 + const T& get() const { return *ptr_; } 1.309 + private: 1.310 + const T* ptr_; 1.311 +}; 1.312 + 1.313 +template <typename T> 1.314 +struct IgnoreResultHelper { 1.315 + explicit IgnoreResultHelper(T functor) : functor_(functor) {} 1.316 + 1.317 + T functor_; 1.318 +}; 1.319 + 1.320 +template <typename T> 1.321 +struct IgnoreResultHelper<Callback<T> > { 1.322 + explicit IgnoreResultHelper(const Callback<T>& functor) : functor_(functor) {} 1.323 + 1.324 + const Callback<T>& functor_; 1.325 +}; 1.326 + 1.327 +// An alternate implementation is to avoid the destructive copy, and instead 1.328 +// specialize ParamTraits<> for OwnedWrapper<> to change the StorageType to 1.329 +// a class that is essentially a scoped_ptr<>. 1.330 +// 1.331 +// The current implementation has the benefit though of leaving ParamTraits<> 1.332 +// fully in callback_internal.h as well as avoiding type conversions during 1.333 +// storage. 1.334 +template <typename T> 1.335 +class OwnedWrapper { 1.336 + public: 1.337 + explicit OwnedWrapper(T* o) : ptr_(o) {} 1.338 + ~OwnedWrapper() { delete ptr_; } 1.339 + T* get() const { return ptr_; } 1.340 + OwnedWrapper(const OwnedWrapper& other) { 1.341 + ptr_ = other.ptr_; 1.342 + other.ptr_ = NULL; 1.343 + } 1.344 + 1.345 + private: 1.346 + mutable T* ptr_; 1.347 +}; 1.348 + 1.349 +// PassedWrapper is a copyable adapter for a scoper that ignores const. 1.350 +// 1.351 +// It is needed to get around the fact that Bind() takes a const reference to 1.352 +// all its arguments. Because Bind() takes a const reference to avoid 1.353 +// unnecessary copies, it is incompatible with movable-but-not-copyable 1.354 +// types; doing a destructive "move" of the type into Bind() would violate 1.355 +// the const correctness. 1.356 +// 1.357 +// This conundrum cannot be solved without either C++11 rvalue references or 1.358 +// a O(2^n) blowup of Bind() templates to handle each combination of regular 1.359 +// types and movable-but-not-copyable types. Thus we introduce a wrapper type 1.360 +// that is copyable to transmit the correct type information down into 1.361 +// BindState<>. Ignoring const in this type makes sense because it is only 1.362 +// created when we are explicitly trying to do a destructive move. 1.363 +// 1.364 +// Two notes: 1.365 +// 1) PassedWrapper supports any type that has a "Pass()" function. 1.366 +// This is intentional. The whitelisting of which specific types we 1.367 +// support is maintained by CallbackParamTraits<>. 1.368 +// 2) is_valid_ is distinct from NULL because it is valid to bind a "NULL" 1.369 +// scoper to a Callback and allow the Callback to execute once. 1.370 +template <typename T> 1.371 +class PassedWrapper { 1.372 + public: 1.373 + explicit PassedWrapper(T scoper) : is_valid_(true), scoper_(scoper.Pass()) {} 1.374 + PassedWrapper(const PassedWrapper& other) 1.375 + : is_valid_(other.is_valid_), scoper_(other.scoper_.Pass()) { 1.376 + } 1.377 + T Pass() const { 1.378 + CHECK(is_valid_); 1.379 + is_valid_ = false; 1.380 + return scoper_.Pass(); 1.381 + } 1.382 + 1.383 + private: 1.384 + mutable bool is_valid_; 1.385 + mutable T scoper_; 1.386 +}; 1.387 + 1.388 +// Unwrap the stored parameters for the wrappers above. 1.389 +template <typename T> 1.390 +struct UnwrapTraits { 1.391 + typedef const T& ForwardType; 1.392 + static ForwardType Unwrap(const T& o) { return o; } 1.393 +}; 1.394 + 1.395 +template <typename T> 1.396 +struct UnwrapTraits<UnretainedWrapper<T> > { 1.397 + typedef T* ForwardType; 1.398 + static ForwardType Unwrap(UnretainedWrapper<T> unretained) { 1.399 + return unretained.get(); 1.400 + } 1.401 +}; 1.402 + 1.403 +template <typename T> 1.404 +struct UnwrapTraits<ConstRefWrapper<T> > { 1.405 + typedef const T& ForwardType; 1.406 + static ForwardType Unwrap(ConstRefWrapper<T> const_ref) { 1.407 + return const_ref.get(); 1.408 + } 1.409 +}; 1.410 + 1.411 +template <typename T> 1.412 +struct UnwrapTraits<scoped_refptr<T> > { 1.413 + typedef T* ForwardType; 1.414 + static ForwardType Unwrap(const scoped_refptr<T>& o) { return o.get(); } 1.415 +}; 1.416 + 1.417 +template <typename T> 1.418 +struct UnwrapTraits<WeakPtr<T> > { 1.419 + typedef const WeakPtr<T>& ForwardType; 1.420 + static ForwardType Unwrap(const WeakPtr<T>& o) { return o; } 1.421 +}; 1.422 + 1.423 +template <typename T> 1.424 +struct UnwrapTraits<OwnedWrapper<T> > { 1.425 + typedef T* ForwardType; 1.426 + static ForwardType Unwrap(const OwnedWrapper<T>& o) { 1.427 + return o.get(); 1.428 + } 1.429 +}; 1.430 + 1.431 +template <typename T> 1.432 +struct UnwrapTraits<PassedWrapper<T> > { 1.433 + typedef T ForwardType; 1.434 + static T Unwrap(PassedWrapper<T>& o) { 1.435 + return o.Pass(); 1.436 + } 1.437 +}; 1.438 + 1.439 +// Utility for handling different refcounting semantics in the Bind() 1.440 +// function. 1.441 +template <bool is_method, typename T> 1.442 +struct MaybeRefcount; 1.443 + 1.444 +template <typename T> 1.445 +struct MaybeRefcount<false, T> { 1.446 + static void AddRef(const T&) {} 1.447 + static void Release(const T&) {} 1.448 +}; 1.449 + 1.450 +template <typename T, size_t n> 1.451 +struct MaybeRefcount<false, T[n]> { 1.452 + static void AddRef(const T*) {} 1.453 + static void Release(const T*) {} 1.454 +}; 1.455 + 1.456 +template <typename T> 1.457 +struct MaybeRefcount<true, T> { 1.458 + static void AddRef(const T&) {} 1.459 + static void Release(const T&) {} 1.460 +}; 1.461 + 1.462 +template <typename T> 1.463 +struct MaybeRefcount<true, T*> { 1.464 + static void AddRef(T* o) { o->AddRef(); } 1.465 + static void Release(T* o) { o->Release(); } 1.466 +}; 1.467 + 1.468 +// No need to additionally AddRef() and Release() since we are storing a 1.469 +// scoped_refptr<> inside the storage object already. 1.470 +template <typename T> 1.471 +struct MaybeRefcount<true, scoped_refptr<T> > { 1.472 + static void AddRef(const scoped_refptr<T>& o) {} 1.473 + static void Release(const scoped_refptr<T>& o) {} 1.474 +}; 1.475 + 1.476 +template <typename T> 1.477 +struct MaybeRefcount<true, const T*> { 1.478 + static void AddRef(const T* o) { o->AddRef(); } 1.479 + static void Release(const T* o) { o->Release(); } 1.480 +}; 1.481 + 1.482 +// IsWeakMethod is a helper that determine if we are binding a WeakPtr<> to a 1.483 +// method. It is used internally by Bind() to select the correct 1.484 +// InvokeHelper that will no-op itself in the event the WeakPtr<> for 1.485 +// the target object is invalidated. 1.486 +// 1.487 +// P1 should be the type of the object that will be received of the method. 1.488 +template <bool IsMethod, typename P1> 1.489 +struct IsWeakMethod : public false_type {}; 1.490 + 1.491 +template <typename T> 1.492 +struct IsWeakMethod<true, WeakPtr<T> > : public true_type {}; 1.493 + 1.494 +template <typename T> 1.495 +struct IsWeakMethod<true, ConstRefWrapper<WeakPtr<T> > > : public true_type {}; 1.496 + 1.497 +} // namespace internal 1.498 + 1.499 +template <typename T> 1.500 +static inline internal::UnretainedWrapper<T> Unretained(T* o) { 1.501 + return internal::UnretainedWrapper<T>(o); 1.502 +} 1.503 + 1.504 +template <typename T> 1.505 +static inline internal::ConstRefWrapper<T> ConstRef(const T& o) { 1.506 + return internal::ConstRefWrapper<T>(o); 1.507 +} 1.508 + 1.509 +template <typename T> 1.510 +static inline internal::OwnedWrapper<T> Owned(T* o) { 1.511 + return internal::OwnedWrapper<T>(o); 1.512 +} 1.513 + 1.514 +// We offer 2 syntaxes for calling Passed(). The first takes a temporary and 1.515 +// is best suited for use with the return value of a function. The second 1.516 +// takes a pointer to the scoper and is just syntactic sugar to avoid having 1.517 +// to write Passed(scoper.Pass()). 1.518 +template <typename T> 1.519 +static inline internal::PassedWrapper<T> Passed(T scoper) { 1.520 + return internal::PassedWrapper<T>(scoper.Pass()); 1.521 +} 1.522 +template <typename T> 1.523 +static inline internal::PassedWrapper<T> Passed(T* scoper) { 1.524 + return internal::PassedWrapper<T>(scoper->Pass()); 1.525 +} 1.526 + 1.527 +template <typename T> 1.528 +static inline internal::IgnoreResultHelper<T> IgnoreResult(T data) { 1.529 + return internal::IgnoreResultHelper<T>(data); 1.530 +} 1.531 + 1.532 +template <typename T> 1.533 +static inline internal::IgnoreResultHelper<Callback<T> > 1.534 +IgnoreResult(const Callback<T>& data) { 1.535 + return internal::IgnoreResultHelper<Callback<T> >(data); 1.536 +} 1.537 + 1.538 +BASE_EXPORT void DoNothing(); 1.539 + 1.540 +template<typename T> 1.541 +void DeletePointer(T* obj) { 1.542 + delete obj; 1.543 +} 1.544 + 1.545 +} // namespace base 1.546 + 1.547 +#endif // BASE_BIND_HELPERS_H_