mirror of
https://github.com/mollyim/webrtc.git
synced 2025-05-16 07:10:38 +01:00
Fix flaky memory leak in RemoteAudioSource
Bug: webrtc:8405 Change-Id: Ie7c89214323678c6ea34e344bb1a5a33ad46b3f0 Reviewed-on: https://webrtc-review.googlesource.com/13401 Commit-Queue: Steve Anton <steveanton@webrtc.org> Reviewed-by: Taylor Brandstetter <deadbeef@webrtc.org> Cr-Commit-Position: refs/heads/master@{#20362}
This commit is contained in:
parent
dc9ca9329b
commit
3b80aace61
4 changed files with 21 additions and 23 deletions
|
@ -22,22 +22,6 @@
|
|||
|
||||
namespace webrtc {
|
||||
|
||||
class RemoteAudioSource::MessageHandler : public rtc::MessageHandler {
|
||||
public:
|
||||
explicit MessageHandler(RemoteAudioSource* source) : source_(source) {}
|
||||
|
||||
private:
|
||||
~MessageHandler() override {}
|
||||
|
||||
void OnMessage(rtc::Message* msg) override {
|
||||
source_->OnMessage(msg);
|
||||
delete this;
|
||||
}
|
||||
|
||||
const rtc::scoped_refptr<RemoteAudioSource> source_;
|
||||
RTC_DISALLOW_IMPLICIT_CONSTRUCTORS(MessageHandler);
|
||||
};
|
||||
|
||||
class RemoteAudioSource::Sink : public AudioSinkInterface {
|
||||
public:
|
||||
explicit Sink(RemoteAudioSource* source) : source_(source) {}
|
||||
|
@ -148,7 +132,13 @@ void RemoteAudioSource::OnData(const AudioSinkInterface::Data& audio) {
|
|||
void RemoteAudioSource::OnAudioChannelGone() {
|
||||
// Called when the audio channel is deleted. It may be the worker thread
|
||||
// in libjingle or may be a different worker thread.
|
||||
main_thread_->Post(RTC_FROM_HERE, new MessageHandler(this));
|
||||
// This object needs to live long enough for the cleanup logic in OnMessage to
|
||||
// run, so take a reference to it as the data. Sometimes the message may not
|
||||
// be processed (because the thread was destroyed shortly after this call),
|
||||
// but that is fine because the thread destructor will take care of destroying
|
||||
// the message data which will release the reference on RemoteAudioSource.
|
||||
main_thread_->Post(RTC_FROM_HERE, this, 0,
|
||||
new rtc::ScopedRefMessageData<RemoteAudioSource>(this));
|
||||
}
|
||||
|
||||
void RemoteAudioSource::OnMessage(rtc::Message* msg) {
|
||||
|
@ -156,6 +146,9 @@ void RemoteAudioSource::OnMessage(rtc::Message* msg) {
|
|||
sinks_.clear();
|
||||
state_ = MediaSourceInterface::kEnded;
|
||||
FireOnChanged();
|
||||
// Will possibly delete this RemoteAudioSource since it is reference counted
|
||||
// in the message.
|
||||
delete msg->pdata;
|
||||
}
|
||||
|
||||
} // namespace webrtc
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
#include "api/notifier.h"
|
||||
#include "pc/channel.h"
|
||||
#include "rtc_base/criticalsection.h"
|
||||
#include "rtc_base/messagehandler.h"
|
||||
|
||||
namespace rtc {
|
||||
struct Message;
|
||||
|
@ -27,7 +28,8 @@ class Thread;
|
|||
namespace webrtc {
|
||||
|
||||
// This class implements the audio source used by the remote audio track.
|
||||
class RemoteAudioSource : public Notifier<AudioSourceInterface> {
|
||||
class RemoteAudioSource : public Notifier<AudioSourceInterface>,
|
||||
rtc::MessageHandler {
|
||||
public:
|
||||
// Creates an instance of RemoteAudioSource.
|
||||
static rtc::scoped_refptr<RemoteAudioSource> Create(
|
||||
|
@ -61,8 +63,7 @@ class RemoteAudioSource : public Notifier<AudioSourceInterface> {
|
|||
void OnData(const AudioSinkInterface::Data& audio);
|
||||
void OnAudioChannelGone();
|
||||
|
||||
class MessageHandler;
|
||||
void OnMessage(rtc::Message* msg);
|
||||
void OnMessage(rtc::Message* msg) override;
|
||||
|
||||
AudioObserverList audio_observers_;
|
||||
rtc::CriticalSection sink_lock_;
|
||||
|
|
|
@ -529,6 +529,7 @@ AutoThread::AutoThread() : Thread(SocketServer::CreateDefault()) {
|
|||
|
||||
AutoThread::~AutoThread() {
|
||||
Stop();
|
||||
DoDestroy();
|
||||
if (ThreadManager::Instance()->CurrentThread() == this) {
|
||||
ThreadManager::Instance()->SetCurrentThread(nullptr);
|
||||
}
|
||||
|
@ -550,6 +551,12 @@ AutoSocketServerThread::~AutoSocketServerThread() {
|
|||
// P2PTransportChannelPingTest, relying on the message posted in
|
||||
// cricket::Connection::Destroy.
|
||||
ProcessMessages(0);
|
||||
// Stop and destroy the thread before clearing it as the current thread.
|
||||
// Sometimes there are messages left in the MessageQueue that will be
|
||||
// destroyed by DoDestroy, and sometimes the destructors of the message and/or
|
||||
// its contents rely on this thread still being set as the current thread.
|
||||
Stop();
|
||||
DoDestroy();
|
||||
rtc::ThreadManager::Instance()->SetCurrentThread(old_thread_);
|
||||
if (old_thread_) {
|
||||
MessageQueueManager::Add(old_thread_);
|
||||
|
|
|
@ -1,10 +1,7 @@
|
|||
# Tests that are failing when run under memcheck.
|
||||
# https://code.google.com/p/webrtc/issues/detail?id=4387
|
||||
DtmfSenderTest.*
|
||||
PeerConnectionCryptoUnitTest.*
|
||||
PeerConnectionEndToEndTest.*
|
||||
PeerConnectionIceUnitTest.*
|
||||
PeerConnectionIntegrationTest.*
|
||||
PeerConnectionInterfaceTest.*
|
||||
PeerConnectionRtpTest.*
|
||||
RTCStatsIntegrationTest.*
|
||||
|
|
Loading…
Reference in a new issue