diff foosdk/sdk/foobar2000/helpers/fb2k_threads.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/fb2k_threads.h	Mon Jan 05 02:15:46 2026 -0500
@@ -0,0 +1,92 @@
+#pragma once
+
+inline static t_size GetOptimalWorkerThreadCount() throw() {
+	return pfc::getOptimalWorkerThreadCount();
+}
+
+//! IMPORTANT: all classes derived from CVerySimpleThread must call WaitTillThreadDone() in their destructor, to avoid object destruction during a virtual function call!
+class CVerySimpleThread : private pfc::thread {
+public:
+#ifdef _WIN32
+	void StartThread(int winPriority) {
+		StartThread(pfc::thread::argWinPriority(winPriority));
+	}
+#endif
+	void StartThread( pfc::thread::arg_t const & arg = pfc::thread::argCurrentThread() ) {
+        pfc::thread::start( arg );
+	}
+
+	bool IsThreadActive() const {
+		return this->pfc::thread::isActive();
+	}
+	void WaitTillThreadDone() {
+		this->pfc::thread::waitTillDone();
+	}
+protected:
+	CVerySimpleThread() {}
+	virtual void ThreadProc() = 0;
+private:
+
+	void threadProc() {
+		this->ThreadProc();
+	}
+
+	PFC_CLASS_NOT_COPYABLE_EX(CVerySimpleThread)
+};
+
+//! IMPORTANT: all classes derived from CSimpleThread must call AbortThread()/WaitTillThreadDone() in their destructors, to avoid object destruction during a virtual function call!
+class CSimpleThread : private completion_notify_receiver, private pfc::thread {
+public:
+#ifdef _WIN32
+	void StartThread(int winPriority) {
+		StartThread(pfc::thread::argWinPriority(winPriority));
+	}
+#endif
+	void StartThread(pfc::thread::arg_t const & arg = pfc::thread::argCurrentThread() ) {
+		AbortThread();
+		m_abort.reset();
+		m_ownNotify = create_task(0);
+        this->pfc::thread::start( arg );
+	}
+	void AbortThread() {
+		m_abort.abort();
+		CloseThread();
+	}
+	bool IsThreadActive() const {
+		return this->pfc::thread::isActive();
+	}
+	void WaitTillThreadDone() {
+		CloseThread();
+	}
+protected:
+	CSimpleThread() {}
+	~CSimpleThread() {AbortThread();}
+
+	virtual unsigned ThreadProc(abort_callback & p_abort) = 0;
+	//! Called when the thread has completed normally, with p_code equal to ThreadProc retval. Not called when AbortThread() or WaitTillThreadDone() was used to abort the thread / wait for the thread to finish.
+	virtual void ThreadDone(unsigned p_code) {};
+private:
+	void CloseThread() {
+		this->pfc::thread::waitTillDone();
+		orphan_all_tasks();
+	}
+
+	void on_task_completion(unsigned p_id,unsigned p_status) {
+		if (IsThreadActive()) {
+			CloseThread();
+			ThreadDone(p_status);
+		}
+	}
+	void threadProc() {
+		unsigned code = ~0;
+		try {
+			code = ThreadProc(m_abort);
+		} catch(...) {}
+		if (!m_abort.is_aborting()) m_ownNotify->on_completion_async(code);
+	}
+	abort_callback_impl m_abort;
+	completion_notify_ptr m_ownNotify;
+
+	PFC_CLASS_NOT_COPYABLE_EX(CSimpleThread);
+};
+