diff options
-rw-r--r-- | Makefile.am | 1 | ||||
-rw-r--r-- | src/DatabaseLock.cxx | 2 | ||||
-rw-r--r-- | src/DatabaseLock.hxx | 13 | ||||
-rw-r--r-- | src/event/Loop.cxx | 6 | ||||
-rw-r--r-- | src/event/Loop.hxx | 11 | ||||
-rw-r--r-- | src/thread/Id.hxx | 99 |
6 files changed, 117 insertions, 15 deletions
diff --git a/Makefile.am b/Makefile.am index f12eebf7d..c4dc716c7 100644 --- a/Makefile.am +++ b/Makefile.am @@ -80,6 +80,7 @@ src_mpd_SOURCES = \ $(DECODER_SRC) \ $(OUTPUT_API_SRC) \ $(MIXER_API_SRC) \ + src/thread/Id.hxx \ src/thread/Mutex.hxx \ src/thread/PosixMutex.hxx \ src/thread/CriticalSection.hxx \ diff --git a/src/DatabaseLock.cxx b/src/DatabaseLock.cxx index 398e5aebb..de67012e7 100644 --- a/src/DatabaseLock.cxx +++ b/src/DatabaseLock.cxx @@ -24,5 +24,5 @@ Mutex db_mutex; #ifndef NDEBUG -GThread *db_mutex_holder; +ThreadId db_mutex_holder; #endif diff --git a/src/DatabaseLock.hxx b/src/DatabaseLock.hxx index ba6157999..005835549 100644 --- a/src/DatabaseLock.hxx +++ b/src/DatabaseLock.hxx @@ -30,14 +30,15 @@ #include "thread/Mutex.hxx" #include "gcc.h" -#include <glib.h> #include <assert.h> extern Mutex db_mutex; #ifndef NDEBUG -extern GThread *db_mutex_holder; +#include "thread/Id.hxx" + +extern ThreadId db_mutex_holder; /** * Does the current thread hold the database lock? @@ -46,7 +47,7 @@ gcc_pure static inline bool holding_db_lock(void) { - return db_mutex_holder == g_thread_self(); + return db_mutex_holder.IsInside(); } #endif @@ -62,9 +63,9 @@ db_lock(void) db_mutex.lock(); - assert(db_mutex_holder == NULL); + assert(db_mutex_holder.IsNull()); #ifndef NDEBUG - db_mutex_holder = g_thread_self(); + db_mutex_holder = ThreadId::GetCurrent(); #endif } @@ -76,7 +77,7 @@ db_unlock(void) { assert(holding_db_lock()); #ifndef NDEBUG - db_mutex_holder = NULL; + db_mutex_holder = ThreadId::Null(); #endif db_mutex.unlock(); diff --git a/src/event/Loop.cxx b/src/event/Loop.cxx index ad20245de..5154c3562 100644 --- a/src/event/Loop.cxx +++ b/src/event/Loop.cxx @@ -23,12 +23,12 @@ void EventLoop::Run() { - assert(thread == nullptr); - thread = g_thread_self(); + assert(thread.IsNull()); + thread = ThreadId::GetCurrent(); g_main_loop_run(loop); - assert(thread == g_thread_self()); + assert(thread.IsInside()); } guint diff --git a/src/event/Loop.hxx b/src/event/Loop.hxx index 02befe79e..e26da9687 100644 --- a/src/event/Loop.hxx +++ b/src/event/Loop.hxx @@ -21,6 +21,7 @@ #define MPD_EVENT_LOOP_HXX #include "check.h" +#include "thread/Id.hxx" #include "gcc.h" #include <glib.h> @@ -34,19 +35,19 @@ class EventLoop { /** * A reference to the thread that is currently inside Run(). */ - GThread *thread; + ThreadId thread; public: EventLoop() :context(g_main_context_new()), loop(g_main_loop_new(context, false)), - thread(nullptr) {} + thread(ThreadId::Null()) {} struct Default {}; EventLoop(gcc_unused Default _dummy) :context(g_main_context_ref(g_main_context_default())), loop(g_main_loop_new(context, false)), - thread(nullptr) {} + thread(ThreadId::Null()) {} ~EventLoop() { g_main_loop_unref(loop); @@ -58,9 +59,9 @@ public: */ gcc_pure bool IsInside() const { - assert(thread != nullptr); + assert(!thread.IsNull()); - return g_thread_self() == thread; + return thread.IsInside(); } GMainContext *GetContext() { diff --git a/src/thread/Id.hxx b/src/thread/Id.hxx new file mode 100644 index 000000000..3d0dfe311 --- /dev/null +++ b/src/thread/Id.hxx @@ -0,0 +1,99 @@ +/* + * Copyright (C) 2003-2013 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_THREAD_ID_HXX +#define MPD_THREAD_ID_HXX + +#include "gcc.h" + +#ifdef WIN32 +#include <windows.h> +#else +#include <pthread.h> +#endif + +/** + * A low-level identification for a thread. Designed to work with + * existing threads, such as the main thread. Mostly useful for + * debugging code. + */ +class ThreadId { +#ifdef WIN32 + DWORD id; +#else + pthread_t id; +#endif + +public: + /** + * No initialisation. + */ + ThreadId() = default; + +#ifdef WIN32 + constexpr ThreadId(DWORD _id):id(_id) {} +#else + constexpr ThreadId(pthread_t _id):id(_id) {} +#endif + + gcc_const + static ThreadId Null() { +#ifdef WIN32 + return 0; +#else + static ThreadId null; + return null; +#endif + } + + gcc_pure + bool IsNull() const { + return *this == Null(); + } + + /** + * Return the current thread's id . + */ + gcc_pure + static const ThreadId GetCurrent() { +#ifdef WIN32 + return ::GetCurrentThreadId(); +#else + return ::pthread_self(); +#endif + } + + gcc_pure + bool operator==(const ThreadId &other) const { +#ifdef WIN32 + return id == other.id; +#else + return ::pthread_equal(id, other.id); +#endif + } + + /** + * Check if this thread is the current thread. + */ + bool IsInside() const { + return *this == GetCurrent(); + } +}; + +#endif |