Allow DtlsTransport::Information() to be called off-thread
Bug: chromium:907849 Change-Id: I7e89aa21f26cbd858fa9845375681e5e6781fece Reviewed-on: https://webrtc-review.googlesource.com/c/122503 Reviewed-by: Fredrik Solenberg <solenberg@webrtc.org> Reviewed-by: Henrik Boström <hbos@webrtc.org> Commit-Queue: Harald Alvestrand <hta@webrtc.org> Cr-Commit-Position: refs/heads/master@{#26686}
This commit is contained in:
committed by
Commit Bot
parent
068fc359e5
commit
69fb6c8510
@ -55,15 +55,16 @@ class DtlsTransportObserverInterface {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// A DTLS transport, as represented to the outside world.
|
// A DTLS transport, as represented to the outside world.
|
||||||
// This object is created on the signaling thread, and can only be
|
// This object is created on the network thread, and can only be
|
||||||
// accessed on that thread.
|
// accessed on that thread, except for functions explicitly marked otherwise.
|
||||||
// References can be held by other threads, and destruction can therefore
|
// References can be held by other threads, and destruction can therefore
|
||||||
// be initiated by other threads.
|
// be initiated by other threads.
|
||||||
class DtlsTransportInterface : public rtc::RefCountInterface {
|
class DtlsTransportInterface : public rtc::RefCountInterface {
|
||||||
public:
|
public:
|
||||||
// Returns a pointer to the ICE transport that is owned by the DTLS transport.
|
// Returns a pointer to the ICE transport that is owned by the DTLS transport.
|
||||||
virtual rtc::scoped_refptr<IceTransportInterface> ice_transport() = 0;
|
virtual rtc::scoped_refptr<IceTransportInterface> ice_transport() = 0;
|
||||||
// These functions can only be called from the signalling thread.
|
// Returns information on the state of the DtlsTransport.
|
||||||
|
// This function can be called from other threads.
|
||||||
virtual DtlsTransportInformation Information() = 0;
|
virtual DtlsTransportInformation Information() = 0;
|
||||||
// Observer management.
|
// Observer management.
|
||||||
virtual void RegisterObserver(DtlsTransportObserverInterface* observer) = 0;
|
virtual void RegisterObserver(DtlsTransportObserverInterface* observer) = 0;
|
||||||
|
|||||||
@ -43,69 +43,86 @@ DtlsTransportState TranslateState(cricket::DtlsTransportState internal_state) {
|
|||||||
// Implementation of DtlsTransportInterface
|
// Implementation of DtlsTransportInterface
|
||||||
DtlsTransport::DtlsTransport(
|
DtlsTransport::DtlsTransport(
|
||||||
std::unique_ptr<cricket::DtlsTransportInternal> internal)
|
std::unique_ptr<cricket::DtlsTransportInternal> internal)
|
||||||
: signaling_thread_(rtc::Thread::Current()),
|
: owner_thread_(rtc::Thread::Current()),
|
||||||
|
info_(DtlsTransportState::kNew),
|
||||||
internal_dtls_transport_(std::move(internal)) {
|
internal_dtls_transport_(std::move(internal)) {
|
||||||
RTC_DCHECK(internal_dtls_transport_.get());
|
RTC_DCHECK(internal_dtls_transport_.get());
|
||||||
internal_dtls_transport_->SignalDtlsState.connect(
|
internal_dtls_transport_->SignalDtlsState.connect(
|
||||||
this, &DtlsTransport::OnInternalDtlsState);
|
this, &DtlsTransport::OnInternalDtlsState);
|
||||||
ice_transport_ = new rtc::RefCountedObject<IceTransportWithPointer>(
|
ice_transport_ = new rtc::RefCountedObject<IceTransportWithPointer>(
|
||||||
internal_dtls_transport_->ice_transport());
|
internal_dtls_transport_->ice_transport());
|
||||||
|
UpdateInformation();
|
||||||
}
|
}
|
||||||
|
|
||||||
DtlsTransport::~DtlsTransport() {
|
DtlsTransport::~DtlsTransport() {
|
||||||
// We depend on the signaling thread to call Clear() before dropping
|
// We depend on the signaling thread to call Clear() before dropping
|
||||||
// its last reference to this object.
|
// its last reference to this object.
|
||||||
RTC_DCHECK(signaling_thread_->IsCurrent() || !internal_dtls_transport_);
|
RTC_DCHECK(owner_thread_->IsCurrent() || !internal_dtls_transport_);
|
||||||
}
|
}
|
||||||
|
|
||||||
DtlsTransportInformation DtlsTransport::Information() {
|
DtlsTransportInformation DtlsTransport::Information() {
|
||||||
RTC_DCHECK(signaling_thread_->IsCurrent());
|
rtc::CritScope scope(&lock_);
|
||||||
if (internal()) {
|
return info_;
|
||||||
return DtlsTransportInformation(TranslateState(internal()->dtls_state()));
|
|
||||||
} else {
|
|
||||||
return DtlsTransportInformation(DtlsTransportState::kClosed);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void DtlsTransport::RegisterObserver(DtlsTransportObserverInterface* observer) {
|
void DtlsTransport::RegisterObserver(DtlsTransportObserverInterface* observer) {
|
||||||
RTC_DCHECK(signaling_thread_->IsCurrent());
|
RTC_DCHECK_RUN_ON(owner_thread_);
|
||||||
RTC_DCHECK(observer);
|
RTC_DCHECK(observer);
|
||||||
observer_ = observer;
|
observer_ = observer;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DtlsTransport::UnregisterObserver() {
|
void DtlsTransport::UnregisterObserver() {
|
||||||
RTC_DCHECK(signaling_thread_->IsCurrent());
|
RTC_DCHECK_RUN_ON(owner_thread_);
|
||||||
observer_ = nullptr;
|
observer_ = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
rtc::scoped_refptr<IceTransportInterface> DtlsTransport::ice_transport() {
|
rtc::scoped_refptr<IceTransportInterface> DtlsTransport::ice_transport() {
|
||||||
|
RTC_DCHECK_RUN_ON(owner_thread_);
|
||||||
|
rtc::CritScope scope(&lock_);
|
||||||
return ice_transport_;
|
return ice_transport_;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Internal functions
|
// Internal functions
|
||||||
void DtlsTransport::Clear() {
|
void DtlsTransport::Clear() {
|
||||||
RTC_DCHECK(signaling_thread_->IsCurrent());
|
RTC_DCHECK_RUN_ON(owner_thread_);
|
||||||
RTC_DCHECK(internal());
|
RTC_DCHECK(internal());
|
||||||
if (internal()->dtls_state() != cricket::DTLS_TRANSPORT_CLOSED) {
|
bool must_send_event =
|
||||||
internal_dtls_transport_.reset();
|
(internal()->dtls_state() != cricket::DTLS_TRANSPORT_CLOSED);
|
||||||
if (observer_) {
|
// The destructor of cricket::DtlsTransportInternal calls back
|
||||||
observer_->OnStateChange(Information());
|
// into DtlsTransport, so we can't hold the lock while releasing.
|
||||||
}
|
std::unique_ptr<cricket::DtlsTransportInternal> transport_to_release;
|
||||||
} else {
|
{
|
||||||
internal_dtls_transport_.reset();
|
rtc::CritScope scope(&lock_);
|
||||||
|
transport_to_release = std::move(internal_dtls_transport_);
|
||||||
|
ice_transport_->Clear();
|
||||||
|
}
|
||||||
|
UpdateInformation();
|
||||||
|
if (observer_ && must_send_event) {
|
||||||
|
observer_->OnStateChange(Information());
|
||||||
}
|
}
|
||||||
ice_transport_->Clear();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void DtlsTransport::OnInternalDtlsState(
|
void DtlsTransport::OnInternalDtlsState(
|
||||||
cricket::DtlsTransportInternal* transport,
|
cricket::DtlsTransportInternal* transport,
|
||||||
cricket::DtlsTransportState state) {
|
cricket::DtlsTransportState state) {
|
||||||
RTC_DCHECK(signaling_thread_->IsCurrent());
|
RTC_DCHECK_RUN_ON(owner_thread_);
|
||||||
RTC_DCHECK(transport == internal());
|
RTC_DCHECK(transport == internal());
|
||||||
RTC_DCHECK(state == internal()->dtls_state());
|
RTC_DCHECK(state == internal()->dtls_state());
|
||||||
|
UpdateInformation();
|
||||||
if (observer_) {
|
if (observer_) {
|
||||||
observer_->OnStateChange(Information());
|
observer_->OnStateChange(Information());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DtlsTransport::UpdateInformation() {
|
||||||
|
RTC_DCHECK_RUN_ON(owner_thread_);
|
||||||
|
rtc::CritScope scope(&lock_);
|
||||||
|
if (internal_dtls_transport_) {
|
||||||
|
info_ = DtlsTransportInformation(
|
||||||
|
TranslateState(internal_dtls_transport_->dtls_state()));
|
||||||
|
} else {
|
||||||
|
info_ = DtlsTransportInformation(DtlsTransportState::kClosed);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace webrtc
|
} // namespace webrtc
|
||||||
|
|||||||
@ -28,7 +28,11 @@ class IceTransportWithPointer;
|
|||||||
class DtlsTransport : public DtlsTransportInterface,
|
class DtlsTransport : public DtlsTransportInterface,
|
||||||
public sigslot::has_slots<> {
|
public sigslot::has_slots<> {
|
||||||
public:
|
public:
|
||||||
// This object must be constructed on the signaling thread.
|
// This object must be constructed and updated on a consistent thread,
|
||||||
|
// the same thread as the one the cricket::DtlsTransportInternal object
|
||||||
|
// lives on.
|
||||||
|
// The Information() function can be called from a different thread,
|
||||||
|
// such as the signalling thread.
|
||||||
explicit DtlsTransport(
|
explicit DtlsTransport(
|
||||||
std::unique_ptr<cricket::DtlsTransportInternal> internal);
|
std::unique_ptr<cricket::DtlsTransportInternal> internal);
|
||||||
|
|
||||||
@ -39,10 +43,12 @@ class DtlsTransport : public DtlsTransportInterface,
|
|||||||
void Clear();
|
void Clear();
|
||||||
|
|
||||||
cricket::DtlsTransportInternal* internal() {
|
cricket::DtlsTransportInternal* internal() {
|
||||||
|
rtc::CritScope scope(&lock_);
|
||||||
return internal_dtls_transport_.get();
|
return internal_dtls_transport_.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
const cricket::DtlsTransportInternal* internal() const {
|
const cricket::DtlsTransportInternal* internal() const {
|
||||||
|
rtc::CritScope scope(&lock_);
|
||||||
return internal_dtls_transport_.get();
|
return internal_dtls_transport_.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -52,11 +58,16 @@ class DtlsTransport : public DtlsTransportInterface,
|
|||||||
private:
|
private:
|
||||||
void OnInternalDtlsState(cricket::DtlsTransportInternal* transport,
|
void OnInternalDtlsState(cricket::DtlsTransportInternal* transport,
|
||||||
cricket::DtlsTransportState state);
|
cricket::DtlsTransportState state);
|
||||||
|
void UpdateInformation();
|
||||||
|
|
||||||
DtlsTransportObserverInterface* observer_ = nullptr;
|
DtlsTransportObserverInterface* observer_ = nullptr;
|
||||||
rtc::Thread* signaling_thread_;
|
rtc::Thread* owner_thread_;
|
||||||
std::unique_ptr<cricket::DtlsTransportInternal> internal_dtls_transport_;
|
rtc::CriticalSection lock_;
|
||||||
rtc::scoped_refptr<IceTransportWithPointer> ice_transport_;
|
DtlsTransportInformation info_ RTC_GUARDED_BY(lock_);
|
||||||
|
std::unique_ptr<cricket::DtlsTransportInternal> internal_dtls_transport_
|
||||||
|
RTC_GUARDED_BY(lock_);
|
||||||
|
rtc::scoped_refptr<IceTransportWithPointer> ice_transport_
|
||||||
|
RTC_GUARDED_BY(lock_);
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace webrtc
|
} // namespace webrtc
|
||||||
|
|||||||
Reference in New Issue
Block a user