thread/Id: new class replacing GThread pointers
Remove a GLib dependencies from class EventLoop and DatabaseLock.
This commit is contained in:
		| @@ -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 \ | ||||
|   | ||||
| @@ -24,5 +24,5 @@ | ||||
| Mutex db_mutex; | ||||
|  | ||||
| #ifndef NDEBUG | ||||
| GThread *db_mutex_holder; | ||||
| ThreadId db_mutex_holder; | ||||
| #endif | ||||
|   | ||||
| @@ -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(); | ||||
|   | ||||
| @@ -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 | ||||
|   | ||||
| @@ -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() { | ||||
|   | ||||
							
								
								
									
										99
									
								
								src/thread/Id.hxx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										99
									
								
								src/thread/Id.hxx
									
									
									
									
									
										Normal file
									
								
							| @@ -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 | ||||
		Reference in New Issue
	
	Block a user
	 Max Kellermann
					Max Kellermann