mirror of
https://github.com/mollyim/webrtc.git
synced 2025-05-13 13:50:40 +01:00
Proxy: solve event tracing with compile time strings.
This change creates trace events with a single parameter composed of ClassName::Method. The change additionally causes the duration of the proxy call to be traced, not only the occurrence. Fixed: webrtc:12787 Change-Id: I1689862318d4c6fc1dcef343c3ccf3ae9f7e17df Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/219788 Commit-Queue: Markus Handell <handellm@webrtc.org> Reviewed-by: Mirko Bonadei <mbonadei@webrtc.org> Reviewed-by: Tommi <tommi@webrtc.org> Cr-Commit-Position: refs/heads/master@{#34149}
This commit is contained in:
parent
d325f322c7
commit
3d46d0b200
15 changed files with 193 additions and 98 deletions
|
@ -102,7 +102,6 @@ class DtmfSender : public DtmfSenderInterface, public sigslot::has_slots<> {
|
||||||
|
|
||||||
// Define proxy for DtmfSenderInterface.
|
// Define proxy for DtmfSenderInterface.
|
||||||
BEGIN_PRIMARY_PROXY_MAP(DtmfSender)
|
BEGIN_PRIMARY_PROXY_MAP(DtmfSender)
|
||||||
|
|
||||||
PROXY_PRIMARY_THREAD_DESTRUCTOR()
|
PROXY_PRIMARY_THREAD_DESTRUCTOR()
|
||||||
PROXY_METHOD1(void, RegisterObserver, DtmfSenderObserverInterface*)
|
PROXY_METHOD1(void, RegisterObserver, DtmfSenderObserverInterface*)
|
||||||
PROXY_METHOD0(void, UnregisterObserver)
|
PROXY_METHOD0(void, UnregisterObserver)
|
||||||
|
@ -112,7 +111,7 @@ PROXY_CONSTMETHOD0(std::string, tones)
|
||||||
PROXY_CONSTMETHOD0(int, duration)
|
PROXY_CONSTMETHOD0(int, duration)
|
||||||
PROXY_CONSTMETHOD0(int, inter_tone_gap)
|
PROXY_CONSTMETHOD0(int, inter_tone_gap)
|
||||||
PROXY_CONSTMETHOD0(int, comma_delay)
|
PROXY_CONSTMETHOD0(int, comma_delay)
|
||||||
END_PROXY_MAP()
|
END_PROXY_MAP(DtmfSender)
|
||||||
|
|
||||||
// Get DTMF code from the DTMF event character.
|
// Get DTMF code from the DTMF event character.
|
||||||
bool GetDtmfCode(char tone, int* code);
|
bool GetDtmfCode(char tone, int* code);
|
||||||
|
|
|
@ -37,7 +37,7 @@ PROXY_METHOD1(bool, RemoveTrack, AudioTrackInterface*)
|
||||||
PROXY_METHOD1(bool, RemoveTrack, VideoTrackInterface*)
|
PROXY_METHOD1(bool, RemoveTrack, VideoTrackInterface*)
|
||||||
PROXY_METHOD1(void, RegisterObserver, ObserverInterface*)
|
PROXY_METHOD1(void, RegisterObserver, ObserverInterface*)
|
||||||
PROXY_METHOD1(void, UnregisterObserver, ObserverInterface*)
|
PROXY_METHOD1(void, UnregisterObserver, ObserverInterface*)
|
||||||
END_PROXY_MAP()
|
END_PROXY_MAP(MediaStream)
|
||||||
|
|
||||||
} // namespace webrtc
|
} // namespace webrtc
|
||||||
|
|
||||||
|
|
|
@ -37,7 +37,7 @@ PROXY_METHOD0(rtc::scoped_refptr<AudioProcessorInterface>, GetAudioProcessor)
|
||||||
PROXY_METHOD1(bool, set_enabled, bool)
|
PROXY_METHOD1(bool, set_enabled, bool)
|
||||||
PROXY_METHOD1(void, RegisterObserver, ObserverInterface*)
|
PROXY_METHOD1(void, RegisterObserver, ObserverInterface*)
|
||||||
PROXY_METHOD1(void, UnregisterObserver, ObserverInterface*)
|
PROXY_METHOD1(void, UnregisterObserver, ObserverInterface*)
|
||||||
END_PROXY_MAP()
|
END_PROXY_MAP(AudioTrack)
|
||||||
|
|
||||||
BEGIN_PROXY_MAP(VideoTrack)
|
BEGIN_PROXY_MAP(VideoTrack)
|
||||||
PROXY_PRIMARY_THREAD_DESTRUCTOR()
|
PROXY_PRIMARY_THREAD_DESTRUCTOR()
|
||||||
|
@ -57,7 +57,7 @@ BYPASS_PROXY_CONSTMETHOD0(VideoTrackSourceInterface*, GetSource)
|
||||||
|
|
||||||
PROXY_METHOD1(void, RegisterObserver, ObserverInterface*)
|
PROXY_METHOD1(void, RegisterObserver, ObserverInterface*)
|
||||||
PROXY_METHOD1(void, UnregisterObserver, ObserverInterface*)
|
PROXY_METHOD1(void, UnregisterObserver, ObserverInterface*)
|
||||||
END_PROXY_MAP()
|
END_PROXY_MAP(VideoTrack)
|
||||||
|
|
||||||
} // namespace webrtc
|
} // namespace webrtc
|
||||||
|
|
||||||
|
|
|
@ -51,7 +51,7 @@ PROXY_METHOD2(rtc::scoped_refptr<AudioTrackInterface>,
|
||||||
AudioSourceInterface*)
|
AudioSourceInterface*)
|
||||||
PROXY_SECONDARY_METHOD2(bool, StartAecDump, FILE*, int64_t)
|
PROXY_SECONDARY_METHOD2(bool, StartAecDump, FILE*, int64_t)
|
||||||
PROXY_SECONDARY_METHOD0(void, StopAecDump)
|
PROXY_SECONDARY_METHOD0(void, StopAecDump)
|
||||||
END_PROXY_MAP()
|
END_PROXY_MAP(PeerConnectionFactory)
|
||||||
|
|
||||||
} // namespace webrtc
|
} // namespace webrtc
|
||||||
|
|
||||||
|
|
|
@ -157,7 +157,7 @@ PROXY_METHOD1(bool, StartRtcEventLog, std::unique_ptr<RtcEventLogOutput>)
|
||||||
PROXY_METHOD0(void, StopRtcEventLog)
|
PROXY_METHOD0(void, StopRtcEventLog)
|
||||||
PROXY_METHOD0(void, Close)
|
PROXY_METHOD0(void, Close)
|
||||||
BYPASS_PROXY_CONSTMETHOD0(rtc::Thread*, signaling_thread)
|
BYPASS_PROXY_CONSTMETHOD0(rtc::Thread*, signaling_thread)
|
||||||
END_PROXY_MAP()
|
END_PROXY_MAP(PeerConnection)
|
||||||
|
|
||||||
} // namespace webrtc
|
} // namespace webrtc
|
||||||
|
|
||||||
|
|
|
@ -14,8 +14,12 @@
|
||||||
|
|
||||||
namespace webrtc {
|
namespace webrtc {
|
||||||
namespace proxy_internal {
|
namespace proxy_internal {
|
||||||
void TraceApiCall(const char* class_name, const char* method_name) {
|
ScopedTrace::ScopedTrace(const char* class_and_method_name)
|
||||||
TRACE_EVENT1("webrtc", class_name, "method", method_name);
|
: class_and_method_name_(class_and_method_name) {
|
||||||
|
TRACE_EVENT_BEGIN0("webrtc", class_and_method_name_);
|
||||||
|
}
|
||||||
|
ScopedTrace::~ScopedTrace() {
|
||||||
|
TRACE_EVENT_END0("webrtc", class_and_method_name_);
|
||||||
}
|
}
|
||||||
} // namespace proxy_internal
|
} // namespace proxy_internal
|
||||||
} // namespace webrtc
|
} // namespace webrtc
|
||||||
|
|
192
pc/proxy.h
192
pc/proxy.h
|
@ -71,16 +71,30 @@
|
||||||
#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"
|
||||||
|
#include "rtc_base/string_utils.h"
|
||||||
#include "rtc_base/system/rtc_export.h"
|
#include "rtc_base/system/rtc_export.h"
|
||||||
#include "rtc_base/thread.h"
|
#include "rtc_base/thread.h"
|
||||||
|
|
||||||
|
#if !defined(RTC_DISABLE_PROXY_TRACE_EVENTS) && !defined(WEBRTC_CHROMIUM_BUILD)
|
||||||
|
#define RTC_DISABLE_PROXY_TRACE_EVENTS
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace rtc {
|
namespace rtc {
|
||||||
class Location;
|
class Location;
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace webrtc {
|
namespace webrtc {
|
||||||
namespace proxy_internal {
|
namespace proxy_internal {
|
||||||
RTC_EXPORT void TraceApiCall(const char* class_name, const char* method_name);
|
|
||||||
|
// Class for tracing the lifetime of MethodCall::Marshal.
|
||||||
|
class ScopedTrace {
|
||||||
|
public:
|
||||||
|
explicit ScopedTrace(const char* class_and_method_name);
|
||||||
|
~ScopedTrace();
|
||||||
|
|
||||||
|
private:
|
||||||
|
const char* const class_and_method_name_;
|
||||||
|
};
|
||||||
} // namespace proxy_internal
|
} // namespace proxy_internal
|
||||||
|
|
||||||
template <typename R>
|
template <typename R>
|
||||||
|
@ -195,8 +209,8 @@ class ConstMethodCall : public QueuedTask {
|
||||||
template <class INTERNAL_CLASS> \
|
template <class INTERNAL_CLASS> \
|
||||||
class c##ProxyWithInternal : public c##Interface { \
|
class c##ProxyWithInternal : public c##Interface { \
|
||||||
protected: \
|
protected: \
|
||||||
|
static constexpr char proxy_name_[] = #c "Proxy"; \
|
||||||
typedef c##Interface C; \
|
typedef c##Interface C; \
|
||||||
const char* class_name_ = PROXY_STRINGIZE(c); \
|
|
||||||
\
|
\
|
||||||
public: \
|
public: \
|
||||||
const INTERNAL_CLASS* internal() const { return c_; } \
|
const INTERNAL_CLASS* internal() const { return c_; } \
|
||||||
|
@ -205,8 +219,10 @@ class ConstMethodCall : public QueuedTask {
|
||||||
// clang-format off
|
// clang-format off
|
||||||
// clang-format would put the semicolon alone,
|
// clang-format would put the semicolon alone,
|
||||||
// leading to a presubmit error (cpplint.py)
|
// leading to a presubmit error (cpplint.py)
|
||||||
#define END_PROXY_MAP() \
|
#define END_PROXY_MAP(c) \
|
||||||
};
|
}; \
|
||||||
|
template <class INTERNAL_CLASS> \
|
||||||
|
constexpr char c##ProxyWithInternal<INTERNAL_CLASS>::proxy_name_[];
|
||||||
// clang-format on
|
// clang-format on
|
||||||
|
|
||||||
#define PRIMARY_PROXY_MAP_BOILERPLATE(c) \
|
#define PRIMARY_PROXY_MAP_BOILERPLATE(c) \
|
||||||
|
@ -306,53 +322,67 @@ class ConstMethodCall : public QueuedTask {
|
||||||
\
|
\
|
||||||
public: // NOLINTNEXTLINE
|
public: // NOLINTNEXTLINE
|
||||||
|
|
||||||
#define PROXY_METHOD0(r, method) \
|
#if defined(RTC_DISABLE_PROXY_TRACE_EVENTS)
|
||||||
r method() override { \
|
#define TRACE_BOILERPLATE(method) \
|
||||||
proxy_internal::TraceApiCall(class_name_, PROXY_STRINGIZE(method)); \
|
do { \
|
||||||
MethodCall<C, r> call(c_, &C::method); \
|
} while (0)
|
||||||
return call.Marshal(RTC_FROM_HERE, primary_thread_); \
|
#else // if defined(RTC_DISABLE_PROXY_TRACE_EVENTS)
|
||||||
|
#define TRACE_BOILERPLATE(method) \
|
||||||
|
static constexpr auto class_and_method_name = \
|
||||||
|
rtc::MakeCompileTimeString(proxy_name_) \
|
||||||
|
.Concat(rtc::MakeCompileTimeString("::")) \
|
||||||
|
.Concat(rtc::MakeCompileTimeString(#method)); \
|
||||||
|
proxy_internal::ScopedTrace scoped_trace(class_and_method_name.string)
|
||||||
|
|
||||||
|
#endif // if defined(RTC_DISABLE_PROXY_TRACE_EVENTS)
|
||||||
|
|
||||||
|
#define PROXY_METHOD0(r, method) \
|
||||||
|
r method() override { \
|
||||||
|
TRACE_BOILERPLATE(method); \
|
||||||
|
MethodCall<C, r> call(c_, &C::method); \
|
||||||
|
return call.Marshal(RTC_FROM_HERE, primary_thread_); \
|
||||||
}
|
}
|
||||||
|
|
||||||
#define PROXY_CONSTMETHOD0(r, method) \
|
#define PROXY_CONSTMETHOD0(r, method) \
|
||||||
r method() const override { \
|
r method() const override { \
|
||||||
proxy_internal::TraceApiCall(class_name_, PROXY_STRINGIZE(method)); \
|
TRACE_BOILERPLATE(method); \
|
||||||
ConstMethodCall<C, r> call(c_, &C::method); \
|
ConstMethodCall<C, r> call(c_, &C::method); \
|
||||||
return call.Marshal(RTC_FROM_HERE, primary_thread_); \
|
return call.Marshal(RTC_FROM_HERE, primary_thread_); \
|
||||||
}
|
}
|
||||||
|
|
||||||
#define PROXY_METHOD1(r, method, t1) \
|
#define PROXY_METHOD1(r, method, t1) \
|
||||||
r method(t1 a1) override { \
|
r method(t1 a1) override { \
|
||||||
proxy_internal::TraceApiCall(class_name_, PROXY_STRINGIZE(method)); \
|
TRACE_BOILERPLATE(method); \
|
||||||
MethodCall<C, r, t1> call(c_, &C::method, std::move(a1)); \
|
MethodCall<C, r, t1> call(c_, &C::method, std::move(a1)); \
|
||||||
return call.Marshal(RTC_FROM_HERE, primary_thread_); \
|
return call.Marshal(RTC_FROM_HERE, primary_thread_); \
|
||||||
}
|
}
|
||||||
|
|
||||||
#define PROXY_CONSTMETHOD1(r, method, t1) \
|
#define PROXY_CONSTMETHOD1(r, method, t1) \
|
||||||
r method(t1 a1) const override { \
|
r method(t1 a1) const override { \
|
||||||
proxy_internal::TraceApiCall(class_name_, PROXY_STRINGIZE(method)); \
|
TRACE_BOILERPLATE(method); \
|
||||||
ConstMethodCall<C, r, t1> call(c_, &C::method, std::move(a1)); \
|
ConstMethodCall<C, r, t1> call(c_, &C::method, std::move(a1)); \
|
||||||
return call.Marshal(RTC_FROM_HERE, primary_thread_); \
|
return call.Marshal(RTC_FROM_HERE, primary_thread_); \
|
||||||
}
|
}
|
||||||
|
|
||||||
#define PROXY_METHOD2(r, method, t1, t2) \
|
#define PROXY_METHOD2(r, method, t1, t2) \
|
||||||
r method(t1 a1, t2 a2) override { \
|
r method(t1 a1, t2 a2) override { \
|
||||||
proxy_internal::TraceApiCall(class_name_, PROXY_STRINGIZE(method)); \
|
TRACE_BOILERPLATE(method); \
|
||||||
MethodCall<C, r, t1, t2> call(c_, &C::method, std::move(a1), \
|
MethodCall<C, r, t1, t2> call(c_, &C::method, std::move(a1), \
|
||||||
std::move(a2)); \
|
std::move(a2)); \
|
||||||
return call.Marshal(RTC_FROM_HERE, primary_thread_); \
|
return call.Marshal(RTC_FROM_HERE, primary_thread_); \
|
||||||
}
|
}
|
||||||
|
|
||||||
#define PROXY_METHOD3(r, method, t1, t2, t3) \
|
#define PROXY_METHOD3(r, method, t1, t2, t3) \
|
||||||
r method(t1 a1, t2 a2, t3 a3) override { \
|
r method(t1 a1, t2 a2, t3 a3) override { \
|
||||||
proxy_internal::TraceApiCall(class_name_, PROXY_STRINGIZE(method)); \
|
TRACE_BOILERPLATE(method); \
|
||||||
MethodCall<C, r, t1, t2, t3> call(c_, &C::method, std::move(a1), \
|
MethodCall<C, r, t1, t2, t3> call(c_, &C::method, std::move(a1), \
|
||||||
std::move(a2), std::move(a3)); \
|
std::move(a2), std::move(a3)); \
|
||||||
return call.Marshal(RTC_FROM_HERE, primary_thread_); \
|
return call.Marshal(RTC_FROM_HERE, primary_thread_); \
|
||||||
}
|
}
|
||||||
|
|
||||||
#define PROXY_METHOD4(r, method, t1, t2, t3, t4) \
|
#define PROXY_METHOD4(r, method, t1, t2, t3, t4) \
|
||||||
r method(t1 a1, t2 a2, t3 a3, t4 a4) override { \
|
r method(t1 a1, t2 a2, t3 a3, t4 a4) override { \
|
||||||
proxy_internal::TraceApiCall(class_name_, PROXY_STRINGIZE(method)); \
|
TRACE_BOILERPLATE(method); \
|
||||||
MethodCall<C, r, t1, t2, t3, t4> call(c_, &C::method, std::move(a1), \
|
MethodCall<C, r, t1, t2, t3, t4> call(c_, &C::method, std::move(a1), \
|
||||||
std::move(a2), std::move(a3), \
|
std::move(a2), std::move(a3), \
|
||||||
std::move(a4)); \
|
std::move(a4)); \
|
||||||
|
@ -361,7 +391,7 @@ class ConstMethodCall : public QueuedTask {
|
||||||
|
|
||||||
#define PROXY_METHOD5(r, method, t1, t2, t3, t4, t5) \
|
#define PROXY_METHOD5(r, method, t1, t2, t3, t4, t5) \
|
||||||
r method(t1 a1, t2 a2, t3 a3, t4 a4, t5 a5) override { \
|
r method(t1 a1, t2 a2, t3 a3, t4 a4, t5 a5) override { \
|
||||||
proxy_internal::TraceApiCall(class_name_, PROXY_STRINGIZE(method)); \
|
TRACE_BOILERPLATE(method); \
|
||||||
MethodCall<C, r, t1, t2, t3, t4, t5> call(c_, &C::method, std::move(a1), \
|
MethodCall<C, r, t1, t2, t3, t4, t5> call(c_, &C::method, std::move(a1), \
|
||||||
std::move(a2), std::move(a3), \
|
std::move(a2), std::move(a3), \
|
||||||
std::move(a4), std::move(a5)); \
|
std::move(a4), std::move(a5)); \
|
||||||
|
@ -369,61 +399,61 @@ class ConstMethodCall : public QueuedTask {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Define methods which should be invoked on the secondary thread.
|
// Define methods which should be invoked on the secondary thread.
|
||||||
#define PROXY_SECONDARY_METHOD0(r, method) \
|
#define PROXY_SECONDARY_METHOD0(r, method) \
|
||||||
r method() override { \
|
r method() override { \
|
||||||
proxy_internal::TraceApiCall(class_name_, PROXY_STRINGIZE(method)); \
|
TRACE_BOILERPLATE(method); \
|
||||||
MethodCall<C, r> call(c_, &C::method); \
|
MethodCall<C, r> call(c_, &C::method); \
|
||||||
return call.Marshal(RTC_FROM_HERE, secondary_thread_); \
|
return call.Marshal(RTC_FROM_HERE, secondary_thread_); \
|
||||||
}
|
}
|
||||||
|
|
||||||
#define PROXY_SECONDARY_CONSTMETHOD0(r, method) \
|
#define PROXY_SECONDARY_CONSTMETHOD0(r, method) \
|
||||||
r method() const override { \
|
r method() const override { \
|
||||||
proxy_internal::TraceApiCall(class_name_, PROXY_STRINGIZE(method)); \
|
TRACE_BOILERPLATE(method); \
|
||||||
ConstMethodCall<C, r> call(c_, &C::method); \
|
ConstMethodCall<C, r> call(c_, &C::method); \
|
||||||
return call.Marshal(RTC_FROM_HERE, secondary_thread_); \
|
return call.Marshal(RTC_FROM_HERE, secondary_thread_); \
|
||||||
}
|
}
|
||||||
|
|
||||||
#define PROXY_SECONDARY_METHOD1(r, method, t1) \
|
#define PROXY_SECONDARY_METHOD1(r, method, t1) \
|
||||||
r method(t1 a1) override { \
|
r method(t1 a1) override { \
|
||||||
proxy_internal::TraceApiCall(class_name_, PROXY_STRINGIZE(method)); \
|
TRACE_BOILERPLATE(method); \
|
||||||
MethodCall<C, r, t1> call(c_, &C::method, std::move(a1)); \
|
MethodCall<C, r, t1> call(c_, &C::method, std::move(a1)); \
|
||||||
return call.Marshal(RTC_FROM_HERE, secondary_thread_); \
|
return call.Marshal(RTC_FROM_HERE, secondary_thread_); \
|
||||||
}
|
}
|
||||||
|
|
||||||
#define PROXY_SECONDARY_CONSTMETHOD1(r, method, t1) \
|
#define PROXY_SECONDARY_CONSTMETHOD1(r, method, t1) \
|
||||||
r method(t1 a1) const override { \
|
r method(t1 a1) const override { \
|
||||||
proxy_internal::TraceApiCall(class_name_, PROXY_STRINGIZE(method)); \
|
TRACE_BOILERPLATE(method); \
|
||||||
ConstMethodCall<C, r, t1> call(c_, &C::method, std::move(a1)); \
|
ConstMethodCall<C, r, t1> call(c_, &C::method, std::move(a1)); \
|
||||||
return call.Marshal(RTC_FROM_HERE, secondary_thread_); \
|
return call.Marshal(RTC_FROM_HERE, secondary_thread_); \
|
||||||
}
|
}
|
||||||
|
|
||||||
#define PROXY_SECONDARY_METHOD2(r, method, t1, t2) \
|
#define PROXY_SECONDARY_METHOD2(r, method, t1, t2) \
|
||||||
r method(t1 a1, t2 a2) override { \
|
r method(t1 a1, t2 a2) override { \
|
||||||
proxy_internal::TraceApiCall(class_name_, PROXY_STRINGIZE(method)); \
|
TRACE_BOILERPLATE(method); \
|
||||||
MethodCall<C, r, t1, t2> call(c_, &C::method, std::move(a1), \
|
MethodCall<C, r, t1, t2> call(c_, &C::method, std::move(a1), \
|
||||||
std::move(a2)); \
|
std::move(a2)); \
|
||||||
return call.Marshal(RTC_FROM_HERE, secondary_thread_); \
|
return call.Marshal(RTC_FROM_HERE, secondary_thread_); \
|
||||||
}
|
}
|
||||||
|
|
||||||
#define PROXY_SECONDARY_CONSTMETHOD2(r, method, t1, t2) \
|
#define PROXY_SECONDARY_CONSTMETHOD2(r, method, t1, t2) \
|
||||||
r method(t1 a1, t2 a2) const override { \
|
r method(t1 a1, t2 a2) const override { \
|
||||||
proxy_internal::TraceApiCall(class_name_, PROXY_STRINGIZE(method)); \
|
TRACE_BOILERPLATE(method); \
|
||||||
ConstMethodCall<C, r, t1, t2> call(c_, &C::method, std::move(a1), \
|
ConstMethodCall<C, r, t1, t2> call(c_, &C::method, std::move(a1), \
|
||||||
std::move(a2)); \
|
std::move(a2)); \
|
||||||
return call.Marshal(RTC_FROM_HERE, secondary_thread_); \
|
return call.Marshal(RTC_FROM_HERE, secondary_thread_); \
|
||||||
}
|
}
|
||||||
|
|
||||||
#define PROXY_SECONDARY_METHOD3(r, method, t1, t2, t3) \
|
#define PROXY_SECONDARY_METHOD3(r, method, t1, t2, t3) \
|
||||||
r method(t1 a1, t2 a2, t3 a3) override { \
|
r method(t1 a1, t2 a2, t3 a3) override { \
|
||||||
proxy_internal::TraceApiCall(class_name_, PROXY_STRINGIZE(method)); \
|
TRACE_BOILERPLATE(method); \
|
||||||
MethodCall<C, r, t1, t2, t3> call(c_, &C::method, std::move(a1), \
|
MethodCall<C, r, t1, t2, t3> call(c_, &C::method, std::move(a1), \
|
||||||
std::move(a2), std::move(a3)); \
|
std::move(a2), std::move(a3)); \
|
||||||
return call.Marshal(RTC_FROM_HERE, secondary_thread_); \
|
return call.Marshal(RTC_FROM_HERE, secondary_thread_); \
|
||||||
}
|
}
|
||||||
|
|
||||||
#define PROXY_SECONDARY_CONSTMETHOD3(r, method, t1, t2) \
|
#define PROXY_SECONDARY_CONSTMETHOD3(r, method, t1, t2) \
|
||||||
r method(t1 a1, t2 a2, t3 a3) const override { \
|
r method(t1 a1, t2 a2, t3 a3) const override { \
|
||||||
proxy_internal::TraceApiCall(class_name_, PROXY_STRINGIZE(method)); \
|
TRACE_BOILERPLATE(method); \
|
||||||
ConstMethodCall<C, r, t1, t2, t3> call(c_, &C::method, std::move(a1), \
|
ConstMethodCall<C, r, t1, t2, t3> call(c_, &C::method, std::move(a1), \
|
||||||
std::move(a2), std::move(a3)); \
|
std::move(a2), std::move(a3)); \
|
||||||
return call.Marshal(RTC_FROM_HERE, secondary_thread_); \
|
return call.Marshal(RTC_FROM_HERE, secondary_thread_); \
|
||||||
|
@ -432,10 +462,10 @@ class ConstMethodCall : public QueuedTask {
|
||||||
// For use when returning purely const state (set during construction).
|
// For use when returning purely const state (set during construction).
|
||||||
// Use with caution. This method should only be used when the return value will
|
// Use with caution. This method should only be used when the return value will
|
||||||
// always be the same.
|
// always be the same.
|
||||||
#define BYPASS_PROXY_CONSTMETHOD0(r, method) \
|
#define BYPASS_PROXY_CONSTMETHOD0(r, method) \
|
||||||
r method() const override { \
|
r method() const override { \
|
||||||
proxy_internal::TraceApiCall(class_name_, PROXY_STRINGIZE(method)); \
|
TRACE_BOILERPLATE(method); \
|
||||||
return c_->method(); \
|
return c_->method(); \
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace webrtc
|
} // namespace webrtc
|
||||||
|
|
|
@ -71,7 +71,7 @@ PROXY_CONSTMETHOD0(std::string, ConstMethod0)
|
||||||
PROXY_SECONDARY_METHOD1(std::string, Method1, std::string)
|
PROXY_SECONDARY_METHOD1(std::string, Method1, std::string)
|
||||||
PROXY_CONSTMETHOD1(std::string, ConstMethod1, std::string)
|
PROXY_CONSTMETHOD1(std::string, ConstMethod1, std::string)
|
||||||
PROXY_SECONDARY_METHOD2(std::string, Method2, std::string, std::string)
|
PROXY_SECONDARY_METHOD2(std::string, Method2, std::string, std::string)
|
||||||
END_PROXY_MAP()
|
END_PROXY_MAP(Fake)
|
||||||
|
|
||||||
// Preprocessor hack to get a proxy class a name different than FakeProxy.
|
// Preprocessor hack to get a proxy class a name different than FakeProxy.
|
||||||
#define FakeProxy FakeSignalingProxy
|
#define FakeProxy FakeSignalingProxy
|
||||||
|
@ -84,7 +84,7 @@ PROXY_CONSTMETHOD0(std::string, ConstMethod0)
|
||||||
PROXY_METHOD1(std::string, Method1, std::string)
|
PROXY_METHOD1(std::string, Method1, std::string)
|
||||||
PROXY_CONSTMETHOD1(std::string, ConstMethod1, std::string)
|
PROXY_CONSTMETHOD1(std::string, ConstMethod1, std::string)
|
||||||
PROXY_METHOD2(std::string, Method2, std::string, std::string)
|
PROXY_METHOD2(std::string, Method2, std::string, std::string)
|
||||||
END_PROXY_MAP()
|
END_PROXY_MAP(Fake)
|
||||||
#undef FakeProxy
|
#undef FakeProxy
|
||||||
|
|
||||||
class SignalingProxyTest : public ::testing::Test {
|
class SignalingProxyTest : public ::testing::Test {
|
||||||
|
@ -272,7 +272,7 @@ class Foo : public FooInterface {
|
||||||
BEGIN_OWNED_PROXY_MAP(Foo)
|
BEGIN_OWNED_PROXY_MAP(Foo)
|
||||||
PROXY_PRIMARY_THREAD_DESTRUCTOR()
|
PROXY_PRIMARY_THREAD_DESTRUCTOR()
|
||||||
PROXY_METHOD0(void, Bar)
|
PROXY_METHOD0(void, Bar)
|
||||||
END_PROXY_MAP()
|
END_PROXY_MAP(Foo)
|
||||||
|
|
||||||
class OwnedProxyTest : public ::testing::Test {
|
class OwnedProxyTest : public ::testing::Test {
|
||||||
public:
|
public:
|
||||||
|
|
|
@ -47,7 +47,7 @@ PROXY_SECONDARY_CONSTMETHOD0(rtc::scoped_refptr<FrameDecryptorInterface>,
|
||||||
PROXY_SECONDARY_METHOD1(void,
|
PROXY_SECONDARY_METHOD1(void,
|
||||||
SetDepacketizerToDecoderFrameTransformer,
|
SetDepacketizerToDecoderFrameTransformer,
|
||||||
rtc::scoped_refptr<FrameTransformerInterface>)
|
rtc::scoped_refptr<FrameTransformerInterface>)
|
||||||
END_PROXY_MAP()
|
END_PROXY_MAP(RtpReceiver)
|
||||||
|
|
||||||
} // namespace webrtc
|
} // namespace webrtc
|
||||||
|
|
||||||
|
|
|
@ -44,7 +44,7 @@ PROXY_METHOD1(void, SetStreams, const std::vector<std::string>&)
|
||||||
PROXY_METHOD1(void,
|
PROXY_METHOD1(void,
|
||||||
SetEncoderToPacketizerFrameTransformer,
|
SetEncoderToPacketizerFrameTransformer,
|
||||||
rtc::scoped_refptr<FrameTransformerInterface>)
|
rtc::scoped_refptr<FrameTransformerInterface>)
|
||||||
END_PROXY_MAP()
|
END_PROXY_MAP(RtpSender)
|
||||||
|
|
||||||
} // namespace webrtc
|
} // namespace webrtc
|
||||||
|
|
||||||
|
|
|
@ -310,7 +310,7 @@ PROXY_CONSTMETHOD0(std::vector<RtpHeaderExtensionCapability>,
|
||||||
PROXY_METHOD1(webrtc::RTCError,
|
PROXY_METHOD1(webrtc::RTCError,
|
||||||
SetOfferedRtpHeaderExtensions,
|
SetOfferedRtpHeaderExtensions,
|
||||||
rtc::ArrayView<const RtpHeaderExtensionCapability>)
|
rtc::ArrayView<const RtpHeaderExtensionCapability>)
|
||||||
END_PROXY_MAP()
|
END_PROXY_MAP(RtpTransceiver)
|
||||||
|
|
||||||
} // namespace webrtc
|
} // namespace webrtc
|
||||||
|
|
||||||
|
|
|
@ -65,7 +65,7 @@ PROXY_CONSTMETHOD0(uint64_t, buffered_amount)
|
||||||
PROXY_METHOD0(void, Close)
|
PROXY_METHOD0(void, Close)
|
||||||
// TODO(bugs.webrtc.org/11547): Change to run on the network thread.
|
// TODO(bugs.webrtc.org/11547): Change to run on the network thread.
|
||||||
PROXY_METHOD1(bool, Send, const DataBuffer&)
|
PROXY_METHOD1(bool, Send, const DataBuffer&)
|
||||||
END_PROXY_MAP()
|
END_PROXY_MAP(DataChannel)
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
|
|
|
@ -42,7 +42,7 @@ PROXY_SECONDARY_METHOD1(void,
|
||||||
PROXY_SECONDARY_METHOD1(void,
|
PROXY_SECONDARY_METHOD1(void,
|
||||||
RemoveEncodedSink,
|
RemoveEncodedSink,
|
||||||
rtc::VideoSinkInterface<RecordableEncodedFrame>*)
|
rtc::VideoSinkInterface<RecordableEncodedFrame>*)
|
||||||
END_PROXY_MAP()
|
END_PROXY_MAP(VideoTrackSource)
|
||||||
|
|
||||||
} // namespace webrtc
|
} // namespace webrtc
|
||||||
|
|
||||||
|
|
|
@ -88,6 +88,43 @@ std::string string_trim(const std::string& s);
|
||||||
// TODO(jonasolsson): replace with absl::Hex when that becomes available.
|
// TODO(jonasolsson): replace with absl::Hex when that becomes available.
|
||||||
std::string ToHex(const int i);
|
std::string ToHex(const int i);
|
||||||
|
|
||||||
|
// CompileTimeString comprises of a string-like object which can be used as a
|
||||||
|
// regular const char* in compile time and supports concatenation. Useful for
|
||||||
|
// concatenating constexpr strings in for example macro declarations.
|
||||||
|
namespace rtc_base_string_utils_internal {
|
||||||
|
template <int NPlus1>
|
||||||
|
struct CompileTimeString {
|
||||||
|
char string[NPlus1] = {0};
|
||||||
|
constexpr CompileTimeString() = default;
|
||||||
|
template <int MPlus1>
|
||||||
|
explicit constexpr CompileTimeString(const char (&chars)[MPlus1]) {
|
||||||
|
char* chars_pointer = string;
|
||||||
|
for (auto c : chars)
|
||||||
|
*chars_pointer++ = c;
|
||||||
|
}
|
||||||
|
template <int MPlus1>
|
||||||
|
constexpr auto Concat(CompileTimeString<MPlus1> b) {
|
||||||
|
CompileTimeString<NPlus1 + MPlus1 - 1> result;
|
||||||
|
char* chars_pointer = result.string;
|
||||||
|
for (auto c : string)
|
||||||
|
*chars_pointer++ = c;
|
||||||
|
chars_pointer = result.string + NPlus1 - 1;
|
||||||
|
for (auto c : b.string)
|
||||||
|
*chars_pointer++ = c;
|
||||||
|
result.string[NPlus1 + MPlus1 - 2] = 0;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
constexpr operator const char*() { return string; }
|
||||||
|
};
|
||||||
|
} // namespace rtc_base_string_utils_internal
|
||||||
|
|
||||||
|
// Makes a constexpr CompileTimeString<X> without having to specify X
|
||||||
|
// explicitly.
|
||||||
|
template <int N>
|
||||||
|
constexpr auto MakeCompileTimeString(const char (&a)[N]) {
|
||||||
|
return rtc_base_string_utils_internal::CompileTimeString<N>(a);
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace rtc
|
} // namespace rtc
|
||||||
|
|
||||||
#endif // RTC_BASE_STRING_UTILS_H_
|
#endif // RTC_BASE_STRING_UTILS_H_
|
||||||
|
|
|
@ -39,4 +39,29 @@ TEST(string_toutf, Empty) {
|
||||||
|
|
||||||
#endif // WEBRTC_WIN
|
#endif // WEBRTC_WIN
|
||||||
|
|
||||||
|
TEST(CompileTimeString, MakeActsLikeAString) {
|
||||||
|
EXPECT_STREQ(MakeCompileTimeString("abc123"), "abc123");
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(CompileTimeString, ConvertibleToStdString) {
|
||||||
|
EXPECT_EQ(std::string(MakeCompileTimeString("abab")), "abab");
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace detail {
|
||||||
|
constexpr bool StringEquals(const char* a, const char* b) {
|
||||||
|
while (*a && *a == *b)
|
||||||
|
a++, b++;
|
||||||
|
return *a == *b;
|
||||||
|
}
|
||||||
|
} // namespace detail
|
||||||
|
|
||||||
|
static_assert(detail::StringEquals(MakeCompileTimeString("handellm"),
|
||||||
|
"handellm"),
|
||||||
|
"String should initialize.");
|
||||||
|
|
||||||
|
static_assert(detail::StringEquals(MakeCompileTimeString("abc123").Concat(
|
||||||
|
MakeCompileTimeString("def456ghi")),
|
||||||
|
"abc123def456ghi"),
|
||||||
|
"Strings should concatenate.");
|
||||||
|
|
||||||
} // namespace rtc
|
} // namespace rtc
|
||||||
|
|
Loading…
Reference in a new issue