summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/db/update/Service.cxx10
-rw-r--r--src/db/update/Service.hxx1
-rw-r--r--src/decoder/DecoderControl.cxx3
-rw-r--r--src/decoder/DecoderControl.hxx3
-rw-r--r--src/decoder/DecoderThread.cxx38
-rw-r--r--src/event/Thread.cxx14
-rw-r--r--src/event/Thread.hxx6
-rw-r--r--src/input/ThreadInputStream.cxx11
-rw-r--r--src/input/ThreadInputStream.hxx2
-rw-r--r--src/neighbor/plugins/SmbclientNeighborPlugin.cxx17
-rw-r--r--src/output/Init.cxx3
-rw-r--r--src/output/Internal.hxx1
-rw-r--r--src/output/OutputThread.cxx11
-rw-r--r--src/player/Control.cxx1
-rw-r--r--src/player/Control.hxx3
-rw-r--r--src/player/Thread.cxx74
-rw-r--r--src/thread/Thread.cxx7
-rw-r--r--src/thread/Thread.hxx11
-rw-r--r--test/run_output.cxx2
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 */