[vlc-commits] demux: adaptive: cleanup current source (fix #17553)

Francois Cartegnie git at videolan.org
Sun Jul 16 20:19:06 CEST 2017


vlc | branch: master | Francois Cartegnie <fcvlcdev at free.fr> | Thu Jul 13 17:38:57 2017 +0200| [25320d090f8d6da6d4625abf70ff55dd35cd57d8] | committer: Francois Cartegnie

demux: adaptive: cleanup current source (fix #17553)

and potential crash

> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=25320d090f8d6da6d4625abf70ff55dd35cd57d8
---

 modules/demux/adaptive/http/Chunk.cpp      | 27 ++++++++++++++++++++++++---
 modules/demux/adaptive/http/Chunk.h        |  3 +++
 modules/demux/adaptive/http/Downloader.cpp |  5 +++++
 3 files changed, 32 insertions(+), 3 deletions(-)

diff --git a/modules/demux/adaptive/http/Chunk.cpp b/modules/demux/adaptive/http/Chunk.cpp
index c063e81268..c5787c77dd 100644
--- a/modules/demux/adaptive/http/Chunk.cpp
+++ b/modules/demux/adaptive/http/Chunk.cpp
@@ -249,24 +249,29 @@ HTTPChunkBufferedSource::HTTPChunkBufferedSource(const std::string& url, Abstrac
     vlc_cond_init(&avail);
     done = false;
     eof = false;
+    held = false;
     downloadstart = 0;
 }
 
 HTTPChunkBufferedSource::~HTTPChunkBufferedSource()
 {
+    /* cancel ourself if in queue */
+    connManager->cancel(this);
+
     vlc_mutex_lock(&lock);
+    done = true;
+    if(held) /* wait release if not in queue but currently downloaded */
+        vlc_cond_wait(&avail, &lock);
+
     if(p_head)
     {
         block_ChainRelease(p_head);
         p_head = NULL;
         pp_tail = &p_head;
     }
-    done = true;
     buffered = 0;
     vlc_mutex_unlock(&lock);
 
-    connManager->cancel(this);
-
     vlc_cond_destroy(&avail);
     vlc_mutex_destroy(&lock);
 }
@@ -280,6 +285,21 @@ bool HTTPChunkBufferedSource::isDone() const
     return b_done;
 }
 
+void HTTPChunkBufferedSource::hold()
+{
+    vlc_mutex_lock(&lock);
+    held = true;
+    vlc_mutex_unlock(&lock);
+}
+
+void HTTPChunkBufferedSource::release()
+{
+    vlc_mutex_lock(&lock);
+    held = false;
+    vlc_cond_signal(&avail);
+    vlc_mutex_unlock(&lock);
+}
+
 void HTTPChunkBufferedSource::bufferize(size_t readsize)
 {
     vlc_mutex_lock(&lock);
@@ -317,6 +337,7 @@ void HTTPChunkBufferedSource::bufferize(size_t readsize)
     if(ret <= 0)
     {
         block_Release(p_block);
+        p_block = NULL;
         vlc_mutex_lock(&lock);
         done = true;
         rate.size = buffered + consumed;
diff --git a/modules/demux/adaptive/http/Chunk.h b/modules/demux/adaptive/http/Chunk.h
index bbb56d23c0..8f0120f1aa 100644
--- a/modules/demux/adaptive/http/Chunk.h
+++ b/modules/demux/adaptive/http/Chunk.h
@@ -118,6 +118,8 @@ namespace adaptive
                 virtual block_t *  readBlock       (); /* reimpl */
                 virtual block_t *  read            (size_t); /* reimpl */
                 virtual bool       hasMoreData     () const; /* impl */
+                void               hold();
+                void               release();
 
             protected:
                 virtual bool       prepare(); /* reimpl */
@@ -133,6 +135,7 @@ namespace adaptive
                 mtime_t             downloadstart;
                 vlc_mutex_t         lock;
                 vlc_cond_t          avail;
+                bool                held;
         };
 
         class HTTPChunk : public AbstractChunk
diff --git a/modules/demux/adaptive/http/Downloader.cpp b/modules/demux/adaptive/http/Downloader.cpp
index afce4597ed..ba8172740c 100644
--- a/modules/demux/adaptive/http/Downloader.cpp
+++ b/modules/demux/adaptive/http/Downloader.cpp
@@ -63,6 +63,7 @@ Downloader::~Downloader()
 void Downloader::schedule(HTTPChunkBufferedSource *source)
 {
     vlc_mutex_lock(&lock);
+    source->hold();
     chunks.push_back(source);
     vlc_cond_signal(&waitcond);
     vlc_mutex_unlock(&lock);
@@ -71,6 +72,7 @@ void Downloader::schedule(HTTPChunkBufferedSource *source)
 void Downloader::cancel(HTTPChunkBufferedSource *source)
 {
     vlc_mutex_lock(&lock);
+    source->release();
     chunks.remove(source);
     vlc_mutex_unlock(&lock);
 }
@@ -106,7 +108,10 @@ void Downloader::Run()
             HTTPChunkBufferedSource *source = chunks.front();
             DownloadSource(source);
             if(source->isDone())
+            {
                 chunks.pop_front();
+                source->release();
+            }
         }
     }
     vlc_mutex_unlock(&lock);



More information about the vlc-commits mailing list