Discussion:
demux: adaptive: cleanup current source (fix #17553)
(too old to reply)
Francois Cartegnie
2017-07-16 18:19:06 UTC
Permalink
Raw Message
vlc | branch: master | Francois Cartegnie <***@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);

Loading...