From 73013a3c044fef94a6cdc9a422f85b8c86f27c1a Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Thu, 15 Mar 2018 19:23:31 +0100 Subject: input/thread: move code to Stop() Fixes crash due to "pure virtual method called" in the "mms" input plugin. Closes #253 --- src/input/ThreadInputStream.hxx | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) (limited to 'src/input/ThreadInputStream.hxx') diff --git a/src/input/ThreadInputStream.hxx b/src/input/ThreadInputStream.hxx index 046e0821c..cbf378926 100644 --- a/src/input/ThreadInputStream.hxx +++ b/src/input/ThreadInputStream.hxx @@ -27,6 +27,7 @@ #include +#include #include template class CircularBuffer; @@ -39,6 +40,11 @@ template class CircularBuffer; * manages the thread and the buffer. * * This works only for "streams": unknown length, no seeking, no tags. + * + * The implementation must call Stop() before its destruction + * completes. This cannot be done in ~ThreadInputStream() because at + * this point, the class has been morphed back to #ThreadInputStream + * and the still-running thread will crash due to pure method call. */ class ThreadInputStream : public InputStream { const char *const plugin; @@ -76,7 +82,13 @@ public: thread(BIND_THIS_METHOD(ThreadFunc)), buffer_size(_buffer_size) {} - virtual ~ThreadInputStream(); +#ifndef NDEBUG + ~ThreadInputStream() override { + /* Stop() must have been called already */ + assert(!thread.IsDefined()); + assert(buffer == nullptr); + } +#endif /** * Initialize the object and start the thread. @@ -90,6 +102,12 @@ public: size_t Read(void *ptr, size_t size) override final; protected: + /** + * Stop the thread and free the buffer. This must be called + * before destruction of this object completes. + */ + void Stop() noexcept; + void SetMimeType(const char *_mime) { assert(thread.IsInside()); -- cgit v1.2.3