Introduce BYPASS_PROXY_CONSTMETHOD0.
This allows const getters that query const state to be called without marshalling calls between threads. This must not be used to return pointers/references etc. I'm starting by using this macro with the data channel which has a few of these getters, as well as changing things a bit to make more parts of the implementation, const. Change-Id: I6ec7a3774cd8f7be2ef122fb7c7fc5919afee600 Bug: webrtc:11547 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/176846 Reviewed-by: Karl Wiberg <kwiberg@webrtc.org> Commit-Queue: Tommi <tommi@webrtc.org> Cr-Commit-Position: refs/heads/master@{#31489}
This commit is contained in:
parent
5f7bfbe6c6
commit
0ca13d97d2
11
api/proxy.h
11
api/proxy.h
@ -55,6 +55,7 @@
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <tuple>
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
|
||||
#include "api/scoped_refptr.h"
|
||||
@ -396,6 +397,16 @@ class ConstMethodCall : public rtc::Message, public rtc::MessageHandler {
|
||||
return call.Marshal(RTC_FROM_HERE, worker_thread_); \
|
||||
}
|
||||
|
||||
// For use when returning purely const state (set during construction).
|
||||
// Use with caution. This method should only be used when the return value will
|
||||
// always be the same.
|
||||
#define BYPASS_PROXY_CONSTMETHOD0(r, method) \
|
||||
r method() const override { \
|
||||
static_assert(!std::is_pointer<r>::value, "Type is a pointer"); \
|
||||
static_assert(!std::is_reference<r>::value, "Type is a reference"); \
|
||||
return c_->method(); \
|
||||
}
|
||||
|
||||
} // namespace webrtc
|
||||
|
||||
#endif // API_PROXY_H_
|
||||
|
||||
@ -139,9 +139,9 @@ rtc::scoped_refptr<DataChannel> DataChannel::Create(
|
||||
const std::string& label,
|
||||
const InternalDataChannelInit& config) {
|
||||
rtc::scoped_refptr<DataChannel> channel(
|
||||
new rtc::RefCountedObject<DataChannel>(provider, dct, label));
|
||||
if (!channel->Init(config)) {
|
||||
return NULL;
|
||||
new rtc::RefCountedObject<DataChannel>(config, provider, dct, label));
|
||||
if (!channel->Init()) {
|
||||
return nullptr;
|
||||
}
|
||||
return channel;
|
||||
}
|
||||
@ -152,11 +152,13 @@ bool DataChannel::IsSctpLike(cricket::DataChannelType type) {
|
||||
type == cricket::DCT_DATA_CHANNEL_TRANSPORT_SCTP;
|
||||
}
|
||||
|
||||
DataChannel::DataChannel(DataChannelProviderInterface* provider,
|
||||
DataChannel::DataChannel(const InternalDataChannelInit& config,
|
||||
DataChannelProviderInterface* provider,
|
||||
cricket::DataChannelType dct,
|
||||
const std::string& label)
|
||||
: internal_id_(GenerateUniqueId()),
|
||||
label_(label),
|
||||
config_(config),
|
||||
observer_(nullptr),
|
||||
state_(kConnecting),
|
||||
messages_sent_(0),
|
||||
@ -174,29 +176,28 @@ DataChannel::DataChannel(DataChannelProviderInterface* provider,
|
||||
send_ssrc_(0),
|
||||
receive_ssrc_(0) {}
|
||||
|
||||
bool DataChannel::Init(const InternalDataChannelInit& config) {
|
||||
bool DataChannel::Init() {
|
||||
if (data_channel_type_ == cricket::DCT_RTP) {
|
||||
if (config.reliable || config.id != -1 || config.maxRetransmits ||
|
||||
config.maxRetransmitTime) {
|
||||
if (config_.reliable || config_.id != -1 || config_.maxRetransmits ||
|
||||
config_.maxRetransmitTime) {
|
||||
RTC_LOG(LS_ERROR) << "Failed to initialize the RTP data channel due to "
|
||||
"invalid DataChannelInit.";
|
||||
return false;
|
||||
}
|
||||
handshake_state_ = kHandshakeReady;
|
||||
} else if (IsSctpLike(data_channel_type_)) {
|
||||
if (config.id < -1 ||
|
||||
(config.maxRetransmits && *config.maxRetransmits < 0) ||
|
||||
(config.maxRetransmitTime && *config.maxRetransmitTime < 0)) {
|
||||
if (config_.id < -1 ||
|
||||
(config_.maxRetransmits && *config_.maxRetransmits < 0) ||
|
||||
(config_.maxRetransmitTime && *config_.maxRetransmitTime < 0)) {
|
||||
RTC_LOG(LS_ERROR) << "Failed to initialize the SCTP data channel due to "
|
||||
"invalid DataChannelInit.";
|
||||
return false;
|
||||
}
|
||||
if (config.maxRetransmits && config.maxRetransmitTime) {
|
||||
if (config_.maxRetransmits && config_.maxRetransmitTime) {
|
||||
RTC_LOG(LS_ERROR)
|
||||
<< "maxRetransmits and maxRetransmitTime should not be both set.";
|
||||
return false;
|
||||
}
|
||||
config_ = config;
|
||||
|
||||
switch (config_.open_handshake_role) {
|
||||
case webrtc::InternalDataChannelInit::kNone: // pre-negotiated
|
||||
@ -323,7 +324,7 @@ void DataChannel::SetSctpSid(int sid) {
|
||||
return;
|
||||
}
|
||||
|
||||
config_.id = sid;
|
||||
const_cast<InternalDataChannelInit&>(config_).id = sid;
|
||||
provider_->AddSctpDataStream(sid);
|
||||
}
|
||||
|
||||
|
||||
@ -54,6 +54,8 @@ class DataChannelProviderInterface {
|
||||
virtual ~DataChannelProviderInterface() {}
|
||||
};
|
||||
|
||||
// TODO(tommi): Change to not inherit from DataChannelInit but to have it as
|
||||
// a const member. Block access to the 'id' member since it cannot be const.
|
||||
struct InternalDataChannelInit : public DataChannelInit {
|
||||
enum OpenHandshakeRole { kOpener, kAcker, kNone };
|
||||
// The default role is kOpener because the default |negotiated| is false.
|
||||
@ -229,7 +231,8 @@ class DataChannel : public DataChannelInterface, public sigslot::has_slots<> {
|
||||
static void ResetInternalIdAllocatorForTesting(int new_value);
|
||||
|
||||
protected:
|
||||
DataChannel(DataChannelProviderInterface* client,
|
||||
DataChannel(const InternalDataChannelInit& config,
|
||||
DataChannelProviderInterface* client,
|
||||
cricket::DataChannelType dct,
|
||||
const std::string& label);
|
||||
virtual ~DataChannel();
|
||||
@ -266,7 +269,7 @@ class DataChannel : public DataChannelInterface, public sigslot::has_slots<> {
|
||||
kHandshakeReady
|
||||
};
|
||||
|
||||
bool Init(const InternalDataChannelInit& config);
|
||||
bool Init();
|
||||
void UpdateState();
|
||||
void SetState(DataState state);
|
||||
void DisconnectFromProvider();
|
||||
@ -282,8 +285,8 @@ class DataChannel : public DataChannelInterface, public sigslot::has_slots<> {
|
||||
bool SendControlMessage(const rtc::CopyOnWriteBuffer& buffer);
|
||||
|
||||
const int internal_id_;
|
||||
std::string label_;
|
||||
InternalDataChannelInit config_;
|
||||
const std::string label_;
|
||||
const InternalDataChannelInit config_;
|
||||
DataChannelObserver* observer_;
|
||||
DataState state_;
|
||||
RTCError error_;
|
||||
@ -294,7 +297,7 @@ class DataChannel : public DataChannelInterface, public sigslot::has_slots<> {
|
||||
// Number of bytes of data that have been queued using Send(). Increased
|
||||
// before each transport send and decreased after each successful send.
|
||||
uint64_t buffered_amount_;
|
||||
cricket::DataChannelType data_channel_type_;
|
||||
const cricket::DataChannelType data_channel_type_;
|
||||
DataChannelProviderInterface* provider_;
|
||||
HandshakeState handshake_state_;
|
||||
bool connected_to_provider_;
|
||||
@ -318,17 +321,18 @@ BEGIN_SIGNALING_PROXY_MAP(DataChannel)
|
||||
PROXY_SIGNALING_THREAD_DESTRUCTOR()
|
||||
PROXY_METHOD1(void, RegisterObserver, DataChannelObserver*)
|
||||
PROXY_METHOD0(void, UnregisterObserver)
|
||||
PROXY_CONSTMETHOD0(std::string, label)
|
||||
PROXY_CONSTMETHOD0(bool, reliable)
|
||||
PROXY_CONSTMETHOD0(bool, ordered)
|
||||
PROXY_CONSTMETHOD0(uint16_t, maxRetransmitTime)
|
||||
PROXY_CONSTMETHOD0(uint16_t, maxRetransmits)
|
||||
PROXY_CONSTMETHOD0(absl::optional<int>, maxRetransmitsOpt)
|
||||
PROXY_CONSTMETHOD0(absl::optional<int>, maxPacketLifeTime)
|
||||
PROXY_CONSTMETHOD0(std::string, protocol)
|
||||
PROXY_CONSTMETHOD0(bool, negotiated)
|
||||
BYPASS_PROXY_CONSTMETHOD0(std::string, label)
|
||||
BYPASS_PROXY_CONSTMETHOD0(bool, reliable)
|
||||
BYPASS_PROXY_CONSTMETHOD0(bool, ordered)
|
||||
BYPASS_PROXY_CONSTMETHOD0(uint16_t, maxRetransmitTime)
|
||||
BYPASS_PROXY_CONSTMETHOD0(uint16_t, maxRetransmits)
|
||||
BYPASS_PROXY_CONSTMETHOD0(absl::optional<int>, maxRetransmitsOpt)
|
||||
BYPASS_PROXY_CONSTMETHOD0(absl::optional<int>, maxPacketLifeTime)
|
||||
BYPASS_PROXY_CONSTMETHOD0(std::string, protocol)
|
||||
BYPASS_PROXY_CONSTMETHOD0(bool, negotiated)
|
||||
// Can't bypass the proxy since the id may change.
|
||||
PROXY_CONSTMETHOD0(int, id)
|
||||
PROXY_CONSTMETHOD0(Priority, priority)
|
||||
BYPASS_PROXY_CONSTMETHOD0(Priority, priority)
|
||||
PROXY_CONSTMETHOD0(DataState, state)
|
||||
PROXY_CONSTMETHOD0(RTCError, error)
|
||||
PROXY_CONSTMETHOD0(uint32_t, messages_sent)
|
||||
|
||||
@ -22,15 +22,20 @@ class MockDataChannel : public rtc::RefCountedObject<DataChannel> {
|
||||
public:
|
||||
MockDataChannel(int id, DataState state)
|
||||
: MockDataChannel(id, "MockDataChannel", state, "udp", 0, 0, 0, 0) {}
|
||||
MockDataChannel(int id,
|
||||
const std::string& label,
|
||||
DataState state,
|
||||
const std::string& protocol,
|
||||
uint32_t messages_sent,
|
||||
uint64_t bytes_sent,
|
||||
uint32_t messages_received,
|
||||
uint64_t bytes_received)
|
||||
: rtc::RefCountedObject<DataChannel>(nullptr, cricket::DCT_NONE, label) {
|
||||
MockDataChannel(
|
||||
int id,
|
||||
const std::string& label,
|
||||
DataState state,
|
||||
const std::string& protocol,
|
||||
uint32_t messages_sent,
|
||||
uint64_t bytes_sent,
|
||||
uint32_t messages_received,
|
||||
uint64_t bytes_received,
|
||||
const InternalDataChannelInit& config = InternalDataChannelInit())
|
||||
: rtc::RefCountedObject<DataChannel>(config,
|
||||
nullptr,
|
||||
cricket::DCT_NONE,
|
||||
label) {
|
||||
EXPECT_CALL(*this, id()).WillRepeatedly(::testing::Return(id));
|
||||
EXPECT_CALL(*this, state()).WillRepeatedly(::testing::Return(state));
|
||||
EXPECT_CALL(*this, protocol()).WillRepeatedly(::testing::Return(protocol));
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user