Delete rtc::Bind

Bug: webrtc:11339
Change-Id: Id53d17bbf37a15f482e9eb9f8762d2000c772dcc
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/202250
Reviewed-by: Tommi <tommi@webrtc.org>
Reviewed-by: Mirko Bonadei <mbonadei@webrtc.org>
Reviewed-by: Harald Alvestrand <hta@webrtc.org>
Commit-Queue: Niels Moller <nisse@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#33099}
This commit is contained in:
Niels Möller
2021-01-18 11:35:23 +01:00
committed by Commit Bot
parent 4ea26e5663
commit 1a29a5da84
22 changed files with 46 additions and 625 deletions

View File

@ -120,10 +120,6 @@ specific_include_rules = {
"+rtc_base/async_packet_socket.h", "+rtc_base/async_packet_socket.h",
], ],
"peer_connection_factory_proxy\.h": [
"+rtc_base/bind.h",
],
"peer_connection_interface\.h": [ "peer_connection_interface\.h": [
"+media/base/media_config.h", "+media/base/media_config.h",
"+media/base/media_engine.h", "+media/base/media_engine.h",

View File

@ -17,7 +17,6 @@
#include "api/peer_connection_interface.h" #include "api/peer_connection_interface.h"
#include "api/proxy.h" #include "api/proxy.h"
#include "rtc_base/bind.h"
namespace webrtc { namespace webrtc {

View File

@ -16,7 +16,6 @@
#include "api/video/i010_buffer.h" #include "api/video/i010_buffer.h"
#include "api/video/i420_buffer.h" #include "api/video/i420_buffer.h"
#include "api/video/nv12_buffer.h" #include "api/video/nv12_buffer.h"
#include "rtc_base/bind.h"
#include "rtc_base/time_utils.h" #include "rtc_base/time_utils.h"
#include "test/fake_texture_frame.h" #include "test/fake_texture_frame.h"
#include "test/frame_utils.h" #include "test/frame_utils.h"

View File

@ -14,7 +14,6 @@
#include "modules/audio_device/audio_device_buffer.h" #include "modules/audio_device/audio_device_buffer.h"
#include "modules/audio_device/fine_audio_buffer.h" #include "modules/audio_device/fine_audio_buffer.h"
#include "rtc_base/bind.h"
#include "rtc_base/checks.h" #include "rtc_base/checks.h"
#include "rtc_base/logging.h" #include "rtc_base/logging.h"
#include "rtc_base/time_utils.h" #include "rtc_base/time_utils.h"

View File

@ -19,7 +19,6 @@
#include "api/audio/audio_mixer.h" #include "api/audio/audio_mixer.h"
#include "modules/audio_mixer/default_output_rate_calculator.h" #include "modules/audio_mixer/default_output_rate_calculator.h"
#include "rtc_base/bind.h"
#include "rtc_base/checks.h" #include "rtc_base/checks.h"
#include "rtc_base/strings/string_builder.h" #include "rtc_base/strings/string_builder.h"
#include "rtc_base/task_queue_for_test.h" #include "rtc_base/task_queue_for_test.h"

View File

@ -73,8 +73,7 @@ class FakePacketTransport : public PacketTransportInternal {
if (async_) { if (async_) {
invoker_.AsyncInvokeDelayed<void>( invoker_.AsyncInvokeDelayed<void>(
RTC_FROM_HERE, Thread::Current(), RTC_FROM_HERE, Thread::Current(),
Bind(&FakePacketTransport::SendPacketInternal, this, packet), [this, packet] { SendPacketInternal(packet); }, async_delay_ms_);
async_delay_ms_);
} else { } else {
SendPacketInternal(packet); SendPacketInternal(packet);
} }

View File

@ -4744,12 +4744,6 @@ void SdpOfferAnswerHandler::DestroyDataChannelTransport() {
data_channel_controller()->set_rtp_data_channel(nullptr); data_channel_controller()->set_rtp_data_channel(nullptr);
} }
// Note: Cannot use rtc::Bind to create a functor to invoke because it will
// grab a reference to this PeerConnection. If this is called from the
// PeerConnection destructor, the RefCountedObject vtable will have already
// been destroyed (since it is a subclass of PeerConnection) and using
// rtc::Bind will cause "Pure virtual function called" error to appear.
if (pc_->sctp_mid()) { if (pc_->sctp_mid()) {
RTC_DCHECK_RUN_ON(pc_->signaling_thread()); RTC_DCHECK_RUN_ON(pc_->signaling_thread());
data_channel_controller()->OnTransportChannelClosed(); data_channel_controller()->OnTransportChannelClosed();

View File

@ -87,7 +87,6 @@ rtc_library("rtc_base_approved") {
public_deps = [] # no-presubmit-check TODO(webrtc:8603) public_deps = [] # no-presubmit-check TODO(webrtc:8603)
sources = [ sources = [
"bind.h",
"bit_buffer.cc", "bit_buffer.cc",
"bit_buffer.h", "bit_buffer.h",
"buffer.h", "buffer.h",
@ -1323,7 +1322,6 @@ if (rtc_include_tests) {
sources = [ sources = [
"atomic_ops_unittest.cc", "atomic_ops_unittest.cc",
"base64_unittest.cc", "base64_unittest.cc",
"bind_unittest.cc",
"bit_buffer_unittest.cc", "bit_buffer_unittest.cc",
"bounded_inline_vector_unittest.cc", "bounded_inline_vector_unittest.cc",
"buffer_queue_unittest.cc", "buffer_queue_unittest.cc",

View File

@ -55,7 +55,7 @@ void AsyncInvoker::Flush(Thread* thread, uint32_t id /*= MQID_ANY*/) {
// Run this on |thread| to reduce the number of context switches. // Run this on |thread| to reduce the number of context switches.
if (Thread::Current() != thread) { if (Thread::Current() != thread) {
thread->Invoke<void>(RTC_FROM_HERE, thread->Invoke<void>(RTC_FROM_HERE,
Bind(&AsyncInvoker::Flush, this, thread, id)); [this, thread, id] { Flush(thread, id); });
return; return;
} }

View File

@ -17,7 +17,6 @@
#include "api/scoped_refptr.h" #include "api/scoped_refptr.h"
#include "rtc_base/async_invoker_inl.h" #include "rtc_base/async_invoker_inl.h"
#include "rtc_base/bind.h"
#include "rtc_base/constructor_magic.h" #include "rtc_base/constructor_magic.h"
#include "rtc_base/event.h" #include "rtc_base/event.h"
#include "rtc_base/ref_counted_object.h" #include "rtc_base/ref_counted_object.h"

View File

@ -12,7 +12,6 @@
#define RTC_BASE_ASYNC_INVOKER_INL_H_ #define RTC_BASE_ASYNC_INVOKER_INL_H_
#include "api/scoped_refptr.h" #include "api/scoped_refptr.h"
#include "rtc_base/bind.h"
#include "rtc_base/event.h" #include "rtc_base/event.h"
#include "rtc_base/message_handler.h" #include "rtc_base/message_handler.h"
#include "rtc_base/ref_counted_object.h" #include "rtc_base/ref_counted_object.h"

View File

@ -1,282 +0,0 @@
/*
* Copyright 2012 The WebRTC Project Authors. All rights reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
// Bind() is an overloaded function that converts method calls into function
// objects (aka functors). The method object is captured as a scoped_refptr<> if
// possible, and as a raw pointer otherwise. Any arguments to the method are
// captured by value. The return value of Bind is a stateful, nullary function
// object. Care should be taken about the lifetime of objects captured by
// Bind(); the returned functor knows nothing about the lifetime of a non
// ref-counted method object or any arguments passed by pointer, and calling the
// functor with a destroyed object will surely do bad things.
//
// To prevent the method object from being captured as a scoped_refptr<>, you
// can use Unretained. But this should only be done when absolutely necessary,
// and when the caller knows the extra reference isn't needed.
//
// Example usage:
// struct Foo {
// int Test1() { return 42; }
// int Test2() const { return 52; }
// int Test3(int x) { return x*x; }
// float Test4(int x, float y) { return x + y; }
// };
//
// int main() {
// Foo foo;
// cout << rtc::Bind(&Foo::Test1, &foo)() << endl;
// cout << rtc::Bind(&Foo::Test2, &foo)() << endl;
// cout << rtc::Bind(&Foo::Test3, &foo, 3)() << endl;
// cout << rtc::Bind(&Foo::Test4, &foo, 7, 8.5f)() << endl;
// }
//
// Example usage of ref counted objects:
// struct Bar {
// int AddRef();
// int Release();
//
// void Test() {}
// void BindThis() {
// // The functor passed to AsyncInvoke() will keep this object alive.
// invoker.AsyncInvoke(RTC_FROM_HERE,rtc::Bind(&Bar::Test, this));
// }
// };
//
// int main() {
// rtc::scoped_refptr<Bar> bar = new rtc::RefCountedObject<Bar>();
// auto functor = rtc::Bind(&Bar::Test, bar);
// bar = nullptr;
// // The functor stores an internal scoped_refptr<Bar>, so this is safe.
// functor();
// }
//
#ifndef RTC_BASE_BIND_H_
#define RTC_BASE_BIND_H_
#include <tuple>
#include <type_traits>
#include "api/scoped_refptr.h"
#define NONAME
namespace rtc {
namespace detail {
// This is needed because the template parameters in Bind can't be resolved
// if they're used both as parameters of the function pointer type and as
// parameters to Bind itself: the function pointer parameters are exact
// matches to the function prototype, but the parameters to bind have
// references stripped. This trick allows the compiler to dictate the Bind
// parameter types rather than deduce them.
template <class T>
struct identity {
typedef T type;
};
// IsRefCounted<T>::value will be true for types that can be used in
// rtc::scoped_refptr<T>, i.e. types that implements nullary functions AddRef()
// and Release(), regardless of their return types. AddRef() and Release() can
// be defined in T or any superclass of T.
template <typename T>
class IsRefCounted {
// This is a complex implementation detail done with SFINAE.
// Define types such that sizeof(Yes) != sizeof(No).
struct Yes {
char dummy[1];
};
struct No {
char dummy[2];
};
// Define two overloaded template functions with return types of different
// size. This way, we can use sizeof() on the return type to determine which
// function the compiler would have chosen. One function will be preferred
// over the other if it is possible to create it without compiler errors,
// otherwise the compiler will simply remove it, and default to the less
// preferred function.
template <typename R>
static Yes test(R* r, decltype(r->AddRef(), r->Release(), 42));
template <typename C>
static No test(...);
public:
// Trick the compiler to tell if it's possible to call AddRef() and Release().
static const bool value = sizeof(test<T>((T*)nullptr, 42)) == sizeof(Yes);
};
// TernaryTypeOperator is a helper class to select a type based on a static bool
// value.
template <bool condition, typename IfTrueT, typename IfFalseT>
struct TernaryTypeOperator {};
template <typename IfTrueT, typename IfFalseT>
struct TernaryTypeOperator<true, IfTrueT, IfFalseT> {
typedef IfTrueT type;
};
template <typename IfTrueT, typename IfFalseT>
struct TernaryTypeOperator<false, IfTrueT, IfFalseT> {
typedef IfFalseT type;
};
// PointerType<T>::type will be scoped_refptr<T> for ref counted types, and T*
// otherwise.
template <class T>
struct PointerType {
typedef typename TernaryTypeOperator<IsRefCounted<T>::value,
scoped_refptr<T>,
T*>::type type;
};
template <typename T>
class UnretainedWrapper {
public:
explicit UnretainedWrapper(T* o) : ptr_(o) {}
T* get() const { return ptr_; }
private:
T* ptr_;
};
} // namespace detail
template <typename T>
static inline detail::UnretainedWrapper<T> Unretained(T* o) {
return detail::UnretainedWrapper<T>(o);
}
template <class ObjectT, class MethodT, class R, typename... Args>
class MethodFunctor {
public:
MethodFunctor(MethodT method, ObjectT* object, Args... args)
: method_(method), object_(object), args_(args...) {}
R operator()() const {
return CallMethod(std::index_sequence_for<Args...>());
}
private:
template <size_t... S>
R CallMethod(std::index_sequence<S...>) const {
return (object_->*method_)(std::get<S>(args_)...);
}
MethodT method_;
typename detail::PointerType<ObjectT>::type object_;
typename std::tuple<typename std::remove_reference<Args>::type...> args_;
};
template <class ObjectT, class MethodT, class R, typename... Args>
class UnretainedMethodFunctor {
public:
UnretainedMethodFunctor(MethodT method,
detail::UnretainedWrapper<ObjectT> object,
Args... args)
: method_(method), object_(object.get()), args_(args...) {}
R operator()() const {
return CallMethod(std::index_sequence_for<Args...>());
}
private:
template <size_t... S>
R CallMethod(std::index_sequence<S...>) const {
return (object_->*method_)(std::get<S>(args_)...);
}
MethodT method_;
ObjectT* object_;
typename std::tuple<typename std::remove_reference<Args>::type...> args_;
};
template <class FunctorT, class R, typename... Args>
class Functor {
public:
Functor(const FunctorT& functor, Args... args)
: functor_(functor), args_(args...) {}
R operator()() const {
return CallFunction(std::index_sequence_for<Args...>());
}
private:
template <size_t... S>
R CallFunction(std::index_sequence<S...>) const {
return functor_(std::get<S>(args_)...);
}
FunctorT functor_;
typename std::tuple<typename std::remove_reference<Args>::type...> args_;
};
#define FP_T(x) R (ObjectT::*x)(Args...)
template <class ObjectT, class R, typename... Args>
MethodFunctor<ObjectT, FP_T(NONAME), R, Args...> Bind(
FP_T(method),
ObjectT* object,
typename detail::identity<Args>::type... args) {
return MethodFunctor<ObjectT, FP_T(NONAME), R, Args...>(method, object,
args...);
}
template <class ObjectT, class R, typename... Args>
MethodFunctor<ObjectT, FP_T(NONAME), R, Args...> Bind(
FP_T(method),
const scoped_refptr<ObjectT>& object,
typename detail::identity<Args>::type... args) {
return MethodFunctor<ObjectT, FP_T(NONAME), R, Args...>(method, object.get(),
args...);
}
template <class ObjectT, class R, typename... Args>
UnretainedMethodFunctor<ObjectT, FP_T(NONAME), R, Args...> Bind(
FP_T(method),
detail::UnretainedWrapper<ObjectT> object,
typename detail::identity<Args>::type... args) {
return UnretainedMethodFunctor<ObjectT, FP_T(NONAME), R, Args...>(
method, object, args...);
}
#undef FP_T
#define FP_T(x) R (ObjectT::*x)(Args...) const
template <class ObjectT, class R, typename... Args>
MethodFunctor<const ObjectT, FP_T(NONAME), R, Args...> Bind(
FP_T(method),
const ObjectT* object,
typename detail::identity<Args>::type... args) {
return MethodFunctor<const ObjectT, FP_T(NONAME), R, Args...>(method, object,
args...);
}
template <class ObjectT, class R, typename... Args>
UnretainedMethodFunctor<const ObjectT, FP_T(NONAME), R, Args...> Bind(
FP_T(method),
detail::UnretainedWrapper<const ObjectT> object,
typename detail::identity<Args>::type... args) {
return UnretainedMethodFunctor<const ObjectT, FP_T(NONAME), R, Args...>(
method, object, args...);
}
#undef FP_T
#define FP_T(x) R (*x)(Args...)
template <class R, typename... Args>
Functor<FP_T(NONAME), R, Args...> Bind(
FP_T(function),
typename detail::identity<Args>::type... args) {
return Functor<FP_T(NONAME), R, Args...>(function, args...);
}
#undef FP_T
} // namespace rtc
#undef NONAME
#endif // RTC_BASE_BIND_H_

View File

@ -1,248 +0,0 @@
/*
* Copyright 2004 The WebRTC Project Authors. All rights reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#include "rtc_base/bind.h"
#include <string>
#include "rtc_base/ref_count.h"
#include "rtc_base/ref_counted_object.h"
#include "test/gtest.h"
namespace rtc {
namespace {
struct LifeTimeCheck;
struct MethodBindTester {
void NullaryVoid() { ++call_count; }
int NullaryInt() {
++call_count;
return 1;
}
int NullaryConst() const {
++call_count;
return 2;
}
void UnaryVoid(int dummy) { ++call_count; }
template <class T>
T Identity(T value) {
++call_count;
return value;
}
int UnaryByPointer(int* value) const {
++call_count;
return ++(*value);
}
int UnaryByRef(const int& value) const {
++call_count;
return ++const_cast<int&>(value);
}
int Multiply(int a, int b) const {
++call_count;
return a * b;
}
void RefArgument(const scoped_refptr<LifeTimeCheck>& object) {
EXPECT_TRUE(object.get() != nullptr);
}
mutable int call_count;
};
struct A {
int dummy;
};
struct B : public RefCountInterface {
int dummy;
};
struct C : public A, B {};
struct D {
int AddRef();
};
struct E : public D {
int Release();
};
struct F {
void AddRef();
void Release();
};
struct LifeTimeCheck {
LifeTimeCheck() : ref_count_(0) {}
void AddRef() { ++ref_count_; }
void Release() { --ref_count_; }
void NullaryVoid() {}
int ref_count_;
};
int Return42() {
return 42;
}
int Negate(int a) {
return -a;
}
int Multiply(int a, int b) {
return a * b;
}
} // namespace
// Try to catch any problem with scoped_refptr type deduction in rtc::Bind at
// compile time.
#define EXPECT_IS_CAPTURED_AS_PTR(T) \
static_assert(std::is_same<detail::PointerType<T>::type, T*>::value, \
"PointerType")
#define EXPECT_IS_CAPTURED_AS_SCOPED_REFPTR(T) \
static_assert( \
std::is_same<detail::PointerType<T>::type, scoped_refptr<T>>::value, \
"PointerType")
EXPECT_IS_CAPTURED_AS_PTR(void);
EXPECT_IS_CAPTURED_AS_PTR(int);
EXPECT_IS_CAPTURED_AS_PTR(double);
EXPECT_IS_CAPTURED_AS_PTR(A);
EXPECT_IS_CAPTURED_AS_PTR(D);
EXPECT_IS_CAPTURED_AS_PTR(RefCountInterface*);
EXPECT_IS_CAPTURED_AS_PTR(
decltype(Unretained<RefCountedObject<RefCountInterface>>));
EXPECT_IS_CAPTURED_AS_SCOPED_REFPTR(RefCountInterface);
EXPECT_IS_CAPTURED_AS_SCOPED_REFPTR(B);
EXPECT_IS_CAPTURED_AS_SCOPED_REFPTR(C);
EXPECT_IS_CAPTURED_AS_SCOPED_REFPTR(E);
EXPECT_IS_CAPTURED_AS_SCOPED_REFPTR(F);
EXPECT_IS_CAPTURED_AS_SCOPED_REFPTR(RefCountedObject<RefCountInterface>);
EXPECT_IS_CAPTURED_AS_SCOPED_REFPTR(RefCountedObject<B>);
EXPECT_IS_CAPTURED_AS_SCOPED_REFPTR(RefCountedObject<C>);
EXPECT_IS_CAPTURED_AS_SCOPED_REFPTR(const RefCountedObject<RefCountInterface>);
TEST(BindTest, BindToMethod) {
MethodBindTester object = {0};
EXPECT_EQ(0, object.call_count);
Bind(&MethodBindTester::NullaryVoid, &object)();
EXPECT_EQ(1, object.call_count);
EXPECT_EQ(1, Bind(&MethodBindTester::NullaryInt, &object)());
EXPECT_EQ(2, object.call_count);
EXPECT_EQ(2, Bind(&MethodBindTester::NullaryConst,
static_cast<const MethodBindTester*>(&object))());
EXPECT_EQ(3, object.call_count);
Bind(&MethodBindTester::UnaryVoid, &object, 5)();
EXPECT_EQ(4, object.call_count);
EXPECT_EQ(100, Bind(&MethodBindTester::Identity<int>, &object, 100)());
EXPECT_EQ(5, object.call_count);
const std::string string_value("test string");
EXPECT_EQ(string_value, Bind(&MethodBindTester::Identity<std::string>,
&object, string_value)());
EXPECT_EQ(6, object.call_count);
int value = 11;
// Bind binds by value, even if the method signature is by reference, so
// "reference" binds require pointers.
EXPECT_EQ(12, Bind(&MethodBindTester::UnaryByPointer, &object, &value)());
EXPECT_EQ(12, value);
EXPECT_EQ(7, object.call_count);
// It's possible to bind to a function that takes a const reference, though
// the capture will be a copy. See UnaryByRef hackery above where it removes
// the const to make sure the underlying storage is, in fact, a copy.
EXPECT_EQ(13, Bind(&MethodBindTester::UnaryByRef, &object, value)());
// But the original value is unmodified.
EXPECT_EQ(12, value);
EXPECT_EQ(8, object.call_count);
EXPECT_EQ(56, Bind(&MethodBindTester::Multiply, &object, 7, 8)());
EXPECT_EQ(9, object.call_count);
}
TEST(BindTest, BindToFunction) {
EXPECT_EQ(42, Bind(&Return42)());
EXPECT_EQ(3, Bind(&Negate, -3)());
EXPECT_EQ(56, Bind(&Multiply, 8, 7)());
}
// Test Bind where method object implements RefCountInterface and is passed as a
// pointer.
TEST(BindTest, CapturePointerAsScopedRefPtr) {
LifeTimeCheck object;
EXPECT_EQ(object.ref_count_, 0);
scoped_refptr<LifeTimeCheck> scoped_object(&object);
EXPECT_EQ(object.ref_count_, 1);
{
auto functor = Bind(&LifeTimeCheck::NullaryVoid, &object);
EXPECT_EQ(object.ref_count_, 2);
scoped_object = nullptr;
EXPECT_EQ(object.ref_count_, 1);
}
EXPECT_EQ(object.ref_count_, 0);
}
// Test Bind where method object implements RefCountInterface and is passed as a
// scoped_refptr<>.
TEST(BindTest, CaptureScopedRefPtrAsScopedRefPtr) {
LifeTimeCheck object;
EXPECT_EQ(object.ref_count_, 0);
scoped_refptr<LifeTimeCheck> scoped_object(&object);
EXPECT_EQ(object.ref_count_, 1);
{
auto functor = Bind(&LifeTimeCheck::NullaryVoid, scoped_object);
EXPECT_EQ(object.ref_count_, 2);
scoped_object = nullptr;
EXPECT_EQ(object.ref_count_, 1);
}
EXPECT_EQ(object.ref_count_, 0);
}
// Test Bind where method object is captured as scoped_refptr<> and the functor
// dies while there are references left.
TEST(BindTest, FunctorReleasesObjectOnDestruction) {
LifeTimeCheck object;
EXPECT_EQ(object.ref_count_, 0);
scoped_refptr<LifeTimeCheck> scoped_object(&object);
EXPECT_EQ(object.ref_count_, 1);
Bind(&LifeTimeCheck::NullaryVoid, &object)();
EXPECT_EQ(object.ref_count_, 1);
scoped_object = nullptr;
EXPECT_EQ(object.ref_count_, 0);
}
// Test Bind with scoped_refptr<> argument.
TEST(BindTest, ScopedRefPointerArgument) {
LifeTimeCheck object;
EXPECT_EQ(object.ref_count_, 0);
scoped_refptr<LifeTimeCheck> scoped_object(&object);
EXPECT_EQ(object.ref_count_, 1);
{
MethodBindTester bind_tester;
auto functor =
Bind(&MethodBindTester::RefArgument, &bind_tester, scoped_object);
EXPECT_EQ(object.ref_count_, 2);
}
EXPECT_EQ(object.ref_count_, 1);
scoped_object = nullptr;
EXPECT_EQ(object.ref_count_, 0);
}
namespace {
const int* Ref(const int& a) {
return &a;
}
} // anonymous namespace
// Test Bind with non-scoped_refptr<> reference argument, which should be
// modified to a non-reference capture.
TEST(BindTest, RefArgument) {
const int x = 42;
EXPECT_EQ(&x, Ref(x));
// Bind() should make a copy of |x|, i.e. the pointers should be different.
auto functor = Bind(&Ref, x);
EXPECT_NE(&x, functor());
}
} // namespace rtc

View File

@ -11,7 +11,6 @@
#include <type_traits> #include <type_traits>
#include "api/function_view.h" #include "api/function_view.h"
#include "rtc_base/bind.h"
#include "rtc_base/callback_list.h" #include "rtc_base/callback_list.h"
#include "test/gtest.h" #include "test/gtest.h"
@ -209,8 +208,6 @@ TEST(CallbackList, MemberFunctionTest) {
} }
// todo(glahiru): Add a test case to catch some error for Karl's first fix // todo(glahiru): Add a test case to catch some error for Karl's first fix
// todo(glahiru): Add a test for rtc::Bind
// which used the following code in the Send
TEST(CallbackList, RemoveOneReceiver) { TEST(CallbackList, RemoveOneReceiver) {
int removal_tag[2]; int removal_tag[2];

View File

@ -10,7 +10,6 @@
#include "rtc_base/callback.h" #include "rtc_base/callback.h"
#include "rtc_base/bind.h"
#include "rtc_base/keep_ref_until_done.h" #include "rtc_base/keep_ref_until_done.h"
#include "rtc_base/ref_count.h" #include "rtc_base/ref_count.h"
#include "test/gtest.h" #include "test/gtest.h"
@ -30,11 +29,6 @@ void i(int& x) {
x *= x; x *= x;
} // NOLINT: Testing refs } // NOLINT: Testing refs
struct BindTester {
int a() { return 24; }
int b(int x) const { return x * x; }
};
class RefCountedBindTester : public RefCountInterface { class RefCountedBindTester : public RefCountInterface {
public: public:
RefCountedBindTester() : count_(0) {} RefCountedBindTester() : count_(0) {}
@ -89,19 +83,6 @@ TEST(CallbackTest, OneParam) {
EXPECT_EQ(81, x); EXPECT_EQ(81, x);
} }
TEST(CallbackTest, WithBind) {
BindTester t;
Callback0<int> cb1 = Bind(&BindTester::a, &t);
EXPECT_EQ(24, cb1());
EXPECT_EQ(24, cb1());
cb1 = Bind(&BindTester::b, &t, 10);
EXPECT_EQ(100, cb1());
EXPECT_EQ(100, cb1());
cb1 = Bind(&BindTester::b, &t, 5);
EXPECT_EQ(25, cb1());
EXPECT_EQ(25, cb1());
}
TEST(KeepRefUntilDoneTest, simple) { TEST(KeepRefUntilDoneTest, simple) {
RefCountedBindTester t; RefCountedBindTester t;
EXPECT_EQ(0, t.RefCount()); EXPECT_EQ(0, t.RefCount());

View File

@ -16,7 +16,6 @@
#include <utility> #include <utility>
#include <vector> #include <vector>
#include "rtc_base/bind.h"
#include "rtc_base/event.h" #include "rtc_base/event.h"
#include "rtc_base/gunit.h" #include "rtc_base/gunit.h"
#include "rtc_base/thread.h" #include "rtc_base/thread.h"

View File

@ -21,7 +21,6 @@
#include <vector> #include <vector>
#include "absl/memory/memory.h" #include "absl/memory/memory.h"
#include "rtc_base/bind.h"
#include "rtc_base/event.h" #include "rtc_base/event.h"
#include "rtc_base/task_queue_for_test.h" #include "rtc_base/task_queue_for_test.h"
#include "rtc_base/time_utils.h" #include "rtc_base/time_utils.h"
@ -67,7 +66,7 @@ TEST(TaskQueueTest, DISABLED_PostDelayedHighRes) {
webrtc::TaskQueueForTest queue(kQueueName, TaskQueue::Priority::HIGH); webrtc::TaskQueueForTest queue(kQueueName, TaskQueue::Priority::HIGH);
uint32_t start = Time(); uint32_t start = Time();
queue.PostDelayedTask(Bind(&CheckCurrent, &event, &queue), 3); queue.PostDelayedTask([&event, &queue] { CheckCurrent(&event, &queue); }, 3);
EXPECT_TRUE(event.Wait(1000)); EXPECT_TRUE(event.Wait(1000));
uint32_t end = TimeMillis(); uint32_t end = TimeMillis();
// These tests are a little relaxed due to how "powerful" our test bots can // These tests are a little relaxed due to how "powerful" our test bots can

View File

@ -20,7 +20,7 @@
namespace webrtc { namespace webrtc {
namespace webrtc_new_closure_impl { namespace webrtc_new_closure_impl {
// Simple implementation of QueuedTask for use with rtc::Bind and lambdas. // Simple implementation of QueuedTask for use with lambdas.
template <typename Closure> template <typename Closure>
class ClosureTask : public QueuedTask { class ClosureTask : public QueuedTask {
public: public:

View File

@ -433,7 +433,7 @@ TEST(ThreadTest, ThreeThreadsInvoke) {
struct LocalFuncs { struct LocalFuncs {
static void Set(LockedBool* out) { out->Set(true); } static void Set(LockedBool* out) { out->Set(true); }
static void InvokeSet(Thread* thread, LockedBool* out) { static void InvokeSet(Thread* thread, LockedBool* out) {
thread->Invoke<void>(RTC_FROM_HERE, Bind(&Set, out)); thread->Invoke<void>(RTC_FROM_HERE, [out] { Set(out); });
} }
// Set |out| true and call InvokeSet on |thread|. // Set |out| true and call InvokeSet on |thread|.
@ -453,8 +453,9 @@ TEST(ThreadTest, ThreeThreadsInvoke) {
LockedBool async_invoked(false); LockedBool async_invoked(false);
invoker->AsyncInvoke<void>( invoker->AsyncInvoke<void>(
RTC_FROM_HERE, thread1, RTC_FROM_HERE, thread1, [&async_invoked, thread2, out] {
Bind(&SetAndInvokeSet, &async_invoked, thread2, out)); SetAndInvokeSet(&async_invoked, thread2, out);
});
EXPECT_TRUE_WAIT(async_invoked.Get(), 2000); EXPECT_TRUE_WAIT(async_invoked.Get(), 2000);
} }
@ -466,9 +467,12 @@ TEST(ThreadTest, ThreeThreadsInvoke) {
// Start the sequence A --(invoke)--> B --(async invoke)--> C --(invoke)--> A. // Start the sequence A --(invoke)--> B --(async invoke)--> C --(invoke)--> A.
// Thread B returns when C receives the call and C should be blocked until A // Thread B returns when C receives the call and C should be blocked until A
// starts to process messages. // starts to process messages.
thread_b->Invoke<void>(RTC_FROM_HERE, Thread* thread_c_ptr = thread_c.get();
Bind(&LocalFuncs::AsyncInvokeSetAndWait, &invoker, thread_b->Invoke<void>(
thread_c.get(), thread_a, &thread_a_called)); RTC_FROM_HERE, [&invoker, thread_c_ptr, thread_a, &thread_a_called] {
LocalFuncs::AsyncInvokeSetAndWait(&invoker, thread_c_ptr, thread_a,
&thread_a_called);
});
EXPECT_FALSE(thread_a_called.Get()); EXPECT_FALSE(thread_a_called.Get());
EXPECT_TRUE_WAIT(thread_a_called.Get(), 2000); EXPECT_TRUE_WAIT(thread_a_called.Get(), 2000);
@ -519,8 +523,8 @@ class ThreadQueueTest : public ::testing::Test, public Thread {
// succeed, since our critical sections are reentrant. // succeed, since our critical sections are reentrant.
std::unique_ptr<Thread> worker(Thread::CreateWithSocketServer()); std::unique_ptr<Thread> worker(Thread::CreateWithSocketServer());
worker->Start(); worker->Start();
return worker->Invoke<bool>( return worker->Invoke<bool>(RTC_FROM_HERE,
RTC_FROM_HERE, rtc::Bind(&ThreadQueueTest::IsLocked_Worker, this)); [this] { return IsLocked_Worker(); });
} }
}; };
@ -840,11 +844,6 @@ TEST_F(AsyncInvokeTest, FlushWithIds) {
EXPECT_TRUE(flag2.get()); EXPECT_TRUE(flag2.get());
} }
void ThreadIsCurrent(Thread* thread, bool* result, Event* event) {
*result = thread->IsCurrent();
event->Set();
}
void WaitAndSetEvent(Event* wait_event, Event* set_event) { void WaitAndSetEvent(Event* wait_event, Event* set_event) {
wait_event->Wait(Event::kForever); wait_event->Wait(Event::kForever);
set_event->Set(); set_event->Set();
@ -909,15 +908,6 @@ class DestructionFunctor {
bool was_invoked_ = false; bool was_invoked_ = false;
}; };
TEST(ThreadPostTaskTest, InvokesWithBind) {
std::unique_ptr<rtc::Thread> background_thread(rtc::Thread::Create());
background_thread->Start();
Event event;
background_thread->PostTask(RTC_FROM_HERE, Bind(&Event::Set, &event));
event.Wait(Event::kForever);
}
TEST(ThreadPostTaskTest, InvokesWithLambda) { TEST(ThreadPostTaskTest, InvokesWithLambda) {
std::unique_ptr<rtc::Thread> background_thread(rtc::Thread::Create()); std::unique_ptr<rtc::Thread> background_thread(rtc::Thread::Create());
background_thread->Start(); background_thread->Start();
@ -1020,9 +1010,13 @@ TEST(ThreadPostTaskTest, InvokesOnBackgroundThread) {
Event event; Event event;
bool was_invoked_on_background_thread = false; bool was_invoked_on_background_thread = false;
background_thread->PostTask(RTC_FROM_HERE, Thread* background_thread_ptr = background_thread.get();
Bind(&ThreadIsCurrent, background_thread.get(), background_thread->PostTask(
&was_invoked_on_background_thread, &event)); RTC_FROM_HERE,
[background_thread_ptr, &was_invoked_on_background_thread, &event] {
was_invoked_on_background_thread = background_thread_ptr->IsCurrent();
event.Set();
});
event.Wait(Event::kForever); event.Wait(Event::kForever);
EXPECT_TRUE(was_invoked_on_background_thread); EXPECT_TRUE(was_invoked_on_background_thread);
@ -1036,9 +1030,10 @@ TEST(ThreadPostTaskTest, InvokesAsynchronously) {
// thread. The second event ensures that the message is processed. // thread. The second event ensures that the message is processed.
Event event_set_by_test_thread; Event event_set_by_test_thread;
Event event_set_by_background_thread; Event event_set_by_background_thread;
background_thread->PostTask(RTC_FROM_HERE, background_thread->PostTask(RTC_FROM_HERE, [&event_set_by_test_thread,
Bind(&WaitAndSetEvent, &event_set_by_test_thread, &event_set_by_background_thread] {
&event_set_by_background_thread)); WaitAndSetEvent(&event_set_by_test_thread, &event_set_by_background_thread);
});
event_set_by_test_thread.Set(); event_set_by_test_thread.Set();
event_set_by_background_thread.Wait(Event::kForever); event_set_by_background_thread.Wait(Event::kForever);
} }
@ -1052,12 +1047,12 @@ TEST(ThreadPostTaskTest, InvokesInPostedOrder) {
Event third; Event third;
Event fourth; Event fourth;
background_thread->PostTask(RTC_FROM_HERE, background_thread->PostTask(
Bind(&WaitAndSetEvent, &first, &second)); RTC_FROM_HERE, [&first, &second] { WaitAndSetEvent(&first, &second); });
background_thread->PostTask(RTC_FROM_HERE, background_thread->PostTask(
Bind(&WaitAndSetEvent, &second, &third)); RTC_FROM_HERE, [&second, &third] { WaitAndSetEvent(&second, &third); });
background_thread->PostTask(RTC_FROM_HERE, background_thread->PostTask(
Bind(&WaitAndSetEvent, &third, &fourth)); RTC_FROM_HERE, [&third, &fourth] { WaitAndSetEvent(&third, &fourth); });
// All tasks have been posted before the first one is unblocked. // All tasks have been posted before the first one is unblocked.
first.Set(); first.Set();
@ -1075,8 +1070,10 @@ TEST(ThreadPostDelayedTaskTest, InvokesAsynchronously) {
Event event_set_by_background_thread; Event event_set_by_background_thread;
background_thread->PostDelayedTask( background_thread->PostDelayedTask(
RTC_FROM_HERE, RTC_FROM_HERE,
Bind(&WaitAndSetEvent, &event_set_by_test_thread, [&event_set_by_test_thread, &event_set_by_background_thread] {
&event_set_by_background_thread), WaitAndSetEvent(&event_set_by_test_thread,
&event_set_by_background_thread);
},
/*milliseconds=*/10); /*milliseconds=*/10);
event_set_by_test_thread.Set(); event_set_by_test_thread.Set();
event_set_by_background_thread.Wait(Event::kForever); event_set_by_background_thread.Wait(Event::kForever);
@ -1092,14 +1089,14 @@ TEST(ThreadPostDelayedTaskTest, InvokesInDelayOrder) {
Event third; Event third;
Event fourth; Event fourth;
background_thread->PostDelayedTask(RTC_FROM_HERE, background_thread->PostDelayedTask(
Bind(&WaitAndSetEvent, &third, &fourth), RTC_FROM_HERE, [&third, &fourth] { WaitAndSetEvent(&third, &fourth); },
/*milliseconds=*/11); /*milliseconds=*/11);
background_thread->PostDelayedTask(RTC_FROM_HERE, background_thread->PostDelayedTask(
Bind(&WaitAndSetEvent, &first, &second), RTC_FROM_HERE, [&first, &second] { WaitAndSetEvent(&first, &second); },
/*milliseconds=*/9); /*milliseconds=*/9);
background_thread->PostDelayedTask(RTC_FROM_HERE, background_thread->PostDelayedTask(
Bind(&WaitAndSetEvent, &second, &third), RTC_FROM_HERE, [&second, &third] { WaitAndSetEvent(&second, &third); },
/*milliseconds=*/10); /*milliseconds=*/10);
// All tasks have been posted before the first one is unblocked. // All tasks have been posted before the first one is unblocked.

View File

@ -14,7 +14,6 @@
#include "api/scoped_refptr.h" #include "api/scoped_refptr.h"
#include "common_video/include/video_frame_buffer.h" #include "common_video/include/video_frame_buffer.h"
#include "rtc_base/bind.h"
#include "rtc_base/checks.h" #include "rtc_base/checks.h"
#include "rtc_base/keep_ref_until_done.h" #include "rtc_base/keep_ref_until_done.h"
#include "rtc_base/logging.h" #include "rtc_base/logging.h"

View File

@ -19,7 +19,6 @@
#include "helpers.h" #include "helpers.h"
#include "modules/audio_device/fine_audio_buffer.h" #include "modules/audio_device/fine_audio_buffer.h"
#include "rtc_base/atomic_ops.h" #include "rtc_base/atomic_ops.h"
#include "rtc_base/bind.h"
#include "rtc_base/checks.h" #include "rtc_base/checks.h"
#include "rtc_base/logging.h" #include "rtc_base/logging.h"
#include "rtc_base/thread.h" #include "rtc_base/thread.h"

View File

@ -17,7 +17,6 @@
#include "absl/types/optional.h" #include "absl/types/optional.h"
#include "api/numerics/samples_stats_counter.h" #include "api/numerics/samples_stats_counter.h"
#include "api/units/data_size.h" #include "api/units/data_size.h"
#include "rtc_base/bind.h"
#include "rtc_base/logging.h" #include "rtc_base/logging.h"
namespace webrtc { namespace webrtc {