From 8fae865146b624acfb955f974fdbb7e665cf9a8a Mon Sep 17 00:00:00 2001 From: Randell Jesup Date: Wed, 30 Jan 2013 21:26:45 -0500 Subject: [PATCH] Bug 818670: Ensure PipelineListener doesn't release conduit off main thread r=derf --- .../src/mediapipeline/MediaPipeline.h | 33 ++++++++++++++++--- 1 file changed, 29 insertions(+), 4 deletions(-) diff --git a/media/webrtc/signaling/src/mediapipeline/MediaPipeline.h b/media/webrtc/signaling/src/mediapipeline/MediaPipeline.h index 4fcdbbd9038..9a2dbcc4cbe 100644 --- a/media/webrtc/signaling/src/mediapipeline/MediaPipeline.h +++ b/media/webrtc/signaling/src/mediapipeline/MediaPipeline.h @@ -222,6 +222,18 @@ class MediaPipeline : public sigslot::has_slots<> { }; +class ConduitDeleteEvent: public nsRunnable +{ +public: + ConduitDeleteEvent(TemporaryRef aConduit) : + mConduit(aConduit) {} + + /* we exist solely to proxy release of the conduit */ + NS_IMETHOD Run() { return NS_OK; } +private: + RefPtr mConduit; +}; + // A specialization of pipeline for reading from an input device // and transmitting to the network. class MediaPipelineTransmit : public MediaPipeline { @@ -262,6 +274,13 @@ class MediaPipelineTransmit : public MediaPipeline { : conduit_(conduit), active_(false), samples_10ms_buffer_(nullptr), buffer_current_(0), samplenum_10ms_(0){} + ~PipelineListener() + { + // release conduit on mainthread. Must use forget()! + NS_DispatchToMainThread(new ConduitDeleteEvent(conduit_.forget()), NS_DISPATCH_NORMAL); + } + + // XXX. This is not thread-safe but the hazard is just // that active_ = true takes a while to propagate. Revisit // when 823600 lands. @@ -272,8 +291,8 @@ class MediaPipelineTransmit : public MediaPipeline { TrackRate rate, TrackTicks offset, uint32_t events, - const MediaSegment& queued_media); - virtual void NotifyPull(MediaStreamGraph* aGraph, StreamTime aDesiredTime) {} + const MediaSegment& queued_media) MOZ_OVERRIDE; + virtual void NotifyPull(MediaStreamGraph* aGraph, StreamTime aDesiredTime) MOZ_OVERRIDE {} private: virtual void ProcessAudioChunk(AudioSessionConduit *conduit, @@ -365,13 +384,19 @@ class MediaPipelineReceiveAudio : public MediaPipelineReceive { PipelineListener(SourceMediaStream * source, TrackID track_id, const RefPtr& conduit); + ~PipelineListener() + { + // release conduit on mainthread. Must use forget()! + NS_DispatchToMainThread(new ConduitDeleteEvent(conduit_.forget()), NS_DISPATCH_NORMAL); + } + // Implement MediaStreamListener virtual void NotifyQueuedTrackChanges(MediaStreamGraph* graph, TrackID tid, TrackRate rate, TrackTicks offset, uint32_t events, - const MediaSegment& queued_media) {} - virtual void NotifyPull(MediaStreamGraph* aGraph, StreamTime aDesiredTime); + const MediaSegment& queued_media) MOZ_OVERRIDE {} + virtual void NotifyPull(MediaStreamGraph* aGraph, StreamTime aDesiredTime) MOZ_OVERRIDE; private: SourceMediaStream *source_;