diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/fiber.hpp | 53 | ||||
-rw-r--r-- | src/fiber_thread.cpp | 151 | ||||
-rw-r--r-- | src/fiber_win32.cpp | 206 | ||||
-rw-r--r-- | src/thread_none.cpp | 16 |
4 files changed, 0 insertions, 426 deletions
diff --git a/src/fiber.hpp b/src/fiber.hpp deleted file mode 100644 index e67dc4e9e..000000000 --- a/src/fiber.hpp +++ /dev/null @@ -1,53 +0,0 @@ -/* $Id$ */ - -/** @file fiber.hpp Base for all fiber related classes. */ - -#ifndef FIBER_HPP -#define FIBER_HPP - -typedef void (CDECL *FiberFunc)(void *); - -class Fiber { -public: - /** - * Switch to this fiber. - */ - virtual void SwitchToFiber() = 0; - - /** - * Exit a fiber. - */ - virtual void Exit() = 0; - - /** - * Check if a fiber is running. - */ - virtual bool IsRunning() = 0; - - /** - * Get the 'param' data of the Fiber. - */ - virtual void *GetFiberData() = 0; - - /** - * Virtual Destructor to mute warnings. - */ - virtual ~Fiber() {}; - - /** - * Create a new fiber, calling proc(param) when running. - */ - static Fiber *New(FiberFunc proc, void *param); - - /** - * Attach a current thread to a new fiber. - */ - static Fiber *AttachCurrent(void *param); - - /** - * Get the 'param' data of the current active Fiber. - */ - static void *GetCurrentFiberData(); -}; - -#endif /* FIBER_HPP */ diff --git a/src/fiber_thread.cpp b/src/fiber_thread.cpp deleted file mode 100644 index 5155b5519..000000000 --- a/src/fiber_thread.cpp +++ /dev/null @@ -1,151 +0,0 @@ -/* $Id$ */ - -/** @file fiber_thread.cpp ThreadObject implementation of Fiber. */ - -#include "stdafx.h" -#include "fiber.hpp" -#include "thread.h" -#include <stdlib.h> - -class Fiber_Thread : public Fiber { -private: - ThreadObject *m_thread; - FiberFunc m_proc; - void *m_param; - bool m_attached; - ThreadSemaphore *m_sem; - bool m_kill; - - static Fiber_Thread *s_current; - static Fiber_Thread *s_main; - -public: - /** - * Create a ThreadObject fiber and start it, calling proc(param). - */ - Fiber_Thread(FiberFunc proc, void *param) : - m_thread(NULL), - m_proc(proc), - m_param(param), - m_attached(false), - m_kill(false) - { - this->m_sem = ThreadSemaphore::New(); - /* Create a thread and start stFiberProc */ - this->m_thread = ThreadObject::New(&stFiberProc, this); - } - - /** - * Create a ThreadObject fiber and attach current thread to it. - */ - Fiber_Thread(void *param) : - m_thread(NULL), - m_proc(NULL), - m_param(param), - m_attached(true), - m_kill(false) - { - this->m_sem = ThreadSemaphore::New(); - /* Attach the current thread to this Fiber */ - this->m_thread = ThreadObject::AttachCurrent(); - /* We are the current thread */ - if (s_current == NULL) s_current = this; - if (s_main == NULL) s_main = this; - } - - ~Fiber_Thread() - { - /* Remove the thread if needed */ - if (this->m_thread != NULL) { - assert(this->m_attached || !this->m_thread->IsRunning()); - delete this->m_thread; - } - /* Remove the semaphore */ - delete this->m_sem; - } - - /* virtual */ void SwitchToFiber() - { - /* You can't switch to yourself */ - assert(s_current != this); - Fiber_Thread *cur = s_current; - - /* Continue the execution of 'this' Fiber */ - this->m_sem->Set(); - /* Hold the execution of the current Fiber */ - cur->m_sem->Wait(); - if (this->m_kill) { - /* If the thread we switched too was killed, join it so it can finish quiting */ - this->m_thread->Join(); - } - /* If we continue, we are the current thread */ - s_current = cur; - } - - /* virtual */ void Exit() - { - /* Kill off our thread */ - this->m_kill = true; - this->m_thread->Exit(); - } - - /* virtual */ bool IsRunning() - { - if (this->m_thread == NULL) return false; - return this->m_thread->IsRunning(); - } - - /* virtual */ void *GetFiberData() - { - return this->m_param; - } - - static Fiber_Thread *GetCurrentFiber() - { - return s_current; - } - -private: - /** - * First function which is called within the fiber. - */ - static void stFiberProc(void *fiber) - { - Fiber_Thread *cur = (Fiber_Thread *)fiber; - /* Now suspend the thread until we get SwitchToFiber() for the first time */ - cur->m_sem->Wait(); - /* If we continue, we are the current thread */ - s_current = cur; - - try { - cur->m_proc(cur->m_param); - } catch (...) { - /* Unlock the main thread */ - s_main->m_sem->Set(); - throw; - } - } -}; - -/* Initialize the static member of Fiber_Thread */ -/* static */ Fiber_Thread *Fiber_Thread::s_current = NULL; -/* static */ Fiber_Thread *Fiber_Thread::s_main = NULL; - -#ifndef WIN32 - -/* static */ Fiber *Fiber::New(FiberFunc proc, void *param) -{ - return new Fiber_Thread(proc, param); -} - -/* static */ Fiber *Fiber::AttachCurrent(void *param) -{ - return new Fiber_Thread(param); -} - -/* static */ void *Fiber::GetCurrentFiberData() -{ - return Fiber_Thread::GetCurrentFiber()->GetFiberData(); -} - -#endif /* WIN32 */ diff --git a/src/fiber_win32.cpp b/src/fiber_win32.cpp deleted file mode 100644 index 61718188c..000000000 --- a/src/fiber_win32.cpp +++ /dev/null @@ -1,206 +0,0 @@ -/* $Id$ */ - -/** @file fiber_win32.cpp Win32 implementation of Fiber. */ - -#include "stdafx.h" -#include "fiber.hpp" -#include <stdlib.h> -#include <windows.h> -#include <process.h> - -class Fiber_Win32 : public Fiber { -private: - LPVOID m_fiber; - FiberFunc m_proc; - void *m_param; - bool m_attached; - - static Fiber_Win32 *s_main; - -public: - /** - * Create a win32 fiber and start it, calling proc(param). - */ - Fiber_Win32(FiberFunc proc, void *param) : - m_fiber(NULL), - m_proc(proc), - m_param(param), - m_attached(false) - { - CreateFiber(); - } - - /** - * Create a win32 fiber and attach current thread to it. - */ - Fiber_Win32(void *param) : - m_fiber(NULL), - m_proc(NULL), - m_param(param), - m_attached(true) - { - ConvertThreadToFiber(); - if (s_main == NULL) s_main = this; - } - - /* virtual */ ~Fiber_Win32() - { - if (this->m_fiber != NULL) { - if (this->m_attached) { - this->ConvertFiberToThread(); - } else { - this->DeleteFiber(); - } - } - } - - /* virtual */ void SwitchToFiber() - { - typedef VOID (WINAPI *FnSwitchToFiber)(LPVOID fiber); - - static FnSwitchToFiber fnSwitchToFiber = (FnSwitchToFiber)stGetProcAddr("SwitchToFiber"); - assert(fnSwitchToFiber != NULL); - - fnSwitchToFiber(this->m_fiber); - } - - /* virtual */ void Exit() - { - /* Simply switch back to the main fiber, we kill the fiber sooner or later */ - s_main->SwitchToFiber(); - } - - /* virtual */ bool IsRunning() - { - return this->m_fiber != NULL; - } - - /* virtual */ void *GetFiberData() - { - return this->m_param; - } - - /** - * Win95 doesn't have Fiber support. So check if we have Fiber support, - * and else fall back on Fiber_Thread. - */ - static bool IsSupported() - { - static bool first_run = true; - static bool is_supported = false; - - if (first_run) { - first_run = false; - static const char *names[] = { - "ConvertThreadToFiber", - "CreateFiber", - "DeleteFiber", - "ConvertFiberToThread", - "SwitchToFiber"}; - for (size_t i = 0; i < lengthof(names); i++) { - if (stGetProcAddr(names[i]) == NULL) return false; - } - is_supported = true; - } - return is_supported; - } - -private: - /** - * Get a function from kernel32.dll. - * @param name Function to get. - * @return Proc to the function, or NULL when not found. - */ - static FARPROC stGetProcAddr(const char *name) - { - static HMODULE hKernel = LoadLibraryA("kernel32.dll"); - return GetProcAddress(hKernel, name); - } - - /** - * First function which is called within the fiber. - */ - static VOID CALLBACK stFiberProc(LPVOID fiber) - { - Fiber_Win32 *cur = (Fiber_Win32 *)fiber; - cur->m_proc(cur->m_param); - } - - /** - * Delete a fiber. - */ - void DeleteFiber() - { - typedef VOID (WINAPI *FnDeleteFiber)(LPVOID lpFiber); - - static FnDeleteFiber fnDeleteFiber = (FnDeleteFiber)stGetProcAddr("DeleteFiber"); - assert(fnDeleteFiber != NULL); - - fnDeleteFiber(this->m_fiber); - this->m_fiber = NULL; - } - - /** - * Convert a current thread to a fiber. - */ - void ConvertThreadToFiber() - { - typedef LPVOID (WINAPI *FnConvertThreadToFiber)(LPVOID lpParameter); - - static FnConvertThreadToFiber fnConvertThreadToFiber = (FnConvertThreadToFiber)stGetProcAddr("ConvertThreadToFiber"); - assert(fnConvertThreadToFiber != NULL); - - this->m_fiber = fnConvertThreadToFiber(this); - } - - /** - * Create a new fiber. - */ - void CreateFiber() - { - typedef LPVOID (WINAPI *FnCreateFiber)(SIZE_T dwStackSize, LPFIBER_START_ROUTINE lpStartAddress, LPVOID lpParameter); - - static FnCreateFiber fnCreateFiber = (FnCreateFiber)stGetProcAddr("CreateFiber"); - assert(fnCreateFiber != NULL); - - this->m_fiber = fnCreateFiber(0, &stFiberProc, this); - } - - /** - * Convert a fiber back to a thread. - */ - void ConvertFiberToThread() - { - typedef BOOL (WINAPI *FnConvertFiberToThread)(); - - static FnConvertFiberToThread fnConvertFiberToThread = (FnConvertFiberToThread)stGetProcAddr("ConvertFiberToThread"); - assert(fnConvertFiberToThread != NULL); - - fnConvertFiberToThread(); - this->m_fiber = NULL; - } -}; - -/* Initialize the static member of Fiber_Win32 */ -/* static */ Fiber_Win32 *Fiber_Win32::s_main = NULL; - -/* Include Fiber_Thread, as Win95 needs it */ -#include "fiber_thread.cpp" - -/* static */ Fiber *Fiber::New(FiberFunc proc, void *param) -{ - if (Fiber_Win32::IsSupported()) return new Fiber_Win32(proc, param); - return new Fiber_Thread(proc, param); -} - -/* static */ Fiber *Fiber::AttachCurrent(void *param) -{ - if (Fiber_Win32::IsSupported()) return new Fiber_Win32(param); - return new Fiber_Thread(param); -} - -/* static */ void *Fiber::GetCurrentFiberData() -{ - if (Fiber_Win32::IsSupported()) return ((Fiber *)::GetFiberData())->GetFiberData(); - return Fiber_Thread::GetCurrentFiber()->GetFiberData(); -} diff --git a/src/thread_none.cpp b/src/thread_none.cpp index 6209e89a7..a5599dff1 100644 --- a/src/thread_none.cpp +++ b/src/thread_none.cpp @@ -4,7 +4,6 @@ #include "stdafx.h" #include "thread.h" -#include "fiber.hpp" /* static */ ThreadObject *ThreadObject::New(OTTDThreadFunc proc, void *param) { @@ -25,18 +24,3 @@ { return NULL; } - -/* static */ Fiber *Fiber::New(FiberFunc proc, void *param) -{ - return NULL; -} - -/* static */ Fiber *Fiber::AttachCurrent(void *param) -{ - return NULL; -} - -/* static */ void *Fiber::GetCurrentFiberData() -{ - return NULL; -} |