diff options
Diffstat (limited to 'src/fiber_win32.cpp')
-rw-r--r-- | src/fiber_win32.cpp | 206 |
1 files changed, 0 insertions, 206 deletions
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(); -} |