diff options
-rw-r--r-- | src/db/update/Service.cxx | 10 | ||||
-rw-r--r-- | src/db/update/Service.hxx | 1 | ||||
-rw-r--r-- | src/decoder/DecoderControl.cxx | 3 | ||||
-rw-r--r-- | src/decoder/DecoderControl.hxx | 3 | ||||
-rw-r--r-- | src/decoder/DecoderThread.cxx | 38 | ||||
-rw-r--r-- | src/event/Thread.cxx | 14 | ||||
-rw-r--r-- | src/event/Thread.hxx | 6 | ||||
-rw-r--r-- | src/input/ThreadInputStream.cxx | 11 | ||||
-rw-r--r-- | src/input/ThreadInputStream.hxx | 2 | ||||
-rw-r--r-- | src/neighbor/plugins/SmbclientNeighborPlugin.cxx | 17 | ||||
-rw-r--r-- | src/output/Init.cxx | 3 | ||||
-rw-r--r-- | src/output/Internal.hxx | 1 | ||||
-rw-r--r-- | src/output/OutputThread.cxx | 11 | ||||
-rw-r--r-- | src/player/Control.cxx | 1 | ||||
-rw-r--r-- | src/player/Control.hxx | 3 | ||||
-rw-r--r-- | src/player/Thread.cxx | 74 | ||||
-rw-r--r-- | src/thread/Thread.cxx | 7 | ||||
-rw-r--r-- | src/thread/Thread.hxx | 11 | ||||
-rw-r--r-- | test/run_output.cxx | 2 |
19 files changed, 94 insertions, 124 deletions
diff --git a/src/db/update/Service.cxx b/src/db/update/Service.cxx index 2e7fe72da..099dc8104 100644 --- a/src/db/update/Service.cxx +++ b/src/db/update/Service.cxx @@ -43,6 +43,7 @@ UpdateService::UpdateService(EventLoop &_loop, SimpleDatabase &_db, :DeferredMonitor(_loop), db(_db), storage(_storage), listener(_listener), + update_thread(BIND_THIS_METHOD(Task)), update_task_id(0), walk(nullptr) { @@ -141,13 +142,6 @@ UpdateService::Task() } void -UpdateService::Task(void *ctx) -{ - UpdateService &service = *(UpdateService *)ctx; - return service.Task(); -} - -void UpdateService::StartThread(UpdateQueueItem &&i) { assert(GetEventLoop().IsInsideOrNull()); @@ -158,7 +152,7 @@ UpdateService::StartThread(UpdateQueueItem &&i) next = std::move(i); walk = new UpdateWalk(GetEventLoop(), listener, *next.storage); - update_thread.Start(Task, this); + update_thread.Start(); FormatDebug(update_domain, "spawned thread for update job id %i", next.id); diff --git a/src/db/update/Service.hxx b/src/db/update/Service.hxx index 9bd2c344f..4ca38c52b 100644 --- a/src/db/update/Service.hxx +++ b/src/db/update/Service.hxx @@ -98,7 +98,6 @@ private: /* the update thread */ void Task(); - static void Task(void *ctx); void StartThread(UpdateQueueItem &&i); diff --git a/src/decoder/DecoderControl.cxx b/src/decoder/DecoderControl.cxx index 92a21873d..ca724fe36 100644 --- a/src/decoder/DecoderControl.cxx +++ b/src/decoder/DecoderControl.cxx @@ -30,7 +30,8 @@ DecoderControl::DecoderControl(Mutex &_mutex, Cond &_client_cond, const AudioFormat _configured_audio_format, const ReplayGainConfig &_replay_gain_config) - :mutex(_mutex), client_cond(_client_cond), + :thread(BIND_THIS_METHOD(RunThread)), + mutex(_mutex), client_cond(_client_cond), configured_audio_format(_configured_audio_format), replay_gain_config(_replay_gain_config) {} diff --git a/src/decoder/DecoderControl.hxx b/src/decoder/DecoderControl.hxx index ae405896d..90d10d960 100644 --- a/src/decoder/DecoderControl.hxx +++ b/src/decoder/DecoderControl.hxx @@ -415,6 +415,9 @@ public: * mixramp_start/mixramp_end. */ void CycleMixRamp(); + +private: + void RunThread(); }; #endif diff --git a/src/decoder/DecoderThread.cxx b/src/decoder/DecoderThread.cxx index 3dbc11179..5b0e80e60 100644 --- a/src/decoder/DecoderThread.cxx +++ b/src/decoder/DecoderThread.cxx @@ -510,30 +510,28 @@ try { dc.client_cond.signal(); } -static void -decoder_task(void *arg) +void +DecoderControl::RunThread() { - DecoderControl &dc = *(DecoderControl *)arg; - SetThreadName("decoder"); - const std::lock_guard<Mutex> protect(dc.mutex); + const std::lock_guard<Mutex> protect(mutex); do { - assert(dc.state == DecoderState::STOP || - dc.state == DecoderState::ERROR); + assert(state == DecoderState::STOP || + state == DecoderState::ERROR); - switch (dc.command) { + switch (command) { case DecoderCommand::START: - dc.CycleMixRamp(); - dc.replay_gain_prev_db = dc.replay_gain_db; - dc.replay_gain_db = 0; + CycleMixRamp(); + replay_gain_prev_db = replay_gain_db; + replay_gain_db = 0; - decoder_run(dc); + decoder_run(*this); - if (dc.state == DecoderState::ERROR) { + if (state == DecoderState::ERROR) { try { - std::rethrow_exception(dc.error); + std::rethrow_exception(error); } catch (const std::exception &e) { LogError(e); } catch (...) { @@ -549,20 +547,20 @@ decoder_task(void *arg) /* we need to clear the pipe here; usually the PlayerThread is responsible, but it is not aware that the decoder has finished */ - dc.pipe->Clear(*dc.buffer); + pipe->Clear(*buffer); - decoder_run(dc); + decoder_run(*this); break; case DecoderCommand::STOP: - dc.CommandFinishedLocked(); + CommandFinishedLocked(); break; case DecoderCommand::NONE: - dc.Wait(); + Wait(); break; } - } while (dc.command != DecoderCommand::NONE || !dc.quit); + } while (command != DecoderCommand::NONE || !quit); } void @@ -571,5 +569,5 @@ decoder_thread_start(DecoderControl &dc) assert(!dc.thread.IsDefined()); dc.quit = false; - dc.thread.Start(decoder_task, &dc); + dc.thread.Start(); } diff --git a/src/event/Thread.cxx b/src/event/Thread.cxx index e5c8ed0bc..5b7f47adf 100644 --- a/src/event/Thread.cxx +++ b/src/event/Thread.cxx @@ -26,7 +26,7 @@ EventThread::Start() { assert(!thread.IsDefined()); - thread.Start(ThreadFunc, this); + thread.Start(); } void @@ -39,17 +39,9 @@ EventThread::Stop() } void -EventThread::ThreadFunc() +EventThread::Run() { SetThreadName("io"); event_loop.Run(); -}; - -void -EventThread::ThreadFunc(void *arg) -{ - auto &et = *(EventThread *)arg; - - et.ThreadFunc(); -}; +} diff --git a/src/event/Thread.hxx b/src/event/Thread.hxx index 737740825..98edc9c08 100644 --- a/src/event/Thread.hxx +++ b/src/event/Thread.hxx @@ -33,6 +33,9 @@ class EventThread final { Thread thread; public: + EventThread() + :thread(BIND_THIS_METHOD(Run)) {} + ~EventThread() { Stop(); } @@ -55,8 +58,7 @@ public: void Stop(); private: - void ThreadFunc(); - static void ThreadFunc(void *arg); + void Run(); }; #endif /* MAIN_NOTIFY_H */ diff --git a/src/input/ThreadInputStream.cxx b/src/input/ThreadInputStream.cxx index 77faf4b5b..fa9343e53 100644 --- a/src/input/ThreadInputStream.cxx +++ b/src/input/ThreadInputStream.cxx @@ -54,10 +54,10 @@ ThreadInputStream::Start() assert(p != nullptr); buffer = new CircularBuffer<uint8_t>((uint8_t *)p, buffer_size); - thread.Start(ThreadFunc, this); + thread.Start(); } -inline void +void ThreadInputStream::ThreadFunc() { FormatThreadName("input:%s", plugin); @@ -108,13 +108,6 @@ ThreadInputStream::ThreadFunc() } void -ThreadInputStream::ThreadFunc(void *ctx) -{ - ThreadInputStream &tis = *(ThreadInputStream *)ctx; - tis.ThreadFunc(); -} - -void ThreadInputStream::Check() { assert(!thread.IsInside()); diff --git a/src/input/ThreadInputStream.hxx b/src/input/ThreadInputStream.hxx index 7bc168926..1cd5196d0 100644 --- a/src/input/ThreadInputStream.hxx +++ b/src/input/ThreadInputStream.hxx @@ -73,6 +73,7 @@ public: size_t _buffer_size) :InputStream(_uri, _mutex, _cond), plugin(_plugin), + thread(BIND_THIS_METHOD(ThreadFunc)), buffer_size(_buffer_size) {} virtual ~ThreadInputStream(); @@ -138,7 +139,6 @@ protected: private: void ThreadFunc(); - static void ThreadFunc(void *ctx); }; #endif diff --git a/src/neighbor/plugins/SmbclientNeighborPlugin.cxx b/src/neighbor/plugins/SmbclientNeighborPlugin.cxx index 2ccfcc1e2..3b7a8b069 100644 --- a/src/neighbor/plugins/SmbclientNeighborPlugin.cxx +++ b/src/neighbor/plugins/SmbclientNeighborPlugin.cxx @@ -69,7 +69,8 @@ class SmbclientNeighborExplorer final : public NeighborExplorer { public: SmbclientNeighborExplorer(NeighborListener &_listener) - :NeighborExplorer(_listener) {} + :NeighborExplorer(_listener), + thread(BIND_THIS_METHOD(ThreadFunc)) {} /* virtual methods from class NeighborExplorer */ void Open() override; @@ -79,14 +80,13 @@ public: private: void Run(); void ThreadFunc(); - static void ThreadFunc(void *ctx); }; void SmbclientNeighborExplorer::Open() { quit = false; - thread.Start(ThreadFunc, this); + thread.Start(); } void @@ -239,6 +239,8 @@ SmbclientNeighborExplorer::Run() inline void SmbclientNeighborExplorer::ThreadFunc() { + SetThreadName("smbclient"); + mutex.lock(); while (!quit) { @@ -257,15 +259,6 @@ SmbclientNeighborExplorer::ThreadFunc() mutex.unlock(); } -void -SmbclientNeighborExplorer::ThreadFunc(void *ctx) -{ - SetThreadName("smbclient"); - - SmbclientNeighborExplorer &e = *(SmbclientNeighborExplorer *)ctx; - e.ThreadFunc(); -} - static NeighborExplorer * smbclient_neighbor_create(gcc_unused EventLoop &loop, NeighborListener &listener, diff --git a/src/output/Init.cxx b/src/output/Init.cxx index df28292e6..185971d8c 100644 --- a/src/output/Init.cxx +++ b/src/output/Init.cxx @@ -51,7 +51,8 @@ AudioOutput::AudioOutput(const AudioOutputPlugin &_plugin, const ConfigBlock &block) - :plugin(_plugin) + :plugin(_plugin), + thread(BIND_THIS_METHOD(Task)) { assert(plugin.finish != nullptr); assert(plugin.open != nullptr); diff --git a/src/output/Internal.hxx b/src/output/Internal.hxx index 023ee1e23..8ca6b1276 100644 --- a/src/output/Internal.hxx +++ b/src/output/Internal.hxx @@ -515,7 +515,6 @@ private: * The OutputThread. */ void Task(); - static void Task(void *arg); }; /** diff --git a/src/output/OutputThread.cxx b/src/output/OutputThread.cxx index 0f10b47f0..507d3342a 100644 --- a/src/output/OutputThread.cxx +++ b/src/output/OutputThread.cxx @@ -398,7 +398,7 @@ AudioOutput::Pause() pause = false; } -inline void +void AudioOutput::Task() { FormatThreadName("output:%s", name); @@ -515,16 +515,9 @@ AudioOutput::Task() } void -AudioOutput::Task(void *arg) -{ - AudioOutput *ao = (AudioOutput *)arg; - ao->Task(); -} - -void AudioOutput::StartThread() { assert(command == Command::NONE); - thread.Start(Task, this); + thread.Start(); } diff --git a/src/player/Control.cxx b/src/player/Control.cxx index 2b70b2a41..d46b7e424 100644 --- a/src/player/Control.cxx +++ b/src/player/Control.cxx @@ -37,6 +37,7 @@ PlayerControl::PlayerControl(PlayerListener &_listener, buffer_chunks(_buffer_chunks), buffered_before_play(_buffered_before_play), configured_audio_format(_configured_audio_format), + thread(BIND_THIS_METHOD(RunThread)), replay_gain_config(_replay_gain_config) { } diff --git a/src/player/Control.hxx b/src/player/Control.hxx index 7bb8b7c79..e753e3149 100644 --- a/src/player/Control.hxx +++ b/src/player/Control.hxx @@ -537,6 +537,9 @@ public: void ApplyEnabled() override { LockUpdateAudio(); } + +private: + void RunThread(); }; #endif diff --git a/src/player/Thread.cxx b/src/player/Thread.cxx index 3e7ef8f90..eaeb7e3b5 100644 --- a/src/player/Thread.cxx +++ b/src/player/Thread.cxx @@ -1136,91 +1136,89 @@ do_play(PlayerControl &pc, DecoderControl &dc, player.Run(); } -static void -player_task(void *arg) +void +PlayerControl::RunThread() { - PlayerControl &pc = *(PlayerControl *)arg; - SetThreadName("player"); - DecoderControl dc(pc.mutex, pc.cond, - pc.configured_audio_format, - pc.replay_gain_config); + DecoderControl dc(mutex, cond, + configured_audio_format, + replay_gain_config); decoder_thread_start(dc); - MusicBuffer buffer(pc.buffer_chunks); + MusicBuffer buffer(buffer_chunks); - pc.Lock(); + Lock(); while (1) { - switch (pc.command) { + switch (command) { case PlayerCommand::SEEK: case PlayerCommand::QUEUE: - assert(pc.next_song != nullptr); + assert(next_song != nullptr); - pc.Unlock(); - do_play(pc, dc, buffer); - pc.listener.OnPlayerSync(); - pc.Lock(); + Unlock(); + do_play(*this, dc, buffer); + listener.OnPlayerSync(); + Lock(); break; case PlayerCommand::STOP: - pc.Unlock(); - pc.outputs.Cancel(); - pc.Lock(); + Unlock(); + outputs.Cancel(); + Lock(); /* fall through */ case PlayerCommand::PAUSE: - delete pc.next_song; - pc.next_song = nullptr; + delete next_song; + next_song = nullptr; - pc.CommandFinished(); + CommandFinished(); break; case PlayerCommand::CLOSE_AUDIO: - pc.Unlock(); + Unlock(); - pc.outputs.Release(); + outputs.Release(); - pc.Lock(); - pc.CommandFinished(); + Lock(); + CommandFinished(); assert(buffer.IsEmptyUnsafe()); break; case PlayerCommand::UPDATE_AUDIO: - pc.Unlock(); - pc.outputs.EnableDisable(); - pc.Lock(); - pc.CommandFinished(); + Unlock(); + outputs.EnableDisable(); + Lock(); + CommandFinished(); break; case PlayerCommand::EXIT: - pc.Unlock(); + Unlock(); dc.Quit(); - pc.outputs.Close(); + outputs.Close(); - pc.LockCommandFinished(); + LockCommandFinished(); return; case PlayerCommand::CANCEL: - delete pc.next_song; - pc.next_song = nullptr; + delete next_song; + next_song = nullptr; - pc.CommandFinished(); + CommandFinished(); break; case PlayerCommand::REFRESH: /* no-op when not playing */ - pc.CommandFinished(); + CommandFinished(); break; case PlayerCommand::NONE: - pc.Wait(); + Wait(); break; } } @@ -1231,5 +1229,5 @@ StartPlayerThread(PlayerControl &pc) { assert(!pc.thread.IsDefined()); - pc.thread.Start(player_task, &pc); + pc.thread.Start(); } diff --git a/src/thread/Thread.cxx b/src/thread/Thread.cxx index bdb7021fe..69b7333bf 100644 --- a/src/thread/Thread.cxx +++ b/src/thread/Thread.cxx @@ -26,13 +26,10 @@ #endif void -Thread::Start(void (*_f)(void *ctx), void *_ctx) +Thread::Start() { assert(!IsDefined()); - f = _f; - ctx = _ctx; - #ifdef WIN32 handle = ::CreateThread(nullptr, 0, ThreadProc, this, 0, &id); if (handle == nullptr) @@ -87,7 +84,7 @@ Thread::Run() #endif #endif - f(ctx); + f(); #ifdef ANDROID Java::DetachCurrentThread(); diff --git a/src/thread/Thread.hxx b/src/thread/Thread.hxx index 1dbedbd97..86a3efae3 100644 --- a/src/thread/Thread.hxx +++ b/src/thread/Thread.hxx @@ -21,6 +21,7 @@ #define MPD_THREAD_HXX #include "check.h" +#include "util/BindMethod.hxx" #include "Compiler.h" #ifdef WIN32 @@ -32,6 +33,9 @@ #include <assert.h> class Thread { + typedef BoundMethod<void()> Function; + const Function f; + #ifdef WIN32 HANDLE handle = nullptr; DWORD id; @@ -49,11 +53,8 @@ class Thread { #endif #endif - void (*f)(void *ctx); - void *ctx; - public: - Thread() = default; + explicit Thread(Function _f):f(_f) {} Thread(const Thread &) = delete; @@ -89,7 +90,7 @@ public: #endif } - void Start(void (*f)(void *ctx), void *ctx); + void Start(); void Join(); private: diff --git a/test/run_output.cxx b/test/run_output.cxx index a4a39b826..13178957d 100644 --- a/test/run_output.cxx +++ b/test/run_output.cxx @@ -43,6 +43,8 @@ #include <stdlib.h> #include <stdio.h> +void AudioOutput::Task() {} + class DummyAudioOutputClient final : public AudioOutputClient { public: /* virtual methods from AudioOutputClient */ |