Commit d0fbf6db authored by Max Kellermann's avatar Max Kellermann

input/Stream: remove attribute "cond", replace with handler interface

This adds a bit of overhead, but also adds flexibility to the API, because arbitrary triggers may be invoked from that virtual method implementation, not just Cond::signal(). The motivation for this is to make the handlers more dynamic, for the upcoming buffering class utilizing ProxyInputStream.
parent 01d8eb62
...@@ -1382,6 +1382,7 @@ libinput_a_SOURCES = \ ...@@ -1382,6 +1382,7 @@ libinput_a_SOURCES = \
src/input/InputStream.cxx src/input/InputStream.hxx \ src/input/InputStream.cxx src/input/InputStream.hxx \
src/input/Ptr.hxx \ src/input/Ptr.hxx \
src/input/InputPlugin.hxx \ src/input/InputPlugin.hxx \
src/input/Handler.hxx \
src/input/RemoteTagScanner.hxx \ src/input/RemoteTagScanner.hxx \
src/input/ScanTags.cxx src/input/ScanTags.hxx \ src/input/ScanTags.cxx src/input/ScanTags.hxx \
src/input/Reader.cxx src/input/Reader.hxx \ src/input/Reader.cxx src/input/Reader.hxx \
......
...@@ -22,16 +22,14 @@ ...@@ -22,16 +22,14 @@
#include "TagStream.hxx" #include "TagStream.hxx"
#include "archive/ArchiveFile.hxx" #include "archive/ArchiveFile.hxx"
#include "input/InputStream.hxx" #include "input/InputStream.hxx"
#include "thread/Cond.hxx"
bool bool
tag_archive_scan(ArchiveFile &archive, const char *path_utf8, tag_archive_scan(ArchiveFile &archive, const char *path_utf8,
const TagHandler &handler, void *handler_ctx) noexcept const TagHandler &handler, void *handler_ctx) noexcept
try { try {
Mutex mutex; Mutex mutex;
Cond cond;
auto is = archive.OpenStream(path_utf8, mutex, cond); auto is = archive.OpenStream(path_utf8, mutex);
if (!is) if (!is)
return false; return false;
...@@ -45,9 +43,8 @@ tag_archive_scan(ArchiveFile &archive, const char *path_utf8, ...@@ -45,9 +43,8 @@ tag_archive_scan(ArchiveFile &archive, const char *path_utf8,
TagBuilder &builder) noexcept TagBuilder &builder) noexcept
try { try {
Mutex mutex; Mutex mutex;
Cond cond;
auto is = archive.OpenStream(path_utf8, mutex, cond); auto is = archive.OpenStream(path_utf8, mutex);
return is && tag_stream_scan(*is, builder); return is && tag_stream_scan(*is, builder);
} catch (const std::exception &e) { } catch (const std::exception &e) {
return false; return false;
......
...@@ -27,7 +27,6 @@ ...@@ -27,7 +27,6 @@
#include "decoder/DecoderPlugin.hxx" #include "decoder/DecoderPlugin.hxx"
#include "input/InputStream.hxx" #include "input/InputStream.hxx"
#include "input/LocalOpen.hxx" #include "input/LocalOpen.hxx"
#include "thread/Cond.hxx"
#include <exception> #include <exception>
...@@ -41,7 +40,6 @@ class TagFileScan { ...@@ -41,7 +40,6 @@ class TagFileScan {
void *handler_ctx; void *handler_ctx;
Mutex mutex; Mutex mutex;
Cond cond;
InputStreamPtr is; InputStreamPtr is;
public: public:
...@@ -62,8 +60,7 @@ public: ...@@ -62,8 +60,7 @@ public:
/* open the InputStream (if not already open) */ /* open the InputStream (if not already open) */
if (is == nullptr) { if (is == nullptr) {
try { try {
is = OpenLocalInputStream(path_fs, is = OpenLocalInputStream(path_fs, mutex);
mutex, cond);
} catch (...) { } catch (...) {
return false; return false;
} }
......
...@@ -28,7 +28,6 @@ ...@@ -28,7 +28,6 @@
#include "decoder/DecoderPlugin.hxx" #include "decoder/DecoderPlugin.hxx"
#include "input/InputStream.hxx" #include "input/InputStream.hxx"
#include "thread/Mutex.hxx" #include "thread/Mutex.hxx"
#include "thread/Cond.hxx"
#include <exception> #include <exception>
...@@ -78,9 +77,8 @@ bool ...@@ -78,9 +77,8 @@ bool
tag_stream_scan(const char *uri, const TagHandler &handler, void *ctx) tag_stream_scan(const char *uri, const TagHandler &handler, void *ctx)
try { try {
Mutex mutex; Mutex mutex;
Cond cond;
auto is = InputStream::OpenReady(uri, mutex, cond); auto is = InputStream::OpenReady(uri, mutex);
return tag_stream_scan(*is, handler, ctx); return tag_stream_scan(*is, handler, ctx);
} catch (const std::exception &e) { } catch (const std::exception &e) {
return false; return false;
...@@ -104,9 +102,8 @@ bool ...@@ -104,9 +102,8 @@ bool
tag_stream_scan(const char *uri, TagBuilder &builder) tag_stream_scan(const char *uri, TagBuilder &builder)
try { try {
Mutex mutex; Mutex mutex;
Cond cond;
auto is = InputStream::OpenReady(uri, mutex, cond); auto is = InputStream::OpenReady(uri, mutex);
return tag_stream_scan(*is, builder); return tag_stream_scan(*is, builder);
} catch (const std::exception &e) { } catch (const std::exception &e) {
return false; return false;
......
...@@ -23,7 +23,6 @@ ...@@ -23,7 +23,6 @@
#include "input/Ptr.hxx" #include "input/Ptr.hxx"
class Mutex; class Mutex;
class Cond;
class ArchiveVisitor; class ArchiveVisitor;
class ArchiveFile { class ArchiveFile {
...@@ -43,7 +42,7 @@ public: ...@@ -43,7 +42,7 @@ public:
* @param path the path within the archive * @param path the path within the archive
*/ */
virtual InputStreamPtr OpenStream(const char *path, virtual InputStreamPtr OpenStream(const char *path,
Mutex &mutex, Cond &cond) = 0; Mutex &mutex) = 0;
}; };
#endif #endif
...@@ -28,7 +28,6 @@ ...@@ -28,7 +28,6 @@
#include "../ArchiveVisitor.hxx" #include "../ArchiveVisitor.hxx"
#include "input/InputStream.hxx" #include "input/InputStream.hxx"
#include "input/LocalOpen.hxx" #include "input/LocalOpen.hxx"
#include "thread/Cond.hxx"
#include "fs/Path.hxx" #include "fs/Path.hxx"
#include <bzlib.h> #include <bzlib.h>
...@@ -54,7 +53,7 @@ public: ...@@ -54,7 +53,7 @@ public:
} }
InputStreamPtr OpenStream(const char *path, InputStreamPtr OpenStream(const char *path,
Mutex &mutex, Cond &cond) override; Mutex &mutex) override;
}; };
class Bzip2InputStream final : public InputStream { class Bzip2InputStream final : public InputStream {
...@@ -69,7 +68,7 @@ class Bzip2InputStream final : public InputStream { ...@@ -69,7 +68,7 @@ class Bzip2InputStream final : public InputStream {
public: public:
Bzip2InputStream(const std::shared_ptr<InputStream> &_input, Bzip2InputStream(const std::shared_ptr<InputStream> &_input,
const char *uri, const char *uri,
Mutex &mutex, Cond &cond); Mutex &mutex);
~Bzip2InputStream(); ~Bzip2InputStream();
/* virtual methods from InputStream */ /* virtual methods from InputStream */
...@@ -106,8 +105,7 @@ static std::unique_ptr<ArchiveFile> ...@@ -106,8 +105,7 @@ static std::unique_ptr<ArchiveFile>
bz2_open(Path pathname) bz2_open(Path pathname)
{ {
static Mutex mutex; static Mutex mutex;
static Cond cond; auto is = OpenLocalInputStream(pathname, mutex);
auto is = OpenLocalInputStream(pathname, mutex, cond);
return std::make_unique<Bzip2ArchiveFile>(pathname, std::move(is)); return std::make_unique<Bzip2ArchiveFile>(pathname, std::move(is));
} }
...@@ -115,8 +113,8 @@ bz2_open(Path pathname) ...@@ -115,8 +113,8 @@ bz2_open(Path pathname)
Bzip2InputStream::Bzip2InputStream(const std::shared_ptr<InputStream> &_input, Bzip2InputStream::Bzip2InputStream(const std::shared_ptr<InputStream> &_input,
const char *_uri, const char *_uri,
Mutex &_mutex, Cond &_cond) Mutex &_mutex)
:InputStream(_uri, _mutex, _cond), :InputStream(_uri, _mutex),
input(_input) input(_input)
{ {
Open(); Open();
...@@ -129,9 +127,9 @@ Bzip2InputStream::~Bzip2InputStream() ...@@ -129,9 +127,9 @@ Bzip2InputStream::~Bzip2InputStream()
InputStreamPtr InputStreamPtr
Bzip2ArchiveFile::OpenStream(const char *path, Bzip2ArchiveFile::OpenStream(const char *path,
Mutex &mutex, Cond &cond) Mutex &mutex)
{ {
return std::make_unique<Bzip2InputStream>(istream, path, mutex, cond); return std::make_unique<Bzip2InputStream>(istream, path, mutex);
} }
inline bool inline bool
......
...@@ -75,7 +75,7 @@ public: ...@@ -75,7 +75,7 @@ public:
virtual void Visit(ArchiveVisitor &visitor) override; virtual void Visit(ArchiveVisitor &visitor) override;
InputStreamPtr OpenStream(const char *path, InputStreamPtr OpenStream(const char *path,
Mutex &mutex, Cond &cond) override; Mutex &mutex) override;
}; };
/* archive open && listing routine */ /* archive open && listing routine */
...@@ -144,9 +144,9 @@ class Iso9660InputStream final : public InputStream { ...@@ -144,9 +144,9 @@ class Iso9660InputStream final : public InputStream {
public: public:
Iso9660InputStream(const std::shared_ptr<Iso9660> &_iso, Iso9660InputStream(const std::shared_ptr<Iso9660> &_iso,
const char *_uri, const char *_uri,
Mutex &_mutex, Cond &_cond, Mutex &_mutex,
iso9660_stat_t *_statbuf) iso9660_stat_t *_statbuf)
:InputStream(_uri, _mutex, _cond), :InputStream(_uri, _mutex),
iso(_iso), statbuf(_statbuf) { iso(_iso), statbuf(_statbuf) {
size = statbuf->size; size = statbuf->size;
SetReady(); SetReady();
...@@ -163,14 +163,14 @@ public: ...@@ -163,14 +163,14 @@ public:
InputStreamPtr InputStreamPtr
Iso9660ArchiveFile::OpenStream(const char *pathname, Iso9660ArchiveFile::OpenStream(const char *pathname,
Mutex &mutex, Cond &cond) Mutex &mutex)
{ {
auto statbuf = iso9660_ifs_stat_translate(iso->iso, pathname); auto statbuf = iso9660_ifs_stat_translate(iso->iso, pathname);
if (statbuf == nullptr) if (statbuf == nullptr)
throw FormatRuntimeError("not found in the ISO file: %s", throw FormatRuntimeError("not found in the ISO file: %s",
pathname); pathname);
return std::make_unique<Iso9660InputStream>(iso, pathname, mutex, cond, return std::make_unique<Iso9660InputStream>(iso, pathname, mutex,
statbuf); statbuf);
} }
......
...@@ -60,7 +60,7 @@ public: ...@@ -60,7 +60,7 @@ public:
virtual void Visit(ArchiveVisitor &visitor) override; virtual void Visit(ArchiveVisitor &visitor) override;
InputStreamPtr OpenStream(const char *path, InputStreamPtr OpenStream(const char *path,
Mutex &mutex, Cond &cond) override; Mutex &mutex) override;
}; };
/* archive open && listing routine */ /* archive open && listing routine */
...@@ -92,9 +92,9 @@ class ZzipInputStream final : public InputStream { ...@@ -92,9 +92,9 @@ class ZzipInputStream final : public InputStream {
public: public:
ZzipInputStream(const std::shared_ptr<ZzipDir> _dir, const char *_uri, ZzipInputStream(const std::shared_ptr<ZzipDir> _dir, const char *_uri,
Mutex &_mutex, Cond &_cond, Mutex &_mutex,
ZZIP_FILE *_file) ZZIP_FILE *_file)
:InputStream(_uri, _mutex, _cond), :InputStream(_uri, _mutex),
dir(_dir), file(_file) { dir(_dir), file(_file) {
//we are seekable (but its not recommendent to do so) //we are seekable (but its not recommendent to do so)
seekable = true; seekable = true;
...@@ -118,7 +118,7 @@ public: ...@@ -118,7 +118,7 @@ public:
InputStreamPtr InputStreamPtr
ZzipArchiveFile::OpenStream(const char *pathname, ZzipArchiveFile::OpenStream(const char *pathname,
Mutex &mutex, Cond &cond) Mutex &mutex)
{ {
ZZIP_FILE *_file = zzip_file_open(dir->dir, pathname, 0); ZZIP_FILE *_file = zzip_file_open(dir->dir, pathname, 0);
if (_file == nullptr) if (_file == nullptr)
...@@ -126,7 +126,7 @@ ZzipArchiveFile::OpenStream(const char *pathname, ...@@ -126,7 +126,7 @@ ZzipArchiveFile::OpenStream(const char *pathname,
pathname); pathname);
return std::make_unique<ZzipInputStream>(dir, pathname, return std::make_unique<ZzipInputStream>(dir, pathname,
mutex, cond, mutex,
_file); _file);
} }
......
...@@ -40,7 +40,6 @@ ...@@ -40,7 +40,6 @@
#include "LocateUri.hxx" #include "LocateUri.hxx"
#include "TimePrint.hxx" #include "TimePrint.hxx"
#include "thread/Mutex.hxx" #include "thread/Mutex.hxx"
#include "thread/Cond.hxx"
#include <assert.h> #include <assert.h>
#include <inttypes.h> /* for PRIu64 */ #include <inttypes.h> /* for PRIu64 */
...@@ -244,7 +243,7 @@ handle_read_comments(Client &client, Request args, Response &r) ...@@ -244,7 +243,7 @@ handle_read_comments(Client &client, Request args, Response &r)
* opened file or #nullptr on failure. * opened file or #nullptr on failure.
*/ */
static InputStreamPtr static InputStreamPtr
find_stream_art(const char *directory, Mutex &mutex, Cond &cond) find_stream_art(const char *directory, Mutex &mutex)
{ {
static constexpr char const * art_names[] = { static constexpr char const * art_names[] = {
"cover.png", "cover.png",
...@@ -257,7 +256,7 @@ find_stream_art(const char *directory, Mutex &mutex, Cond &cond) ...@@ -257,7 +256,7 @@ find_stream_art(const char *directory, Mutex &mutex, Cond &cond)
std::string art_file = PathTraitsUTF8::Build(directory, name); std::string art_file = PathTraitsUTF8::Build(directory, name);
try { try {
return InputStream::OpenReady(art_file.c_str(), mutex, cond); return InputStream::OpenReady(art_file.c_str(), mutex);
} catch (const std::exception &e) {} } catch (const std::exception &e) {}
} }
return nullptr; return nullptr;
...@@ -269,9 +268,8 @@ read_stream_art(Response &r, const char *uri, size_t offset) ...@@ -269,9 +268,8 @@ read_stream_art(Response &r, const char *uri, size_t offset)
std::string art_directory = PathTraitsUTF8::GetParent(uri); std::string art_directory = PathTraitsUTF8::GetParent(uri);
Mutex mutex; Mutex mutex;
Cond cond;
InputStreamPtr is = find_stream_art(art_directory.c_str(), mutex, cond); InputStreamPtr is = find_stream_art(art_directory.c_str(), mutex);
if (is == nullptr) { if (is == nullptr) {
r.Error(ACK_ERROR_NO_EXIST, "No file exists"); r.Error(ACK_ERROR_NO_EXIST, "No file exists");
......
...@@ -370,7 +370,8 @@ DecoderBridge::OpenUri(const char *uri) ...@@ -370,7 +370,8 @@ DecoderBridge::OpenUri(const char *uri)
Mutex &mutex = dc.mutex; Mutex &mutex = dc.mutex;
Cond &cond = dc.cond; Cond &cond = dc.cond;
auto is = InputStream::Open(uri, mutex, cond); auto is = InputStream::Open(uri, mutex);
is->SetHandler(&dc);
const std::lock_guard<Mutex> lock(mutex); const std::lock_guard<Mutex> lock(mutex);
while (true) { while (true) {
...@@ -404,7 +405,7 @@ try { ...@@ -404,7 +405,7 @@ try {
if (is.IsAvailable()) if (is.IsAvailable())
break; break;
is.cond.wait(is.mutex); dc.cond.wait(is.mutex);
} }
size_t nbytes = is.Read(buffer, length); size_t nbytes = is.Read(buffer, length);
......
...@@ -23,6 +23,7 @@ ...@@ -23,6 +23,7 @@
#include "DecoderCommand.hxx" #include "DecoderCommand.hxx"
#include "AudioFormat.hxx" #include "AudioFormat.hxx"
#include "MixRampInfo.hxx" #include "MixRampInfo.hxx"
#include "input/Handler.hxx"
#include "thread/Mutex.hxx" #include "thread/Mutex.hxx"
#include "thread/Cond.hxx" #include "thread/Cond.hxx"
#include "thread/Thread.hxx" #include "thread/Thread.hxx"
...@@ -60,7 +61,7 @@ enum class DecoderState : uint8_t { ...@@ -60,7 +61,7 @@ enum class DecoderState : uint8_t {
ERROR, ERROR,
}; };
struct DecoderControl { struct DecoderControl final : InputStreamHandler {
/** /**
* The handle of the decoder thread. * The handle of the decoder thread.
*/ */
...@@ -422,6 +423,15 @@ public: ...@@ -422,6 +423,15 @@ public:
private: private:
void RunThread() noexcept; void RunThread() noexcept;
/* virtual methods from class InputStreamHandler */
void OnInputStreamReady() noexcept override {
cond.signal();
}
void OnInputStreamAvailable() noexcept override {
cond.signal();
}
}; };
#endif #endif
...@@ -56,7 +56,8 @@ static constexpr Domain decoder_thread_domain("decoder_thread"); ...@@ -56,7 +56,8 @@ static constexpr Domain decoder_thread_domain("decoder_thread");
static InputStreamPtr static InputStreamPtr
decoder_input_stream_open(DecoderControl &dc, const char *uri) decoder_input_stream_open(DecoderControl &dc, const char *uri)
{ {
auto is = InputStream::Open(uri, dc.mutex, dc.cond); auto is = InputStream::Open(uri, dc.mutex);
is->SetHandler(&dc);
/* wait for the input stream to become ready; its metadata /* wait for the input stream to become ready; its metadata
will be available then */ will be available then */
...@@ -81,7 +82,7 @@ decoder_input_stream_open(DecoderControl &dc, const char *uri) ...@@ -81,7 +82,7 @@ decoder_input_stream_open(DecoderControl &dc, const char *uri)
static InputStreamPtr static InputStreamPtr
decoder_input_stream_open(DecoderControl &dc, Path path) decoder_input_stream_open(DecoderControl &dc, Path path)
{ {
auto is = OpenLocalInputStream(path, dc.mutex, dc.cond); auto is = OpenLocalInputStream(path, dc.mutex);
assert(is->IsReady()); assert(is->IsReady());
......
...@@ -19,6 +19,7 @@ ...@@ -19,6 +19,7 @@
#include "config.h" #include "config.h"
#include "AsyncInputStream.hxx" #include "AsyncInputStream.hxx"
#include "CondHandler.hxx"
#include "tag/Tag.hxx" #include "tag/Tag.hxx"
#include "thread/Cond.hxx" #include "thread/Cond.hxx"
#include "event/Loop.hxx" #include "event/Loop.hxx"
...@@ -29,10 +30,10 @@ ...@@ -29,10 +30,10 @@
#include <string.h> #include <string.h>
AsyncInputStream::AsyncInputStream(EventLoop &event_loop, const char *_url, AsyncInputStream::AsyncInputStream(EventLoop &event_loop, const char *_url,
Mutex &_mutex, Cond &_cond, Mutex &_mutex,
size_t _buffer_size, size_t _buffer_size,
size_t _resume_at) size_t _resume_at)
:InputStream(_url, _mutex, _cond), :InputStream(_url, _mutex),
deferred_resume(event_loop, BIND_THIS_METHOD(DeferredResume)), deferred_resume(event_loop, BIND_THIS_METHOD(DeferredResume)),
deferred_seek(event_loop, BIND_THIS_METHOD(DeferredSeek)), deferred_seek(event_loop, BIND_THIS_METHOD(DeferredSeek)),
allocation(_buffer_size), allocation(_buffer_size),
...@@ -133,8 +134,10 @@ AsyncInputStream::Seek(offset_type new_offset) ...@@ -133,8 +134,10 @@ AsyncInputStream::Seek(offset_type new_offset)
deferred_seek.Schedule(); deferred_seek.Schedule();
CondInputStreamHandler cond_handler;
const ScopeExchangeInputStreamHandler h(*this, &cond_handler);
while (seek_state != SeekState::NONE) while (seek_state != SeekState::NONE)
cond.wait(mutex); cond_handler.cond.wait(mutex);
Check(); Check();
} }
...@@ -151,7 +154,7 @@ AsyncInputStream::SeekDone() noexcept ...@@ -151,7 +154,7 @@ AsyncInputStream::SeekDone() noexcept
open = true; open = true;
seek_state = SeekState::NONE; seek_state = SeekState::NONE;
cond.broadcast(); InvokeOnAvailable();
} }
std::unique_ptr<Tag> std::unique_ptr<Tag>
...@@ -173,6 +176,8 @@ AsyncInputStream::Read(void *ptr, size_t read_size) ...@@ -173,6 +176,8 @@ AsyncInputStream::Read(void *ptr, size_t read_size)
{ {
assert(!GetEventLoop().IsInside()); assert(!GetEventLoop().IsInside());
CondInputStreamHandler cond_handler;
/* wait for data */ /* wait for data */
CircularBuffer<uint8_t>::Range r; CircularBuffer<uint8_t>::Range r;
while (true) { while (true) {
...@@ -182,7 +187,8 @@ AsyncInputStream::Read(void *ptr, size_t read_size) ...@@ -182,7 +187,8 @@ AsyncInputStream::Read(void *ptr, size_t read_size)
if (!r.empty() || IsEOF()) if (!r.empty() || IsEOF())
break; break;
cond.wait(mutex); const ScopeExchangeInputStreamHandler h(*this, &cond_handler);
cond_handler.cond.wait(mutex);
} }
const size_t nbytes = std::min(read_size, r.size); const size_t nbytes = std::min(read_size, r.size);
...@@ -205,7 +211,7 @@ AsyncInputStream::CommitWriteBuffer(size_t nbytes) noexcept ...@@ -205,7 +211,7 @@ AsyncInputStream::CommitWriteBuffer(size_t nbytes) noexcept
if (!IsReady()) if (!IsReady())
SetReady(); SetReady();
else else
cond.broadcast(); InvokeOnAvailable();
} }
void void
...@@ -231,7 +237,7 @@ AsyncInputStream::AppendToBuffer(const void *data, size_t append_size) noexcept ...@@ -231,7 +237,7 @@ AsyncInputStream::AppendToBuffer(const void *data, size_t append_size) noexcept
if (!IsReady()) if (!IsReady())
SetReady(); SetReady();
else else
cond.broadcast(); InvokeOnAvailable();
} }
void void
...@@ -243,7 +249,7 @@ AsyncInputStream::DeferredResume() noexcept ...@@ -243,7 +249,7 @@ AsyncInputStream::DeferredResume() noexcept
Resume(); Resume();
} catch (...) { } catch (...) {
postponed_exception = std::current_exception(); postponed_exception = std::current_exception();
cond.broadcast(); InvokeOnAvailable();
} }
} }
...@@ -265,6 +271,6 @@ AsyncInputStream::DeferredSeek() noexcept ...@@ -265,6 +271,6 @@ AsyncInputStream::DeferredSeek() noexcept
} catch (...) { } catch (...) {
seek_state = SeekState::NONE; seek_state = SeekState::NONE;
postponed_exception = std::current_exception(); postponed_exception = std::current_exception();
cond.broadcast(); InvokeOnAvailable();
} }
} }
...@@ -70,7 +70,7 @@ protected: ...@@ -70,7 +70,7 @@ protected:
public: public:
AsyncInputStream(EventLoop &event_loop, const char *_url, AsyncInputStream(EventLoop &event_loop, const char *_url,
Mutex &_mutex, Cond &_cond, Mutex &_mutex,
size_t _buffer_size, size_t _buffer_size,
size_t _resume_at); size_t _resume_at);
......
/*
* Copyright 2003-2018 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef MPD_COND_INPUT_STREAM_HANDLER_HXX
#define MPD_COND_INPUT_STREAM_HANDLER_HXX
#include "check.h"
#include "Handler.hxx"
#include "thread/Cond.hxx"
/**
* An #InputStreamHandler implementation which signals a #Cond.
*/
struct CondInputStreamHandler final : InputStreamHandler {
Cond cond;
/* virtual methods from class InputStreamHandler */
void OnInputStreamReady() noexcept override {
cond.signal();
}
void OnInputStreamAvailable() noexcept override {
cond.signal();
}
};
#endif
...@@ -35,8 +35,8 @@ class FailingInputStream final : public InputStream { ...@@ -35,8 +35,8 @@ class FailingInputStream final : public InputStream {
public: public:
explicit FailingInputStream(const char *_uri, explicit FailingInputStream(const char *_uri,
const std::exception_ptr _error, const std::exception_ptr _error,
Mutex &_mutex, Cond &_cond) noexcept Mutex &_mutex) noexcept
:InputStream(_uri, _mutex, _cond), error(_error) { :InputStream(_uri, _mutex), error(_error) {
SetReady(); SetReady();
} }
......
/*
* Copyright 2003-2018 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef MPD_INPUT_STREAM_HANDLER_HXX
#define MPD_INPUT_STREAM_HANDLER_HXX
#include "check.h"
/**
* An interface which gets receives events from an #InputStream. Its
* methods will be called from within an arbitrary thread and must not
* block.
*
* A reference to an instance is passed to the #InputStream, but it
* remains owned by the caller.
*/
class InputStreamHandler {
public:
/**
* Called when InputStream::IsReady() becomes true.
*
* Before querying metadata from the #InputStream,
* InputStream::Update() must be called.
*
* Caller locks InputStream::mutex.
*/
virtual void OnInputStreamReady() noexcept = 0;
/**
* Called when InputStream::IsAvailable() becomes true.
*
* Caller locks InputStream::mutex.
*/
virtual void OnInputStreamAvailable() noexcept = 0;
};
#endif
...@@ -24,7 +24,6 @@ ...@@ -24,7 +24,6 @@
struct ConfigBlock; struct ConfigBlock;
class Mutex; class Mutex;
class Cond;
class EventLoop; class EventLoop;
class RemoteTagScanner; class RemoteTagScanner;
class RemoteTagHandler; class RemoteTagHandler;
...@@ -54,8 +53,7 @@ struct InputPlugin { ...@@ -54,8 +53,7 @@ struct InputPlugin {
* *
* Throws std::runtime_error on error. * Throws std::runtime_error on error.
*/ */
InputStreamPtr (*open)(const char *uri, InputStreamPtr (*open)(const char *uri, Mutex &mutex);
Mutex &mutex, Cond &cond);
/** /**
* Prepare a #RemoteTagScanner. The operation must be started * Prepare a #RemoteTagScanner. The operation must be started
......
...@@ -19,8 +19,8 @@ ...@@ -19,8 +19,8 @@
#include "config.h" #include "config.h"
#include "InputStream.hxx" #include "InputStream.hxx"
#include "Handler.hxx"
#include "tag/Tag.hxx" #include "tag/Tag.hxx"
#include "thread/Cond.hxx"
#include "util/StringCompare.hxx" #include "util/StringCompare.hxx"
#include <stdexcept> #include <stdexcept>
...@@ -47,26 +47,8 @@ InputStream::SetReady() noexcept ...@@ -47,26 +47,8 @@ InputStream::SetReady() noexcept
assert(!ready); assert(!ready);
ready = true; ready = true;
cond.broadcast();
}
void InvokeOnReady();
InputStream::WaitReady() noexcept
{
while (true) {
Update();
if (ready)
break;
cond.wait(mutex);
}
}
void
InputStream::LockWaitReady() noexcept
{
const std::lock_guard<Mutex> protect(mutex);
WaitReady();
} }
/** /**
...@@ -177,3 +159,17 @@ InputStream::LockIsEOF() noexcept ...@@ -177,3 +159,17 @@ InputStream::LockIsEOF() noexcept
const std::lock_guard<Mutex> protect(mutex); const std::lock_guard<Mutex> protect(mutex);
return IsEOF(); return IsEOF();
} }
void
InputStream::InvokeOnReady() noexcept
{
if (handler != nullptr)
handler->OnInputStreamReady();
}
void
InputStream::InvokeOnAvailable() noexcept
{
if (handler != nullptr)
handler->OnInputStreamAvailable();
}
...@@ -31,8 +31,8 @@ ...@@ -31,8 +31,8 @@
#include <assert.h> #include <assert.h>
class Cond;
struct Tag; struct Tag;
class InputStreamHandler;
class InputStream { class InputStream {
public: public:
...@@ -55,6 +55,7 @@ public: ...@@ -55,6 +55,7 @@ public:
*/ */
Mutex &mutex; Mutex &mutex;
private:
/** /**
* A cond that gets signalled when the state of this object * A cond that gets signalled when the state of this object
* changes from the I/O thread. The client of this object may * changes from the I/O thread. The client of this object may
...@@ -63,7 +64,7 @@ public: ...@@ -63,7 +64,7 @@ public:
* This object is allocated by the client, and the client is * This object is allocated by the client, and the client is
* responsible for freeing it. * responsible for freeing it.
*/ */
Cond &cond; InputStreamHandler *handler = nullptr;
protected: protected:
/** /**
...@@ -96,9 +97,9 @@ private: ...@@ -96,9 +97,9 @@ private:
std::string mime; std::string mime;
public: public:
InputStream(const char *_uri, Mutex &_mutex, Cond &_cond) noexcept InputStream(const char *_uri, Mutex &_mutex) noexcept
:uri(_uri), :uri(_uri),
mutex(_mutex), cond(_cond) { mutex(_mutex) {
assert(_uri != nullptr); assert(_uri != nullptr);
} }
...@@ -122,16 +123,33 @@ public: ...@@ -122,16 +123,33 @@ public:
* notifications * notifications
* @return an #InputStream object on success * @return an #InputStream object on success
*/ */
gcc_nonnull_all gcc_nonnull(1)
static InputStreamPtr Open(const char *uri, Mutex &mutex, Cond &cond); static InputStreamPtr Open(const char *uri, Mutex &mutex);
/** /**
* Just like Open(), but waits for the stream to become ready. * Just like Open(), but waits for the stream to become ready.
* It is a wrapper for Open(), WaitReady() and Check(). * It is a wrapper for Open(), WaitReady() and Check().
*/ */
gcc_nonnull_all gcc_nonnull(1)
static InputStreamPtr OpenReady(const char *uri, static InputStreamPtr OpenReady(const char *uri, Mutex &mutex);
Mutex &mutex, Cond &cond);
/**
* Install a new handler.
*
* The caller must lock the mutex.
*/
void SetHandler(InputStreamHandler *new_handler) noexcept {
handler = new_handler;
}
/**
* Install a new handler and return the old one.
*
* The caller must lock the mutex.
*/
InputStreamHandler *ExchangeHandler(InputStreamHandler *new_handler) noexcept {
return std::exchange(handler, new_handler);
}
/** /**
* The absolute URI which was used to open this stream. * The absolute URI which was used to open this stream.
...@@ -166,14 +184,6 @@ public: ...@@ -166,14 +184,6 @@ public:
return ready; return ready;
} }
void WaitReady() noexcept;
/**
* Wrapper for WaitReady() which locks and unlocks the mutex;
* the caller must not be holding it already.
*/
void LockWaitReady() noexcept;
gcc_pure gcc_pure
bool HasMimeType() const noexcept { bool HasMimeType() const noexcept {
assert(ready); assert(ready);
...@@ -380,6 +390,30 @@ public: ...@@ -380,6 +390,30 @@ public:
*/ */
gcc_nonnull_all gcc_nonnull_all
void LockReadFull(void *ptr, size_t size); void LockReadFull(void *ptr, size_t size);
protected:
void InvokeOnReady() noexcept;
void InvokeOnAvailable() noexcept;
};
/**
* Install an #InputStreamHandler during the scope in which this
* variable lives, and restore the old handler afterwards.
*/
class ScopeExchangeInputStreamHandler {
InputStream &is;
InputStreamHandler *const old_handler;
public:
ScopeExchangeInputStreamHandler(InputStream &_is,
InputStreamHandler *new_handler) noexcept
:is(_is), old_handler(is.ExchangeHandler(new_handler)) {}
ScopeExchangeInputStreamHandler(const ScopeExchangeInputStreamHandler &) = delete;
~ScopeExchangeInputStreamHandler() noexcept {
is.SetHandler(old_handler);
}
}; };
#endif #endif
...@@ -32,20 +32,20 @@ ...@@ -32,20 +32,20 @@
#include <assert.h> #include <assert.h>
InputStreamPtr InputStreamPtr
OpenLocalInputStream(Path path, Mutex &mutex, Cond &cond) OpenLocalInputStream(Path path, Mutex &mutex)
{ {
InputStreamPtr is; InputStreamPtr is;
#ifdef ENABLE_ARCHIVE #ifdef ENABLE_ARCHIVE
try { try {
#endif #endif
is = OpenFileInputStream(path, mutex, cond); is = OpenFileInputStream(path, mutex);
#ifdef ENABLE_ARCHIVE #ifdef ENABLE_ARCHIVE
} catch (const std::system_error &e) { } catch (const std::system_error &e) {
if (IsPathNotFound(e)) { if (IsPathNotFound(e)) {
/* ENOTDIR means this may be a path inside an archive /* ENOTDIR means this may be a path inside an archive
file */ file */
is = OpenArchiveInputStream(path, mutex, cond); is = OpenArchiveInputStream(path, mutex);
if (!is) if (!is)
throw; throw;
} else } else
......
...@@ -25,7 +25,6 @@ ...@@ -25,7 +25,6 @@
class Path; class Path;
class Mutex; class Mutex;
class Cond;
/** /**
* Open a "local" file. This is a wrapper for the input plugins * Open a "local" file. This is a wrapper for the input plugins
...@@ -34,6 +33,6 @@ class Cond; ...@@ -34,6 +33,6 @@ class Cond;
* Throws std::runtime_error on error. * Throws std::runtime_error on error.
*/ */
InputStreamPtr InputStreamPtr
OpenLocalInputStream(Path path, Mutex &mutex, Cond &cond); OpenLocalInputStream(Path path, Mutex &mutex);
#endif #endif
...@@ -22,6 +22,7 @@ ...@@ -22,6 +22,7 @@
#include "Registry.hxx" #include "Registry.hxx"
#include "InputPlugin.hxx" #include "InputPlugin.hxx"
#include "LocalOpen.hxx" #include "LocalOpen.hxx"
#include "CondHandler.hxx"
#include "RewindInputStream.hxx" #include "RewindInputStream.hxx"
#include "fs/Traits.hxx" #include "fs/Traits.hxx"
#include "fs/AllocatedPath.hxx" #include "fs/AllocatedPath.hxx"
...@@ -29,16 +30,15 @@ ...@@ -29,16 +30,15 @@
#include <stdexcept> #include <stdexcept>
InputStreamPtr InputStreamPtr
InputStream::Open(const char *url, InputStream::Open(const char *url, Mutex &mutex)
Mutex &mutex, Cond &cond)
{ {
if (PathTraitsUTF8::IsAbsolute(url)) { if (PathTraitsUTF8::IsAbsolute(url)) {
const auto path = AllocatedPath::FromUTF8Throw(url); const auto path = AllocatedPath::FromUTF8Throw(url);
return OpenLocalInputStream(path, mutex, cond); return OpenLocalInputStream(path, mutex);
} }
input_plugins_for_each_enabled(plugin) { input_plugins_for_each_enabled(plugin) {
auto is = plugin->open(url, mutex, cond); auto is = plugin->open(url, mutex);
if (is != nullptr) if (is != nullptr)
return input_rewind_open(std::move(is)); return input_rewind_open(std::move(is));
} }
...@@ -47,16 +47,27 @@ InputStream::Open(const char *url, ...@@ -47,16 +47,27 @@ InputStream::Open(const char *url,
} }
InputStreamPtr InputStreamPtr
InputStream::OpenReady(const char *uri, InputStream::OpenReady(const char *uri, Mutex &mutex)
Mutex &mutex, Cond &cond)
{ {
auto is = Open(uri, mutex, cond); CondInputStreamHandler handler;
auto is = Open(uri, mutex);
is->SetHandler(&handler);
{ {
const std::lock_guard<Mutex> protect(mutex); const std::lock_guard<Mutex> protect(mutex);
is->WaitReady();
while (true) {
is->Update();
if (is->IsReady())
break;
handler.cond.wait(mutex);
}
is->Check(); is->Check();
} }
is->SetHandler(nullptr);
return is; return is;
} }
...@@ -20,15 +20,16 @@ ...@@ -20,15 +20,16 @@
#include "config.h" #include "config.h"
#include "ProxyInputStream.hxx" #include "ProxyInputStream.hxx"
#include "tag/Tag.hxx" #include "tag/Tag.hxx"
#include "thread/Cond.hxx"
#include <stdexcept> #include <stdexcept>
ProxyInputStream::ProxyInputStream(InputStreamPtr _input) noexcept ProxyInputStream::ProxyInputStream(InputStreamPtr _input) noexcept
:InputStream(_input->GetURI(), _input->mutex, _input->cond), :InputStream(_input->GetURI(), _input->mutex),
input(std::move(_input)) input(std::move(_input))
{ {
assert(input); assert(input);
input->SetHandler(this);
} }
ProxyInputStream::~ProxyInputStream() noexcept = default; ProxyInputStream::~ProxyInputStream() noexcept = default;
...@@ -40,10 +41,13 @@ ProxyInputStream::SetInput(InputStreamPtr _input) noexcept ...@@ -40,10 +41,13 @@ ProxyInputStream::SetInput(InputStreamPtr _input) noexcept
assert(_input); assert(_input);
input = std::move(_input); input = std::move(_input);
input->SetHandler(this);
/* this call wakes up client threads if the new input is /* this call wakes up client threads if the new input is
ready */ ready */
CopyAttributes(); CopyAttributes();
set_input_cond.signal();
} }
void void
...@@ -89,7 +93,7 @@ void ...@@ -89,7 +93,7 @@ void
ProxyInputStream::Seek(offset_type new_offset) ProxyInputStream::Seek(offset_type new_offset)
{ {
while (!input) while (!input)
cond.wait(mutex); set_input_cond.wait(mutex);
input->Seek(new_offset); input->Seek(new_offset);
CopyAttributes(); CopyAttributes();
...@@ -120,7 +124,7 @@ size_t ...@@ -120,7 +124,7 @@ size_t
ProxyInputStream::Read(void *ptr, size_t read_size) ProxyInputStream::Read(void *ptr, size_t read_size)
{ {
while (!input) while (!input)
cond.wait(mutex); set_input_cond.wait(mutex);
size_t nbytes = input->Read(ptr, read_size); size_t nbytes = input->Read(ptr, read_size);
CopyAttributes(); CopyAttributes();
......
...@@ -22,6 +22,8 @@ ...@@ -22,6 +22,8 @@
#include "InputStream.hxx" #include "InputStream.hxx"
#include "Ptr.hxx" #include "Ptr.hxx"
#include "Handler.hxx"
#include "thread/Cond.hxx"
struct Tag; struct Tag;
...@@ -33,7 +35,9 @@ struct Tag; ...@@ -33,7 +35,9 @@ struct Tag;
* The inner #InputStream instance may be nullptr initially, to be set * The inner #InputStream instance may be nullptr initially, to be set
* later. * later.
*/ */
class ProxyInputStream : public InputStream { class ProxyInputStream : public InputStream, protected InputStreamHandler {
Cond set_input_cond;
protected: protected:
InputStreamPtr input; InputStreamPtr input;
...@@ -45,8 +49,8 @@ public: ...@@ -45,8 +49,8 @@ public:
* Once that instance becomes available, call SetInput(). * Once that instance becomes available, call SetInput().
*/ */
ProxyInputStream(const char *_uri, ProxyInputStream(const char *_uri,
Mutex &_mutex, Cond &_cond) noexcept Mutex &_mutex) noexcept
:InputStream(_uri, _mutex, _cond) {} :InputStream(_uri, _mutex) {}
virtual ~ProxyInputStream() noexcept; virtual ~ProxyInputStream() noexcept;
...@@ -78,6 +82,15 @@ protected: ...@@ -78,6 +82,15 @@ protected:
* attributes. * attributes.
*/ */
void CopyAttributes(); void CopyAttributes();
/* virtual methods from class InputStreamHandler */
void OnInputStreamReady() noexcept override {
InvokeOnReady();
}
void OnInputStreamAvailable() noexcept override {
InvokeOnAvailable();
}
}; };
#endif #endif
...@@ -19,6 +19,7 @@ ...@@ -19,6 +19,7 @@
#include "config.h" #include "config.h"
#include "ThreadInputStream.hxx" #include "ThreadInputStream.hxx"
#include "CondHandler.hxx"
#include "thread/Name.hxx" #include "thread/Name.hxx"
#include <assert.h> #include <assert.h>
...@@ -26,9 +27,9 @@ ...@@ -26,9 +27,9 @@
ThreadInputStream::ThreadInputStream(const char *_plugin, ThreadInputStream::ThreadInputStream(const char *_plugin,
const char *_uri, const char *_uri,
Mutex &_mutex, Cond &_cond, Mutex &_mutex,
size_t _buffer_size) noexcept size_t _buffer_size) noexcept
:InputStream(_uri, _mutex, _cond), :InputStream(_uri, _mutex),
plugin(_plugin), plugin(_plugin),
thread(BIND_THIS_METHOD(ThreadFunc)), thread(BIND_THIS_METHOD(ThreadFunc)),
allocation(_buffer_size), allocation(_buffer_size),
...@@ -94,11 +95,11 @@ ThreadInputStream::ThreadFunc() noexcept ...@@ -94,11 +95,11 @@ ThreadInputStream::ThreadFunc() noexcept
nbytes = ThreadRead(w.data, w.size); nbytes = ThreadRead(w.data, w.size);
} catch (...) { } catch (...) {
postponed_exception = std::current_exception(); postponed_exception = std::current_exception();
cond.broadcast(); InvokeOnAvailable();
break; break;
} }
cond.broadcast(); InvokeOnAvailable();
if (nbytes == 0) { if (nbytes == 0) {
eof = true; eof = true;
...@@ -134,6 +135,8 @@ ThreadInputStream::Read(void *ptr, size_t read_size) ...@@ -134,6 +135,8 @@ ThreadInputStream::Read(void *ptr, size_t read_size)
{ {
assert(!thread.IsInside()); assert(!thread.IsInside());
CondInputStreamHandler cond_handler;
while (true) { while (true) {
if (postponed_exception) if (postponed_exception)
std::rethrow_exception(postponed_exception); std::rethrow_exception(postponed_exception);
...@@ -151,7 +154,8 @@ ThreadInputStream::Read(void *ptr, size_t read_size) ...@@ -151,7 +154,8 @@ ThreadInputStream::Read(void *ptr, size_t read_size)
if (eof) if (eof)
return 0; return 0;
cond.wait(mutex); const ScopeExchangeInputStreamHandler h(*this, &cond_handler);
cond_handler.cond.wait(mutex);
} }
} }
......
...@@ -76,7 +76,7 @@ class ThreadInputStream : public InputStream { ...@@ -76,7 +76,7 @@ class ThreadInputStream : public InputStream {
public: public:
ThreadInputStream(const char *_plugin, ThreadInputStream(const char *_plugin,
const char *_uri, Mutex &_mutex, Cond &_cond, const char *_uri, Mutex &_mutex,
size_t _buffer_size) noexcept; size_t _buffer_size) noexcept;
#ifndef NDEBUG #ifndef NDEBUG
......
...@@ -75,10 +75,10 @@ class AlsaInputStream final ...@@ -75,10 +75,10 @@ class AlsaInputStream final
public: public:
AlsaInputStream(EventLoop &_loop, AlsaInputStream(EventLoop &_loop,
const char *_uri, Mutex &_mutex, Cond &_cond, const char *_uri, Mutex &_mutex,
const char *_device, const char *_device,
snd_pcm_t *_handle, int _frame_size) snd_pcm_t *_handle, int _frame_size)
:AsyncInputStream(_loop, _uri, _mutex, _cond, :AsyncInputStream(_loop, _uri, _mutex,
ALSA_MAX_BUFFERED, ALSA_RESUME_AT), ALSA_MAX_BUFFERED, ALSA_RESUME_AT),
MultiSocketMonitor(_loop), MultiSocketMonitor(_loop),
device(_device), device(_device),
...@@ -111,7 +111,7 @@ public: ...@@ -111,7 +111,7 @@ public:
} }
static InputStreamPtr Create(EventLoop &event_loop, const char *uri, static InputStreamPtr Create(EventLoop &event_loop, const char *uri,
Mutex &mutex, Cond &cond); Mutex &mutex);
protected: protected:
/* virtual methods from AsyncInputStream */ /* virtual methods from AsyncInputStream */
...@@ -148,7 +148,7 @@ private: ...@@ -148,7 +148,7 @@ private:
inline InputStreamPtr inline InputStreamPtr
AlsaInputStream::Create(EventLoop &event_loop, const char *uri, AlsaInputStream::Create(EventLoop &event_loop, const char *uri,
Mutex &mutex, Cond &cond) Mutex &mutex)
{ {
const char *device = StringAfterPrefix(uri, "alsa://"); const char *device = StringAfterPrefix(uri, "alsa://");
if (device == nullptr) if (device == nullptr)
...@@ -168,7 +168,7 @@ AlsaInputStream::Create(EventLoop &event_loop, const char *uri, ...@@ -168,7 +168,7 @@ AlsaInputStream::Create(EventLoop &event_loop, const char *uri,
int frame_size = snd_pcm_format_width(format) / 8 * channels; int frame_size = snd_pcm_format_width(format) / 8 * channels;
return std::make_unique<AlsaInputStream>(event_loop, return std::make_unique<AlsaInputStream>(event_loop,
uri, mutex, cond, uri, mutex,
device, handle, frame_size); device, handle, frame_size);
} }
...@@ -204,7 +204,7 @@ AlsaInputStream::DispatchSockets() noexcept ...@@ -204,7 +204,7 @@ AlsaInputStream::DispatchSockets() noexcept
if (Recover(n_frames) < 0) { if (Recover(n_frames) < 0) {
postponed_exception = std::make_exception_ptr(std::runtime_error("PCM error - stream aborted")); postponed_exception = std::make_exception_ptr(std::runtime_error("PCM error - stream aborted"));
cond.broadcast(); InvokeOnAvailable();
return; return;
} }
} }
...@@ -403,10 +403,10 @@ alsa_input_init(EventLoop &event_loop, const ConfigBlock &) ...@@ -403,10 +403,10 @@ alsa_input_init(EventLoop &event_loop, const ConfigBlock &)
} }
static InputStreamPtr static InputStreamPtr
alsa_input_open(const char *uri, Mutex &mutex, Cond &cond) alsa_input_open(const char *uri, Mutex &mutex)
{ {
return AlsaInputStream::Create(*alsa_input_event_loop, uri, return AlsaInputStream::Create(*alsa_input_event_loop, uri,
mutex, cond); mutex);
} }
const struct InputPlugin input_plugin_alsa = { const struct InputPlugin input_plugin_alsa = {
......
...@@ -35,7 +35,7 @@ ...@@ -35,7 +35,7 @@
#include <stdlib.h> #include <stdlib.h>
InputStreamPtr InputStreamPtr
OpenArchiveInputStream(Path path, Mutex &mutex, Cond &cond) OpenArchiveInputStream(Path path, Mutex &mutex)
{ {
const ArchivePlugin *arplug; const ArchivePlugin *arplug;
...@@ -61,5 +61,5 @@ OpenArchiveInputStream(Path path, Mutex &mutex, Cond &cond) ...@@ -61,5 +61,5 @@ OpenArchiveInputStream(Path path, Mutex &mutex, Cond &cond)
} }
return archive_file_open(arplug, Path::FromFS(archive)) return archive_file_open(arplug, Path::FromFS(archive))
->OpenStream(filename, mutex, cond); ->OpenStream(filename, mutex);
} }
...@@ -24,9 +24,8 @@ ...@@ -24,9 +24,8 @@
class Path; class Path;
class Mutex; class Mutex;
class Cond;
InputStreamPtr InputStreamPtr
OpenArchiveInputStream(Path path, Mutex &mutex, Cond &cond); OpenArchiveInputStream(Path path, Mutex &mutex);
#endif #endif
...@@ -61,11 +61,11 @@ class CdioParanoiaInputStream final : public InputStream { ...@@ -61,11 +61,11 @@ class CdioParanoiaInputStream final : public InputStream {
int buffer_lsn; int buffer_lsn;
public: public:
CdioParanoiaInputStream(const char *_uri, Mutex &_mutex, Cond &_cond, CdioParanoiaInputStream(const char *_uri, Mutex &_mutex,
cdrom_drive_t *_drv, CdIo_t *_cdio, cdrom_drive_t *_drv, CdIo_t *_cdio,
bool reverse_endian, bool reverse_endian,
lsn_t _lsn_from, lsn_t _lsn_to) lsn_t _lsn_from, lsn_t _lsn_to)
:InputStream(_uri, _mutex, _cond), :InputStream(_uri, _mutex),
drv(_drv), cdio(_cdio), para(cdio_paranoia_init(drv)), drv(_drv), cdio(_cdio), para(cdio_paranoia_init(drv)),
lsn_from(_lsn_from), lsn_to(_lsn_to), lsn_from(_lsn_from), lsn_to(_lsn_to),
lsn_relofs(0), lsn_relofs(0),
...@@ -184,7 +184,7 @@ cdio_detect_device(void) ...@@ -184,7 +184,7 @@ cdio_detect_device(void)
static InputStreamPtr static InputStreamPtr
input_cdio_open(const char *uri, input_cdio_open(const char *uri,
Mutex &mutex, Cond &cond) Mutex &mutex)
{ {
struct cdio_uri parsed_uri; struct cdio_uri parsed_uri;
if (!parse_cdio_uri(&parsed_uri, uri)) if (!parse_cdio_uri(&parsed_uri, uri))
...@@ -250,7 +250,7 @@ input_cdio_open(const char *uri, ...@@ -250,7 +250,7 @@ input_cdio_open(const char *uri,
lsn_to = cdio_get_disc_last_lsn(cdio); lsn_to = cdio_get_disc_last_lsn(cdio);
} }
return std::make_unique<CdioParanoiaInputStream>(uri, mutex, cond, return std::make_unique<CdioParanoiaInputStream>(uri, mutex,
drv, cdio, drv, cdio,
reverse_endian, reverse_endian,
lsn_from, lsn_to); lsn_from, lsn_to);
......
...@@ -35,7 +35,6 @@ ...@@ -35,7 +35,6 @@
#include "tag/Tag.hxx" #include "tag/Tag.hxx"
#include "event/Call.hxx" #include "event/Call.hxx"
#include "event/Loop.hxx" #include "event/Loop.hxx"
#include "thread/Cond.hxx"
#include "util/ASCII.hxx" #include "util/ASCII.hxx"
#include "util/StringUtil.hxx" #include "util/StringUtil.hxx"
#include "util/StringFormat.hxx" #include "util/StringFormat.hxx"
...@@ -83,7 +82,7 @@ public: ...@@ -83,7 +82,7 @@ public:
CurlInputStream(EventLoop &event_loop, const char *_url, CurlInputStream(EventLoop &event_loop, const char *_url,
const std::multimap<std::string, std::string> &headers, const std::multimap<std::string, std::string> &headers,
I &&_icy, I &&_icy,
Mutex &_mutex, Cond &_cond); Mutex &_mutex);
~CurlInputStream() noexcept; ~CurlInputStream() noexcept;
...@@ -92,7 +91,7 @@ public: ...@@ -92,7 +91,7 @@ public:
static InputStreamPtr Open(const char *url, static InputStreamPtr Open(const char *url,
const std::multimap<std::string, std::string> &headers, const std::multimap<std::string, std::string> &headers,
Mutex &mutex, Cond &cond); Mutex &mutex);
private: private:
/** /**
...@@ -274,7 +273,7 @@ void ...@@ -274,7 +273,7 @@ void
CurlInputStream::OnEnd() CurlInputStream::OnEnd()
{ {
const std::lock_guard<Mutex> protect(mutex); const std::lock_guard<Mutex> protect(mutex);
cond.broadcast(); InvokeOnAvailable();
AsyncInputStream::SetClosed(); AsyncInputStream::SetClosed();
} }
...@@ -290,7 +289,7 @@ CurlInputStream::OnError(std::exception_ptr e) noexcept ...@@ -290,7 +289,7 @@ CurlInputStream::OnError(std::exception_ptr e) noexcept
else if (!IsReady()) else if (!IsReady())
SetReady(); SetReady();
else else
cond.broadcast(); InvokeOnAvailable();
AsyncInputStream::SetClosed(); AsyncInputStream::SetClosed();
} }
...@@ -352,8 +351,8 @@ inline ...@@ -352,8 +351,8 @@ inline
CurlInputStream::CurlInputStream(EventLoop &event_loop, const char *_url, CurlInputStream::CurlInputStream(EventLoop &event_loop, const char *_url,
const std::multimap<std::string, std::string> &headers, const std::multimap<std::string, std::string> &headers,
I &&_icy, I &&_icy,
Mutex &_mutex, Cond &_cond) Mutex &_mutex)
:AsyncInputStream(event_loop, _url, _mutex, _cond, :AsyncInputStream(event_loop, _url, _mutex,
CURL_MAX_BUFFERED, CURL_MAX_BUFFERED,
CURL_RESUME_AT), CURL_RESUME_AT),
icy(std::forward<I>(_icy)) icy(std::forward<I>(_icy))
...@@ -445,14 +444,14 @@ CurlInputStream::DoSeek(offset_type new_offset) ...@@ -445,14 +444,14 @@ CurlInputStream::DoSeek(offset_type new_offset)
inline InputStreamPtr inline InputStreamPtr
CurlInputStream::Open(const char *url, CurlInputStream::Open(const char *url,
const std::multimap<std::string, std::string> &headers, const std::multimap<std::string, std::string> &headers,
Mutex &mutex, Cond &cond) Mutex &mutex)
{ {
auto icy = std::make_shared<IcyMetaDataParser>(); auto icy = std::make_shared<IcyMetaDataParser>();
auto c = std::make_unique<CurlInputStream>((*curl_init)->GetEventLoop(), auto c = std::make_unique<CurlInputStream>((*curl_init)->GetEventLoop(),
url, headers, url, headers,
icy, icy,
mutex, cond); mutex);
BlockingCall(c->GetEventLoop(), [&c](){ BlockingCall(c->GetEventLoop(), [&c](){
c->InitEasy(); c->InitEasy();
...@@ -465,19 +464,19 @@ CurlInputStream::Open(const char *url, ...@@ -465,19 +464,19 @@ CurlInputStream::Open(const char *url,
InputStreamPtr InputStreamPtr
OpenCurlInputStream(const char *uri, OpenCurlInputStream(const char *uri,
const std::multimap<std::string, std::string> &headers, const std::multimap<std::string, std::string> &headers,
Mutex &mutex, Cond &cond) Mutex &mutex)
{ {
return CurlInputStream::Open(uri, headers, mutex, cond); return CurlInputStream::Open(uri, headers, mutex);
} }
static InputStreamPtr static InputStreamPtr
input_curl_open(const char *url, Mutex &mutex, Cond &cond) input_curl_open(const char *url, Mutex &mutex)
{ {
if (strncmp(url, "http://", 7) != 0 && if (strncmp(url, "http://", 7) != 0 &&
strncmp(url, "https://", 8) != 0) strncmp(url, "https://", 8) != 0)
return nullptr; return nullptr;
return CurlInputStream::Open(url, {}, mutex, cond); return CurlInputStream::Open(url, {}, mutex);
} }
const struct InputPlugin input_plugin_curl = { const struct InputPlugin input_plugin_curl = {
......
...@@ -26,7 +26,6 @@ ...@@ -26,7 +26,6 @@
#include <map> #include <map>
class Mutex; class Mutex;
class Cond;
extern const struct InputPlugin input_plugin_curl; extern const struct InputPlugin input_plugin_curl;
...@@ -40,6 +39,6 @@ extern const struct InputPlugin input_plugin_curl; ...@@ -40,6 +39,6 @@ extern const struct InputPlugin input_plugin_curl;
InputStreamPtr InputStreamPtr
OpenCurlInputStream(const char *uri, OpenCurlInputStream(const char *uri,
const std::multimap<std::string, std::string> &headers, const std::multimap<std::string, std::string> &headers,
Mutex &mutex, Cond &cond); Mutex &mutex);
#endif #endif
...@@ -39,9 +39,9 @@ struct FfmpegInputStream final : public InputStream { ...@@ -39,9 +39,9 @@ struct FfmpegInputStream final : public InputStream {
bool eof; bool eof;
FfmpegInputStream(const char *_uri, Mutex &_mutex, Cond &_cond, FfmpegInputStream(const char *_uri, Mutex &_mutex,
AVIOContext *_h) AVIOContext *_h)
:InputStream(_uri, _mutex, _cond), :InputStream(_uri, _mutex),
h(_h), eof(false) { h(_h), eof(false) {
seekable = (h->seekable & AVIO_SEEKABLE_NORMAL) != 0; seekable = (h->seekable & AVIO_SEEKABLE_NORMAL) != 0;
size = avio_size(h); size = avio_size(h);
...@@ -83,7 +83,7 @@ input_ffmpeg_init(EventLoop &, const ConfigBlock &) ...@@ -83,7 +83,7 @@ input_ffmpeg_init(EventLoop &, const ConfigBlock &)
static InputStreamPtr static InputStreamPtr
input_ffmpeg_open(const char *uri, input_ffmpeg_open(const char *uri,
Mutex &mutex, Cond &cond) Mutex &mutex)
{ {
if (!StringStartsWith(uri, "gopher://") && if (!StringStartsWith(uri, "gopher://") &&
!StringStartsWith(uri, "rtp://") && !StringStartsWith(uri, "rtp://") &&
...@@ -98,7 +98,7 @@ input_ffmpeg_open(const char *uri, ...@@ -98,7 +98,7 @@ input_ffmpeg_open(const char *uri,
if (result != 0) if (result != 0)
throw MakeFfmpegError(result); throw MakeFfmpegError(result);
return std::make_unique<FfmpegInputStream>(uri, mutex, cond, h); return std::make_unique<FfmpegInputStream>(uri, mutex, h);
} }
size_t size_t
......
...@@ -35,8 +35,8 @@ class FileInputStream final : public InputStream { ...@@ -35,8 +35,8 @@ class FileInputStream final : public InputStream {
public: public:
FileInputStream(const char *path, FileReader &&_reader, off_t _size, FileInputStream(const char *path, FileReader &&_reader, off_t _size,
Mutex &_mutex, Cond &_cond) Mutex &_mutex)
:InputStream(path, _mutex, _cond), :InputStream(path, _mutex),
reader(std::move(_reader)) { reader(std::move(_reader)) {
size = _size; size = _size;
seekable = true; seekable = true;
...@@ -54,8 +54,7 @@ public: ...@@ -54,8 +54,7 @@ public:
}; };
InputStreamPtr InputStreamPtr
OpenFileInputStream(Path path, OpenFileInputStream(Path path, Mutex &mutex)
Mutex &mutex, Cond &cond)
{ {
FileReader reader(path); FileReader reader(path);
...@@ -75,7 +74,7 @@ OpenFileInputStream(Path path, ...@@ -75,7 +74,7 @@ OpenFileInputStream(Path path,
return std::make_unique<FileInputStream>(path.ToUTF8().c_str(), return std::make_unique<FileInputStream>(path.ToUTF8().c_str(),
std::move(reader), info.GetSize(), std::move(reader), info.GetSize(),
mutex, cond); mutex);
} }
void void
......
...@@ -24,10 +24,8 @@ ...@@ -24,10 +24,8 @@
class Path; class Path;
class Mutex; class Mutex;
class Cond;
InputStreamPtr InputStreamPtr
OpenFileInputStream(Path path, OpenFileInputStream(Path path, Mutex &mutex);
Mutex &mutex, Cond &cond);
#endif #endif
...@@ -34,8 +34,8 @@ class MmsInputStream final : public ThreadInputStream { ...@@ -34,8 +34,8 @@ class MmsInputStream final : public ThreadInputStream {
mmsx_t *mms; mmsx_t *mms;
public: public:
MmsInputStream(const char *_uri, Mutex &_mutex, Cond &_cond) MmsInputStream(const char *_uri, Mutex &_mutex)
:ThreadInputStream(input_plugin_mms.name, _uri, _mutex, _cond, :ThreadInputStream(input_plugin_mms.name, _uri, _mutex,
MMS_BUFFER_SIZE) { MMS_BUFFER_SIZE) {
} }
...@@ -70,7 +70,7 @@ MmsInputStream::Open() ...@@ -70,7 +70,7 @@ MmsInputStream::Open()
static InputStreamPtr static InputStreamPtr
input_mms_open(const char *url, input_mms_open(const char *url,
Mutex &mutex, Cond &cond) Mutex &mutex)
{ {
if (!StringStartsWith(url, "mms://") && if (!StringStartsWith(url, "mms://") &&
!StringStartsWith(url, "mmsh://") && !StringStartsWith(url, "mmsh://") &&
...@@ -78,7 +78,7 @@ input_mms_open(const char *url, ...@@ -78,7 +78,7 @@ input_mms_open(const char *url,
!StringStartsWith(url, "mmsu://")) !StringStartsWith(url, "mmsu://"))
return nullptr; return nullptr;
auto m = std::make_unique<MmsInputStream>(url, mutex, cond); auto m = std::make_unique<MmsInputStream>(url, mutex);
m->Start(); m->Start();
return m; return m;
} }
......
...@@ -23,7 +23,6 @@ ...@@ -23,7 +23,6 @@
#include "../InputPlugin.hxx" #include "../InputPlugin.hxx"
#include "lib/nfs/Glue.hxx" #include "lib/nfs/Glue.hxx"
#include "lib/nfs/FileReader.hxx" #include "lib/nfs/FileReader.hxx"
#include "thread/Cond.hxx"
#include "util/StringCompare.hxx" #include "util/StringCompare.hxx"
#include <string.h> #include <string.h>
...@@ -46,9 +45,9 @@ class NfsInputStream final : NfsFileReader, public AsyncInputStream { ...@@ -46,9 +45,9 @@ class NfsInputStream final : NfsFileReader, public AsyncInputStream {
bool reconnect_on_resume = false, reconnecting = false; bool reconnect_on_resume = false, reconnecting = false;
public: public:
NfsInputStream(const char *_uri, Mutex &_mutex, Cond &_cond) NfsInputStream(const char *_uri, Mutex &_mutex)
:AsyncInputStream(NfsFileReader::GetEventLoop(), :AsyncInputStream(NfsFileReader::GetEventLoop(),
_uri, _mutex, _cond, _uri, _mutex,
NFS_MAX_BUFFERED, NFS_MAX_BUFFERED,
NFS_RESUME_AT) {} NFS_RESUME_AT) {}
...@@ -100,7 +99,7 @@ NfsInputStream::DoRead() ...@@ -100,7 +99,7 @@ NfsInputStream::DoRead()
NfsFileReader::Read(next_offset, nbytes); NfsFileReader::Read(next_offset, nbytes);
} catch (...) { } catch (...) {
postponed_exception = std::current_exception(); postponed_exception = std::current_exception();
cond.broadcast(); InvokeOnAvailable();
} }
} }
...@@ -196,7 +195,7 @@ NfsInputStream::OnNfsFileError(std::exception_ptr &&e) noexcept ...@@ -196,7 +195,7 @@ NfsInputStream::OnNfsFileError(std::exception_ptr &&e) noexcept
else if (!IsReady()) else if (!IsReady())
SetReady(); SetReady();
else else
cond.broadcast(); InvokeOnAvailable();
} }
/* /*
...@@ -218,12 +217,12 @@ input_nfs_finish() noexcept ...@@ -218,12 +217,12 @@ input_nfs_finish() noexcept
static InputStreamPtr static InputStreamPtr
input_nfs_open(const char *uri, input_nfs_open(const char *uri,
Mutex &mutex, Cond &cond) Mutex &mutex)
{ {
if (!StringStartsWith(uri, "nfs://")) if (!StringStartsWith(uri, "nfs://"))
return nullptr; return nullptr;
auto is = std::make_unique<NfsInputStream>(uri, mutex, cond); auto is = std::make_unique<NfsInputStream>(uri, mutex);
is->Open(); is->Open();
return is; return is;
} }
......
...@@ -49,8 +49,8 @@ class QobuzInputStream final ...@@ -49,8 +49,8 @@ class QobuzInputStream final
public: public:
QobuzInputStream(const char *_uri, const char *_track_id, QobuzInputStream(const char *_uri, const char *_track_id,
Mutex &_mutex, Cond &_cond) noexcept Mutex &_mutex) noexcept
:ProxyInputStream(_uri, _mutex, _cond), :ProxyInputStream(_uri, _mutex),
track_id(_track_id) track_id(_track_id)
{ {
qobuz_client->AddLoginHandler(*this); qobuz_client->AddLoginHandler(*this);
...@@ -70,7 +70,7 @@ public: ...@@ -70,7 +70,7 @@ public:
private: private:
void Failed(std::exception_ptr e) { void Failed(std::exception_ptr e) {
SetInput(std::make_unique<FailingInputStream>(GetURI(), e, SetInput(std::make_unique<FailingInputStream>(GetURI(), e,
mutex, cond)); mutex));
} }
/* virtual methods from QobuzSessionHandler */ /* virtual methods from QobuzSessionHandler */
...@@ -89,11 +89,11 @@ QobuzInputStream::OnQobuzSession() noexcept ...@@ -89,11 +89,11 @@ QobuzInputStream::OnQobuzSession() noexcept
try { try {
const auto session = qobuz_client->GetSession(); const auto session = qobuz_client->GetSession();
QobuzTrackHandler &handler = *this; QobuzTrackHandler &h = *this;
track_request = std::make_unique<QobuzTrackRequest>(*qobuz_client, track_request = std::make_unique<QobuzTrackRequest>(*qobuz_client,
session, session,
track_id.c_str(), track_id.c_str(),
handler); h);
track_request->Start(); track_request->Start();
} catch (...) { } catch (...) {
Failed(std::current_exception()); Failed(std::current_exception());
...@@ -108,7 +108,7 @@ QobuzInputStream::OnQobuzTrackSuccess(std::string url) noexcept ...@@ -108,7 +108,7 @@ QobuzInputStream::OnQobuzTrackSuccess(std::string url) noexcept
try { try {
SetInput(OpenCurlInputStream(url.c_str(), {}, SetInput(OpenCurlInputStream(url.c_str(), {},
mutex, cond)); mutex));
} catch (...) { } catch (...) {
Failed(std::current_exception()); Failed(std::current_exception());
} }
...@@ -180,7 +180,7 @@ ExtractQobuzTrackId(const char *uri) ...@@ -180,7 +180,7 @@ ExtractQobuzTrackId(const char *uri)
} }
static InputStreamPtr static InputStreamPtr
OpenQobuzInput(const char *uri, Mutex &mutex, Cond &cond) OpenQobuzInput(const char *uri, Mutex &mutex)
{ {
assert(qobuz_client != nullptr); assert(qobuz_client != nullptr);
...@@ -190,7 +190,7 @@ OpenQobuzInput(const char *uri, Mutex &mutex, Cond &cond) ...@@ -190,7 +190,7 @@ OpenQobuzInput(const char *uri, Mutex &mutex, Cond &cond)
// TODO: validate track_id // TODO: validate track_id
return std::make_unique<QobuzInputStream>(uri, track_id, mutex, cond); return std::make_unique<QobuzInputStream>(uri, track_id, mutex);
} }
static std::unique_ptr<RemoteTagScanner> static std::unique_ptr<RemoteTagScanner>
......
...@@ -37,9 +37,9 @@ class SmbclientInputStream final : public InputStream { ...@@ -37,9 +37,9 @@ class SmbclientInputStream final : public InputStream {
public: public:
SmbclientInputStream(const char *_uri, SmbclientInputStream(const char *_uri,
Mutex &_mutex, Cond &_cond, Mutex &_mutex,
SMBCCTX *_ctx, int _fd, const struct stat &st) SMBCCTX *_ctx, int _fd, const struct stat &st)
:InputStream(_uri, _mutex, _cond), :InputStream(_uri, _mutex),
ctx(_ctx), fd(_fd) { ctx(_ctx), fd(_fd) {
seekable = true; seekable = true;
size = st.st_size; size = st.st_size;
...@@ -85,7 +85,7 @@ input_smbclient_init(EventLoop &, const ConfigBlock &) ...@@ -85,7 +85,7 @@ input_smbclient_init(EventLoop &, const ConfigBlock &)
static InputStreamPtr static InputStreamPtr
input_smbclient_open(const char *uri, input_smbclient_open(const char *uri,
Mutex &mutex, Cond &cond) Mutex &mutex)
{ {
if (!StringStartsWith(uri, "smb://")) if (!StringStartsWith(uri, "smb://"))
return nullptr; return nullptr;
...@@ -119,7 +119,7 @@ input_smbclient_open(const char *uri, ...@@ -119,7 +119,7 @@ input_smbclient_open(const char *uri,
throw MakeErrno(e, "smbc_fstat() failed"); throw MakeErrno(e, "smbc_fstat() failed");
} }
return std::make_unique<SmbclientInputStream>(uri, mutex, cond, return std::make_unique<SmbclientInputStream>(uri, mutex,
ctx, fd, st); ctx, fd, st);
} }
......
...@@ -60,8 +60,8 @@ class TidalInputStream final ...@@ -60,8 +60,8 @@ class TidalInputStream final
public: public:
TidalInputStream(const char *_uri, const char *_track_id, TidalInputStream(const char *_uri, const char *_track_id,
Mutex &_mutex, Cond &_cond) noexcept Mutex &_mutex) noexcept
:ProxyInputStream(_uri, _mutex, _cond), :ProxyInputStream(_uri, _mutex),
track_id(_track_id) track_id(_track_id)
{ {
tidal_session->AddLoginHandler(*this); tidal_session->AddLoginHandler(*this);
...@@ -81,7 +81,7 @@ public: ...@@ -81,7 +81,7 @@ public:
private: private:
void Failed(std::exception_ptr e) { void Failed(std::exception_ptr e) {
SetInput(std::make_unique<FailingInputStream>(GetURI(), e, SetInput(std::make_unique<FailingInputStream>(GetURI(), e,
mutex, cond)); mutex));
} }
/* virtual methods from TidalSessionHandler */ /* virtual methods from TidalSessionHandler */
...@@ -98,14 +98,14 @@ TidalInputStream::OnTidalSession() noexcept ...@@ -98,14 +98,14 @@ TidalInputStream::OnTidalSession() noexcept
const std::lock_guard<Mutex> protect(mutex); const std::lock_guard<Mutex> protect(mutex);
try { try {
TidalTrackHandler &handler = *this; TidalTrackHandler &h = *this;
track_request = std::make_unique<TidalTrackRequest>(tidal_session->GetCurl(), track_request = std::make_unique<TidalTrackRequest>(tidal_session->GetCurl(),
tidal_session->GetBaseUrl(), tidal_session->GetBaseUrl(),
tidal_session->GetToken(), tidal_session->GetToken(),
tidal_session->GetSession().c_str(), tidal_session->GetSession().c_str(),
track_id.c_str(), track_id.c_str(),
tidal_audioquality, tidal_audioquality,
handler); h);
track_request->Start(); track_request->Start();
} catch (...) { } catch (...) {
Failed(std::current_exception()); Failed(std::current_exception());
...@@ -124,7 +124,7 @@ TidalInputStream::OnTidalTrackSuccess(std::string url) noexcept ...@@ -124,7 +124,7 @@ TidalInputStream::OnTidalTrackSuccess(std::string url) noexcept
try { try {
SetInput(OpenCurlInputStream(url.c_str(), {}, SetInput(OpenCurlInputStream(url.c_str(), {},
mutex, cond)); mutex));
} catch (...) { } catch (...) {
Failed(std::current_exception()); Failed(std::current_exception());
} }
...@@ -211,7 +211,7 @@ ExtractTidalTrackId(const char *uri) ...@@ -211,7 +211,7 @@ ExtractTidalTrackId(const char *uri)
} }
static InputStreamPtr static InputStreamPtr
OpenTidalInput(const char *uri, Mutex &mutex, Cond &cond) OpenTidalInput(const char *uri, Mutex &mutex)
{ {
assert(tidal_session != nullptr); assert(tidal_session != nullptr);
...@@ -221,7 +221,7 @@ OpenTidalInput(const char *uri, Mutex &mutex, Cond &cond) ...@@ -221,7 +221,7 @@ OpenTidalInput(const char *uri, Mutex &mutex, Cond &cond)
// TODO: validate track_id // TODO: validate track_id
return std::make_unique<TidalInputStream>(uri, track_id, mutex, cond); return std::make_unique<TidalInputStream>(uri, track_id, mutex);
} }
static std::unique_ptr<RemoteTagScanner> static std::unique_ptr<RemoteTagScanner>
......
...@@ -29,13 +29,13 @@ playlist_open_any(const char *uri, ...@@ -29,13 +29,13 @@ playlist_open_any(const char *uri,
#ifdef ENABLE_DATABASE #ifdef ENABLE_DATABASE
const Storage *storage, const Storage *storage,
#endif #endif
Mutex &mutex, Cond &cond) Mutex &mutex)
{ {
return uri_has_scheme(uri) return uri_has_scheme(uri)
? playlist_open_remote(uri, mutex, cond) ? playlist_open_remote(uri, mutex)
: playlist_mapper_open(uri, : playlist_mapper_open(uri,
#ifdef ENABLE_DATABASE #ifdef ENABLE_DATABASE
storage, storage,
#endif #endif
mutex, cond); mutex);
} }
...@@ -23,7 +23,6 @@ ...@@ -23,7 +23,6 @@
#include <memory> #include <memory>
class Mutex; class Mutex;
class Cond;
class SongEnumerator; class SongEnumerator;
class Storage; class Storage;
...@@ -37,6 +36,6 @@ playlist_open_any(const char *uri, ...@@ -37,6 +36,6 @@ playlist_open_any(const char *uri,
#ifdef ENABLE_DATABASE #ifdef ENABLE_DATABASE
const Storage *storage, const Storage *storage,
#endif #endif
Mutex &mutex, Cond &cond); Mutex &mutex);
#endif #endif
...@@ -33,7 +33,7 @@ ...@@ -33,7 +33,7 @@
* Load a playlist from the configured playlist directory. * Load a playlist from the configured playlist directory.
*/ */
static std::unique_ptr<SongEnumerator> static std::unique_ptr<SongEnumerator>
playlist_open_in_playlist_dir(const char *uri, Mutex &mutex, Cond &cond) playlist_open_in_playlist_dir(const char *uri, Mutex &mutex)
{ {
assert(spl_valid_name(uri)); assert(spl_valid_name(uri));
...@@ -41,7 +41,7 @@ playlist_open_in_playlist_dir(const char *uri, Mutex &mutex, Cond &cond) ...@@ -41,7 +41,7 @@ playlist_open_in_playlist_dir(const char *uri, Mutex &mutex, Cond &cond)
if (path_fs.IsNull()) if (path_fs.IsNull())
return nullptr; return nullptr;
return playlist_open_path(path_fs, mutex, cond); return playlist_open_path(path_fs, mutex);
} }
#ifdef ENABLE_DATABASE #ifdef ENABLE_DATABASE
...@@ -50,8 +50,7 @@ playlist_open_in_playlist_dir(const char *uri, Mutex &mutex, Cond &cond) ...@@ -50,8 +50,7 @@ playlist_open_in_playlist_dir(const char *uri, Mutex &mutex, Cond &cond)
* Load a playlist from the configured music directory. * Load a playlist from the configured music directory.
*/ */
static std::unique_ptr<SongEnumerator> static std::unique_ptr<SongEnumerator>
playlist_open_in_storage(const char *uri, const Storage *storage, playlist_open_in_storage(const char *uri, const Storage *storage, Mutex &mutex)
Mutex &mutex, Cond &cond)
{ {
assert(uri_safe_local(uri)); assert(uri_safe_local(uri));
...@@ -61,11 +60,11 @@ playlist_open_in_storage(const char *uri, const Storage *storage, ...@@ -61,11 +60,11 @@ playlist_open_in_storage(const char *uri, const Storage *storage,
{ {
const auto path = storage->MapFS(uri); const auto path = storage->MapFS(uri);
if (!path.IsNull()) if (!path.IsNull())
return playlist_open_path(path, mutex, cond); return playlist_open_path(path, mutex);
} }
const auto uri2 = storage->MapUTF8(uri); const auto uri2 = storage->MapUTF8(uri);
return playlist_open_remote(uri2.c_str(), mutex, cond); return playlist_open_remote(uri2.c_str(), mutex);
} }
#endif #endif
...@@ -75,19 +74,17 @@ playlist_mapper_open(const char *uri, ...@@ -75,19 +74,17 @@ playlist_mapper_open(const char *uri,
#ifdef ENABLE_DATABASE #ifdef ENABLE_DATABASE
const Storage *storage, const Storage *storage,
#endif #endif
Mutex &mutex, Cond &cond) Mutex &mutex)
{ {
if (spl_valid_name(uri)) { if (spl_valid_name(uri)) {
auto playlist = playlist_open_in_playlist_dir(uri, auto playlist = playlist_open_in_playlist_dir(uri, mutex);
mutex, cond);
if (playlist != nullptr) if (playlist != nullptr)
return playlist; return playlist;
} }
#ifdef ENABLE_DATABASE #ifdef ENABLE_DATABASE
if (uri_safe_local(uri)) { if (uri_safe_local(uri)) {
auto playlist = playlist_open_in_storage(uri, storage, auto playlist = playlist_open_in_storage(uri, storage, mutex);
mutex, cond);
if (playlist != nullptr) if (playlist != nullptr)
return playlist; return playlist;
} }
......
...@@ -25,7 +25,6 @@ ...@@ -25,7 +25,6 @@
#include <memory> #include <memory>
class Mutex; class Mutex;
class Cond;
class SongEnumerator; class SongEnumerator;
class Storage; class Storage;
...@@ -38,6 +37,6 @@ playlist_mapper_open(const char *uri, ...@@ -38,6 +37,6 @@ playlist_mapper_open(const char *uri,
#ifdef ENABLE_DATABASE #ifdef ENABLE_DATABASE
const Storage *storage, const Storage *storage,
#endif #endif
Mutex &mutex, Cond &cond); Mutex &mutex);
#endif #endif
...@@ -25,7 +25,6 @@ ...@@ -25,7 +25,6 @@
struct ConfigBlock; struct ConfigBlock;
struct Tag; struct Tag;
class Mutex; class Mutex;
class Cond;
class SongEnumerator; class SongEnumerator;
struct playlist_plugin { struct playlist_plugin {
...@@ -52,7 +51,7 @@ struct playlist_plugin { ...@@ -52,7 +51,7 @@ struct playlist_plugin {
* either matched one of the schemes or one of the suffixes. * either matched one of the schemes or one of the suffixes.
*/ */
std::unique_ptr<SongEnumerator> (*open_uri)(const char *uri, std::unique_ptr<SongEnumerator> (*open_uri)(const char *uri,
Mutex &mutex, Cond &cond); Mutex &mutex);
/** /**
* Opens the playlist in the specified input stream. It has * Opens the playlist in the specified input stream. It has
......
...@@ -26,7 +26,6 @@ ...@@ -26,7 +26,6 @@
#include "SongEnumerator.hxx" #include "SongEnumerator.hxx"
#include "DetachedSong.hxx" #include "DetachedSong.hxx"
#include "thread/Mutex.hxx" #include "thread/Mutex.hxx"
#include "thread/Cond.hxx"
#include "fs/Traits.hxx" #include "fs/Traits.hxx"
#ifdef ENABLE_DATABASE #ifdef ENABLE_DATABASE
...@@ -70,13 +69,12 @@ playlist_open_into_queue(const char *uri, ...@@ -70,13 +69,12 @@ playlist_open_into_queue(const char *uri,
const SongLoader &loader) const SongLoader &loader)
{ {
Mutex mutex; Mutex mutex;
Cond cond;
auto playlist = playlist_open_any(uri, auto playlist = playlist_open_any(uri,
#ifdef ENABLE_DATABASE #ifdef ENABLE_DATABASE
loader.GetStorage(), loader.GetStorage(),
#endif #endif
mutex, cond); mutex);
if (playlist == nullptr) if (playlist == nullptr)
throw PlaylistError::NoSuchList(); throw PlaylistError::NoSuchList();
......
...@@ -103,7 +103,7 @@ playlist_list_global_finish() noexcept ...@@ -103,7 +103,7 @@ playlist_list_global_finish() noexcept
} }
static std::unique_ptr<SongEnumerator> static std::unique_ptr<SongEnumerator>
playlist_list_open_uri_scheme(const char *uri, Mutex &mutex, Cond &cond, playlist_list_open_uri_scheme(const char *uri, Mutex &mutex,
bool *tried) bool *tried)
{ {
assert(uri != nullptr); assert(uri != nullptr);
...@@ -120,7 +120,7 @@ playlist_list_open_uri_scheme(const char *uri, Mutex &mutex, Cond &cond, ...@@ -120,7 +120,7 @@ playlist_list_open_uri_scheme(const char *uri, Mutex &mutex, Cond &cond,
if (playlist_plugins_enabled[i] && plugin->open_uri != nullptr && if (playlist_plugins_enabled[i] && plugin->open_uri != nullptr &&
plugin->schemes != nullptr && plugin->schemes != nullptr &&
StringArrayContainsCase(plugin->schemes, scheme.c_str())) { StringArrayContainsCase(plugin->schemes, scheme.c_str())) {
auto playlist = plugin->open_uri(uri, mutex, cond); auto playlist = plugin->open_uri(uri, mutex);
if (playlist) if (playlist)
return playlist; return playlist;
...@@ -132,7 +132,7 @@ playlist_list_open_uri_scheme(const char *uri, Mutex &mutex, Cond &cond, ...@@ -132,7 +132,7 @@ playlist_list_open_uri_scheme(const char *uri, Mutex &mutex, Cond &cond,
} }
static std::unique_ptr<SongEnumerator> static std::unique_ptr<SongEnumerator>
playlist_list_open_uri_suffix(const char *uri, Mutex &mutex, Cond &cond, playlist_list_open_uri_suffix(const char *uri, Mutex &mutex,
const bool *tried) const bool *tried)
{ {
assert(uri != nullptr); assert(uri != nullptr);
...@@ -148,7 +148,7 @@ playlist_list_open_uri_suffix(const char *uri, Mutex &mutex, Cond &cond, ...@@ -148,7 +148,7 @@ playlist_list_open_uri_suffix(const char *uri, Mutex &mutex, Cond &cond,
if (playlist_plugins_enabled[i] && !tried[i] && if (playlist_plugins_enabled[i] && !tried[i] &&
plugin->open_uri != nullptr && plugin->suffixes != nullptr && plugin->open_uri != nullptr && plugin->suffixes != nullptr &&
StringArrayContainsCase(plugin->suffixes, suffix)) { StringArrayContainsCase(plugin->suffixes, suffix)) {
auto playlist = plugin->open_uri(uri, mutex, cond); auto playlist = plugin->open_uri(uri, mutex);
if (playlist != nullptr) if (playlist != nullptr)
return playlist; return playlist;
} }
...@@ -158,7 +158,7 @@ playlist_list_open_uri_suffix(const char *uri, Mutex &mutex, Cond &cond, ...@@ -158,7 +158,7 @@ playlist_list_open_uri_suffix(const char *uri, Mutex &mutex, Cond &cond,
} }
std::unique_ptr<SongEnumerator> std::unique_ptr<SongEnumerator>
playlist_list_open_uri(const char *uri, Mutex &mutex, Cond &cond) playlist_list_open_uri(const char *uri, Mutex &mutex)
{ {
/** this array tracks which plugins have already been tried by /** this array tracks which plugins have already been tried by
playlist_list_open_uri_scheme() */ playlist_list_open_uri_scheme() */
...@@ -168,9 +168,9 @@ playlist_list_open_uri(const char *uri, Mutex &mutex, Cond &cond) ...@@ -168,9 +168,9 @@ playlist_list_open_uri(const char *uri, Mutex &mutex, Cond &cond)
memset(tried, false, sizeof(tried)); memset(tried, false, sizeof(tried));
auto playlist = playlist_list_open_uri_scheme(uri, mutex, cond, tried); auto playlist = playlist_list_open_uri_scheme(uri, mutex, tried);
if (playlist == nullptr) if (playlist == nullptr)
playlist = playlist_list_open_uri_suffix(uri, mutex, cond, playlist = playlist_list_open_uri_suffix(uri, mutex,
tried); tried);
return playlist; return playlist;
......
...@@ -24,7 +24,6 @@ ...@@ -24,7 +24,6 @@
#include "Compiler.h" #include "Compiler.h"
class Mutex; class Mutex;
class Cond;
class SongEnumerator; class SongEnumerator;
extern const struct playlist_plugin *const playlist_plugins[]; extern const struct playlist_plugin *const playlist_plugins[];
...@@ -51,7 +50,7 @@ playlist_list_global_finish() noexcept; ...@@ -51,7 +50,7 @@ playlist_list_global_finish() noexcept;
* Opens a playlist by its URI. * Opens a playlist by its URI.
*/ */
std::unique_ptr<SongEnumerator> std::unique_ptr<SongEnumerator>
playlist_list_open_uri(const char *uri, Mutex &mutex, Cond &cond); playlist_list_open_uri(const char *uri, Mutex &mutex);
std::unique_ptr<SongEnumerator> std::unique_ptr<SongEnumerator>
playlist_list_open_stream_suffix(InputStreamPtr &&is, const char *suffix); playlist_list_open_stream_suffix(InputStreamPtr &&is, const char *suffix);
......
...@@ -32,7 +32,7 @@ ...@@ -32,7 +32,7 @@
#include <assert.h> #include <assert.h>
static std::unique_ptr<SongEnumerator> static std::unique_ptr<SongEnumerator>
playlist_open_path_suffix(Path path, Mutex &mutex, Cond &cond) playlist_open_path_suffix(Path path, Mutex &mutex)
try { try {
assert(!path.IsNull()); assert(!path.IsNull());
...@@ -44,7 +44,7 @@ try { ...@@ -44,7 +44,7 @@ try {
if (!playlist_suffix_supported(suffix_utf8.c_str())) if (!playlist_suffix_supported(suffix_utf8.c_str()))
return nullptr; return nullptr;
auto is = OpenLocalInputStream(path, mutex, cond); auto is = OpenLocalInputStream(path, mutex);
return playlist_list_open_stream_suffix(std::move(is), return playlist_list_open_stream_suffix(std::move(is),
suffix_utf8.c_str()); suffix_utf8.c_str());
} catch (...) { } catch (...) {
...@@ -53,16 +53,16 @@ try { ...@@ -53,16 +53,16 @@ try {
} }
std::unique_ptr<SongEnumerator> std::unique_ptr<SongEnumerator>
playlist_open_path(Path path, Mutex &mutex, Cond &cond) playlist_open_path(Path path, Mutex &mutex)
try { try {
assert(!path.IsNull()); assert(!path.IsNull());
const std::string uri_utf8 = path.ToUTF8(); const std::string uri_utf8 = path.ToUTF8();
auto playlist = !uri_utf8.empty() auto playlist = !uri_utf8.empty()
? playlist_list_open_uri(uri_utf8.c_str(), mutex, cond) ? playlist_list_open_uri(uri_utf8.c_str(), mutex)
: nullptr; : nullptr;
if (playlist == nullptr) if (playlist == nullptr)
playlist = playlist_open_path_suffix(path, mutex, cond); playlist = playlist_open_path_suffix(path, mutex);
return playlist; return playlist;
} catch (...) { } catch (...) {
...@@ -71,15 +71,15 @@ try { ...@@ -71,15 +71,15 @@ try {
} }
std::unique_ptr<SongEnumerator> std::unique_ptr<SongEnumerator>
playlist_open_remote(const char *uri, Mutex &mutex, Cond &cond) playlist_open_remote(const char *uri, Mutex &mutex)
try { try {
assert(uri_has_scheme(uri)); assert(uri_has_scheme(uri));
auto playlist = playlist_list_open_uri(uri, mutex, cond); auto playlist = playlist_list_open_uri(uri, mutex);
if (playlist != nullptr) if (playlist != nullptr)
return playlist; return playlist;
auto is = InputStream::OpenReady(uri, mutex, cond); auto is = InputStream::OpenReady(uri, mutex);
return playlist_list_open_stream(std::move(is), uri); return playlist_list_open_stream(std::move(is), uri);
} catch (...) { } catch (...) {
LogError(std::current_exception()); LogError(std::current_exception());
......
...@@ -25,7 +25,6 @@ ...@@ -25,7 +25,6 @@
#include <memory> #include <memory>
class Mutex; class Mutex;
class Cond;
class SongEnumerator; class SongEnumerator;
class Path; class Path;
...@@ -37,10 +36,10 @@ class Path; ...@@ -37,10 +36,10 @@ class Path;
*/ */
gcc_nonnull_all gcc_nonnull_all
std::unique_ptr<SongEnumerator> std::unique_ptr<SongEnumerator>
playlist_open_path(Path path, Mutex &mutex, Cond &cond); playlist_open_path(Path path, Mutex &mutex);
gcc_nonnull_all gcc_nonnull_all
std::unique_ptr<SongEnumerator> std::unique_ptr<SongEnumerator>
playlist_open_remote(const char *uri, Mutex &mutex, Cond &cond); playlist_open_remote(const char *uri, Mutex &mutex);
#endif #endif
...@@ -26,7 +26,6 @@ ...@@ -26,7 +26,6 @@
#include "DetachedSong.hxx" #include "DetachedSong.hxx"
#include "fs/Traits.hxx" #include "fs/Traits.hxx"
#include "thread/Mutex.hxx" #include "thread/Mutex.hxx"
#include "thread/Cond.hxx"
#include "Partition.hxx" #include "Partition.hxx"
#include "Instance.hxx" #include "Instance.hxx"
...@@ -59,7 +58,6 @@ playlist_file_print(Response &r, Partition &partition, ...@@ -59,7 +58,6 @@ playlist_file_print(Response &r, Partition &partition,
const char *uri, bool detail) const char *uri, bool detail)
{ {
Mutex mutex; Mutex mutex;
Cond cond;
#ifndef ENABLE_DATABASE #ifndef ENABLE_DATABASE
(void)partition; (void)partition;
...@@ -69,7 +67,7 @@ playlist_file_print(Response &r, Partition &partition, ...@@ -69,7 +67,7 @@ playlist_file_print(Response &r, Partition &partition,
#ifdef ENABLE_DATABASE #ifdef ENABLE_DATABASE
partition.instance.storage, partition.instance.storage,
#endif #endif
mutex, cond); mutex);
if (playlist == nullptr) if (playlist == nullptr)
return false; return false;
......
...@@ -89,8 +89,7 @@ static constexpr TagHandler embcue_tag_handler = { ...@@ -89,8 +89,7 @@ static constexpr TagHandler embcue_tag_handler = {
static std::unique_ptr<SongEnumerator> static std::unique_ptr<SongEnumerator>
embcue_playlist_open_uri(const char *uri, embcue_playlist_open_uri(const char *uri,
gcc_unused Mutex &mutex, gcc_unused Mutex &mutex)
gcc_unused Cond &cond)
{ {
if (!PathTraitsUTF8::IsAbsolute(uri)) if (!PathTraitsUTF8::IsAbsolute(uri))
/* only local files supported */ /* only local files supported */
......
...@@ -88,7 +88,7 @@ FlacPlaylist::NextSong() ...@@ -88,7 +88,7 @@ FlacPlaylist::NextSong()
static std::unique_ptr<SongEnumerator> static std::unique_ptr<SongEnumerator>
flac_playlist_open_uri(const char *uri, flac_playlist_open_uri(const char *uri,
gcc_unused Mutex &mutex, gcc_unused Cond &cond) gcc_unused Mutex &mutex)
{ {
if (!PathTraitsUTF8::IsAbsolute(uri)) if (!PathTraitsUTF8::IsAbsolute(uri))
/* only local files supported */ /* only local files supported */
......
...@@ -221,9 +221,9 @@ static constexpr yajl_callbacks parse_callbacks = { ...@@ -221,9 +221,9 @@ static constexpr yajl_callbacks parse_callbacks = {
*/ */
static void static void
soundcloud_parse_json(const char *url, Yajl::Handle &handle, soundcloud_parse_json(const char *url, Yajl::Handle &handle,
Mutex &mutex, Cond &cond) Mutex &mutex)
{ {
auto input_stream = InputStream::OpenReady(url, mutex, cond); auto input_stream = InputStream::OpenReady(url, mutex);
Yajl::ParseInputStream(handle, *input_stream); Yajl::ParseInputStream(handle, *input_stream);
} }
...@@ -235,7 +235,7 @@ soundcloud_parse_json(const char *url, Yajl::Handle &handle, ...@@ -235,7 +235,7 @@ soundcloud_parse_json(const char *url, Yajl::Handle &handle,
* soundcloud://url/<url or path of soundcloud page> * soundcloud://url/<url or path of soundcloud page>
*/ */
static std::unique_ptr<SongEnumerator> static std::unique_ptr<SongEnumerator>
soundcloud_open_uri(const char *uri, Mutex &mutex, Cond &cond) soundcloud_open_uri(const char *uri, Mutex &mutex)
{ {
assert(strncmp(uri, "soundcloud://", 13) == 0); assert(strncmp(uri, "soundcloud://", 13) == 0);
uri += 13; uri += 13;
...@@ -277,7 +277,7 @@ soundcloud_open_uri(const char *uri, Mutex &mutex, Cond &cond) ...@@ -277,7 +277,7 @@ soundcloud_open_uri(const char *uri, Mutex &mutex, Cond &cond)
SoundCloudJsonData data; SoundCloudJsonData data;
Yajl::Handle handle(&parse_callbacks, nullptr, &data); Yajl::Handle handle(&parse_callbacks, nullptr, &data);
soundcloud_parse_json(u, handle, mutex, cond); soundcloud_parse_json(u, handle, mutex);
data.songs.reverse(); data.songs.reverse();
return std::make_unique<MemorySongEnumerator>(std::move(data.songs)); return std::make_unique<MemorySongEnumerator>(std::move(data.songs));
......
...@@ -23,7 +23,6 @@ ...@@ -23,7 +23,6 @@
#include "ApeTag.hxx" #include "ApeTag.hxx"
#include "fs/Path.hxx" #include "fs/Path.hxx"
#include "thread/Mutex.hxx" #include "thread/Mutex.hxx"
#include "thread/Cond.hxx"
#include "input/InputStream.hxx" #include "input/InputStream.hxx"
#include "input/LocalOpen.hxx" #include "input/LocalOpen.hxx"
#include "Log.hxx" #include "Log.hxx"
...@@ -53,9 +52,8 @@ bool ...@@ -53,9 +52,8 @@ bool
ScanGenericTags(Path path, const TagHandler &handler, void *ctx) ScanGenericTags(Path path, const TagHandler &handler, void *ctx)
try { try {
Mutex mutex; Mutex mutex;
Cond cond;
auto is = OpenLocalInputStream(path, mutex, cond); auto is = OpenLocalInputStream(path, mutex);
return ScanGenericTags(*is, handler, ctx); return ScanGenericTags(*is, handler, ctx);
} catch (...) { } catch (...) {
LogError(std::current_exception()); LogError(std::current_exception());
......
...@@ -73,7 +73,7 @@ DumpDecoderClient::SeekError() ...@@ -73,7 +73,7 @@ DumpDecoderClient::SeekError()
InputStreamPtr InputStreamPtr
DumpDecoderClient::OpenUri(const char *uri) DumpDecoderClient::OpenUri(const char *uri)
{ {
return InputStream::OpenReady(uri, mutex, cond); return InputStream::OpenReady(uri, mutex);
} }
size_t size_t
......
...@@ -23,7 +23,6 @@ ...@@ -23,7 +23,6 @@
#include "check.h" #include "check.h"
#include "decoder/Client.hxx" #include "decoder/Client.hxx"
#include "thread/Mutex.hxx" #include "thread/Mutex.hxx"
#include "thread/Cond.hxx"
/** /**
* A #DecoderClient implementation which dumps metadata to stderr and * A #DecoderClient implementation which dumps metadata to stderr and
...@@ -36,7 +35,6 @@ class DumpDecoderClient final : public DecoderClient { ...@@ -36,7 +35,6 @@ class DumpDecoderClient final : public DecoderClient {
public: public:
Mutex mutex; Mutex mutex;
Cond cond;
bool IsInitialized() const noexcept { bool IsInitialized() const noexcept {
return initialized; return initialized;
......
...@@ -20,7 +20,6 @@ ...@@ -20,7 +20,6 @@
#include "config.h" #include "config.h"
#include "tag/ApeLoader.hxx" #include "tag/ApeLoader.hxx"
#include "thread/Mutex.hxx" #include "thread/Mutex.hxx"
#include "thread/Cond.hxx"
#include "fs/Path.hxx" #include "fs/Path.hxx"
#include "Log.hxx" #include "Log.hxx"
#include "input/InputStream.hxx" #include "input/InputStream.hxx"
...@@ -62,9 +61,8 @@ try { ...@@ -62,9 +61,8 @@ try {
const Path path = Path::FromFS(argv[1]); const Path path = Path::FromFS(argv[1]);
Mutex mutex; Mutex mutex;
Cond cond;
auto is = OpenLocalInputStream(path, mutex, cond); auto is = OpenLocalInputStream(path, mutex);
if (!tag_ape_scan(*is, MyApeTagCallback)) { if (!tag_ape_scan(*is, MyApeTagCallback)) {
fprintf(stderr, "error\n"); fprintf(stderr, "error\n");
......
...@@ -74,14 +74,13 @@ try { ...@@ -74,14 +74,13 @@ try {
/* open the playlist */ /* open the playlist */
Mutex mutex; Mutex mutex;
Cond cond;
InputStreamPtr is; InputStreamPtr is;
auto playlist = playlist_list_open_uri(uri, mutex, cond); auto playlist = playlist_list_open_uri(uri, mutex);
if (playlist == NULL) { if (playlist == NULL) {
/* open the stream and wait until it becomes ready */ /* open the stream and wait until it becomes ready */
is = InputStream::OpenReady(uri, mutex, cond); is = InputStream::OpenReady(uri, mutex);
/* open the playlist */ /* open the playlist */
......
...@@ -23,7 +23,6 @@ ...@@ -23,7 +23,6 @@
#include "ReplayGainInfo.hxx" #include "ReplayGainInfo.hxx"
#include "config/ConfigGlobal.hxx" #include "config/ConfigGlobal.hxx"
#include "thread/Mutex.hxx" #include "thread/Mutex.hxx"
#include "thread/Cond.hxx"
#include "fs/Path.hxx" #include "fs/Path.hxx"
#include "input/InputStream.hxx" #include "input/InputStream.hxx"
#include "input/LocalOpen.hxx" #include "input/LocalOpen.hxx"
...@@ -75,9 +74,8 @@ try { ...@@ -75,9 +74,8 @@ try {
const Path path = Path::FromFS(argv[1]); const Path path = Path::FromFS(argv[1]);
Mutex mutex; Mutex mutex;
Cond cond;
auto is = OpenLocalInputStream(path, mutex, cond); auto is = OpenLocalInputStream(path, mutex);
const auto tag = tag_id3_load(*is); const auto tag = tag_id3_load(*is);
if (tag == NULL) { if (tag == NULL) {
......
...@@ -23,7 +23,6 @@ ...@@ -23,7 +23,6 @@
#include "input/InputStream.hxx" #include "input/InputStream.hxx"
#include "input/TextInputStream.hxx" #include "input/TextInputStream.hxx"
#include "config/ConfigGlobal.hxx" #include "config/ConfigGlobal.hxx"
#include "thread/Cond.hxx"
#include "Log.hxx" #include "Log.hxx"
#ifdef ENABLE_ARCHIVE #ifdef ENABLE_ARCHIVE
...@@ -94,9 +93,8 @@ try { ...@@ -94,9 +93,8 @@ try {
/* open the stream and dump it */ /* open the stream and dump it */
Mutex mutex; Mutex mutex;
Cond cond;
auto is = InputStream::OpenReady(argv[1], mutex, cond); auto is = InputStream::OpenReady(argv[1], mutex);
return dump_input_stream(std::move(is)); return dump_input_stream(std::move(is));
} catch (const std::exception &e) { } catch (const std::exception &e) {
LogError(e); LogError(e);
......
...@@ -26,7 +26,6 @@ ...@@ -26,7 +26,6 @@
#include "tag/Handler.hxx" #include "tag/Handler.hxx"
#include "tag/Generic.hxx" #include "tag/Generic.hxx"
#include "fs/Path.hxx" #include "fs/Path.hxx"
#include "thread/Cond.hxx"
#include "Log.hxx" #include "Log.hxx"
#include "util/ScopeExit.hxx" #include "util/ScopeExit.hxx"
...@@ -110,11 +109,10 @@ try { ...@@ -110,11 +109,10 @@ try {
} }
Mutex mutex; Mutex mutex;
Cond cond;
InputStreamPtr is; InputStreamPtr is;
if (!success && plugin->scan_stream != NULL) { if (!success && plugin->scan_stream != NULL) {
is = InputStream::OpenReady(path.c_str(), mutex, cond); is = InputStream::OpenReady(path.c_str(), mutex);
success = plugin->ScanStream(*is, print_handler, nullptr); success = plugin->ScanStream(*is, print_handler, nullptr);
} }
......
...@@ -123,8 +123,7 @@ try { ...@@ -123,8 +123,7 @@ try {
if (plugin->file_decode != nullptr) { if (plugin->file_decode != nullptr) {
plugin->FileDecode(client, Path::FromFS(c.uri)); plugin->FileDecode(client, Path::FromFS(c.uri));
} else if (plugin->stream_decode != nullptr) { } else if (plugin->stream_decode != nullptr) {
auto is = InputStream::OpenReady(c.uri, client.mutex, auto is = InputStream::OpenReady(c.uri, client.mutex);
client.cond);
plugin->StreamDecode(client, *is); plugin->StreamDecode(client, *is);
} else { } else {
fprintf(stderr, "Decoder plugin is not usable\n"); fprintf(stderr, "Decoder plugin is not usable\n");
......
...@@ -239,8 +239,7 @@ try { ...@@ -239,8 +239,7 @@ try {
/* open the stream and dump it */ /* open the stream and dump it */
Mutex mutex; Mutex mutex;
Cond cond; auto is = InputStream::OpenReady(c.uri, mutex);
auto is = InputStream::OpenReady(c.uri, mutex, cond);
return dump_input_stream(is.get()); return dump_input_stream(is.get());
} catch (const std::exception &e) { } catch (const std::exception &e) {
LogError(e); LogError(e);
......
...@@ -6,7 +6,6 @@ ...@@ -6,7 +6,6 @@
#include "input/RewindInputStream.hxx" #include "input/RewindInputStream.hxx"
#include "input/InputStream.hxx" #include "input/InputStream.hxx"
#include "thread/Mutex.hxx" #include "thread/Mutex.hxx"
#include "thread/Cond.hxx"
#include <cppunit/TestFixture.h> #include <cppunit/TestFixture.h>
#include <cppunit/extensions/TestFactoryRegistry.h> #include <cppunit/extensions/TestFactoryRegistry.h>
...@@ -24,9 +23,9 @@ class StringInputStream final : public InputStream { ...@@ -24,9 +23,9 @@ class StringInputStream final : public InputStream {
public: public:
StringInputStream(const char *_uri, StringInputStream(const char *_uri,
Mutex &_mutex, Cond &_cond, Mutex &_mutex,
const char *_data) const char *_data)
:InputStream(_uri, _mutex, _cond), :InputStream(_uri, _mutex),
data(_data), remaining(strlen(data)) { data(_data), remaining(strlen(data)) {
SetReady(); SetReady();
} }
...@@ -54,10 +53,9 @@ class RewindTest : public CppUnit::TestFixture { ...@@ -54,10 +53,9 @@ class RewindTest : public CppUnit::TestFixture {
public: public:
void TestRewind() { void TestRewind() {
Mutex mutex; Mutex mutex;
Cond cond;
StringInputStream *sis = StringInputStream *sis =
new StringInputStream("foo://", mutex, cond, new StringInputStream("foo://", mutex,
"foo bar"); "foo bar");
CPPUNIT_ASSERT(sis->IsReady()); CPPUNIT_ASSERT(sis->IsReady());
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment