diff foosdk/sdk/foobar2000/helpers/ThreadUtils.h @ 1:20d02a178406 default tip

*: check in everything else yay
author Paper <paper@tflc.us>
date Mon, 05 Jan 2026 02:15:46 -0500
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/foosdk/sdk/foobar2000/helpers/ThreadUtils.h	Mon Jan 05 02:15:46 2026 -0500
@@ -0,0 +1,66 @@
+#pragma once
+#include "fb2k_threads.h"
+
+#ifdef _WIN32
+#include <functional>
+
+namespace ThreadUtils {
+	bool WaitAbortable(HANDLE ev, abort_callback & abort, DWORD timeout = INFINITE);
+
+	void ProcessPendingMessages();
+	void ProcessPendingMessagesWithDialog(HWND hDialog);
+	
+	void WaitAbortable_MsgLoop(HANDLE ev, abort_callback & abort);
+	
+	
+	// Throws an exception if aborted, returns index of triggered event otherwise.
+	t_size MultiWaitAbortable_MsgLoop2(const HANDLE* ev, t_size evCount, abort_callback& abort);
+
+	// Do not use, broken version of MultiWaitAbortable_MsgLoop2 retained for compatibility (returns 1 based index)
+	t_size MultiWaitAbortable_MsgLoop(const HANDLE* ev, t_size evCount, abort_callback& abort);
+
+	void SleepAbortable_MsgLoop(abort_callback & abort, DWORD timeoutMS);
+	bool WaitAbortable_MsgLoop(HANDLE ev, abort_callback & abort, DWORD timeoutMS);
+
+	DWORD MultiWait_MsgLoop(const HANDLE* ev, DWORD evCount, DWORD timeoutMS);
+	DWORD MultiWait_MsgLoop(const HANDLE* ev, DWORD evCount);
+
+	// Drop-in replacement for pfc::event::g_wait_for()
+	bool pfcWaitMsgLoop(HANDLE ev, double timeout);
+
+	template<typename TWhat>
+	class CObjectQueue {
+	public:
+		CObjectQueue() { m_event.create(true,false); }
+
+		template<typename TSource> void Add(const TSource & source) {
+			insync(m_sync);
+			m_content.add_item(source);
+			if (m_content.get_count() == 1) m_event.set_state(true);
+		}
+		template<typename TDestination> void Get(TDestination & out, abort_callback & abort) {
+			WaitAbortable(m_event.get(), abort);
+			_Get(out);
+		}
+
+		template<typename TDestination> void Get_MsgLoop(TDestination & out, abort_callback & abort) {
+			WaitAbortable_MsgLoop(m_event.get(), abort);
+			_Get(out);
+		}
+
+	private:
+		template<typename TDestination> void _Get(TDestination & out) {
+			insync(m_sync);
+			auto iter = m_content.cfirst();
+			FB2K_DYNAMIC_ASSERT( iter.is_valid() );
+			out = *iter;
+			m_content.remove(iter);
+			if (m_content.get_count() == 0) m_event.set_state(false);
+		}
+		win32_event m_event;
+		critical_section m_sync;
+		pfc::chain_list_v2_t<TWhat> m_content;
+	};
+
+}
+#endif // _WIN32