00001 #include <windows.h>
00002 #include <process.h>
00003 #include "threads.h"
00004
00005
00006 namespace audiere {
00007
00008 struct ThreadInternal {
00009 AI_ThreadRoutine routine;
00010 void* opaque;
00011 };
00012
00013 static unsigned WINAPI InternalThreadRoutine(void* opaque);
00014
00015
00016 bool SupportsThreadPriority() {
00017
00018
00019
00020
00021 OSVERSIONINFO info;
00022 info.dwOSVersionInfoSize = sizeof(info);
00023 if (GetVersionEx(&info) &&
00024 info.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS) {
00025 return false;
00026 } else {
00027 return true;
00028 }
00029 }
00030
00031
00032 int GetWin32Priority(int priority) {
00033 if (priority < -2) {
00034 return THREAD_PRIORITY_IDLE;
00035 } else if (priority == -2) {
00036 return THREAD_PRIORITY_LOWEST;
00037 } else if (priority == -1) {
00038 return THREAD_PRIORITY_BELOW_NORMAL;
00039 } else if (priority == 0) {
00040 return THREAD_PRIORITY_NORMAL;
00041 } else if (priority == 1) {
00042 return THREAD_PRIORITY_ABOVE_NORMAL;
00043 } else {
00044 return THREAD_PRIORITY_HIGHEST;
00045 }
00046 }
00047
00048
00049 bool AI_CreateThread(AI_ThreadRoutine routine, void* opaque, int priority) {
00050
00051 ThreadInternal* internal = new ThreadInternal;
00052 internal->routine = routine;
00053 internal->opaque = opaque;
00054
00055
00056 unsigned threadid;
00057 HANDLE handle = (HANDLE)_beginthreadex(
00058 0, 0, InternalThreadRoutine, internal, CREATE_SUSPENDED, &threadid);
00059 if (handle) {
00060 if (SupportsThreadPriority()) {
00061 SetThreadPriority(handle, GetWin32Priority(priority));
00062 }
00063 ResumeThread(handle);
00064 CloseHandle(handle);
00065 return true;
00066 } else {
00067 return false;
00068 }
00069 }
00070
00071
00072 unsigned WINAPI InternalThreadRoutine(void* opaque) {
00073 ThreadInternal* internal = static_cast<ThreadInternal*>(opaque);
00074
00075
00076 internal->routine(internal->opaque);
00077 delete internal;
00078 return 0;
00079 }
00080
00081
00082 void AI_Sleep(unsigned milliseconds) {
00083 ::Sleep(milliseconds);
00084 }
00085
00086
00087 struct Mutex::Impl {
00088 CRITICAL_SECTION cs;
00089 };
00090
00091 Mutex::Mutex() {
00092 m_impl = new Impl;
00093 InitializeCriticalSection(&m_impl->cs);
00094 }
00095
00096 Mutex::~Mutex() {
00097 DeleteCriticalSection(&m_impl->cs);
00098 delete m_impl;
00099 }
00100
00101 void Mutex::lock() {
00102 EnterCriticalSection(&m_impl->cs);
00103 }
00104
00105 void Mutex::unlock() {
00106 LeaveCriticalSection(&m_impl->cs);
00107 }
00108
00109
00110
00111
00112
00113
00114 struct CondVar::Impl {
00115 HANDLE event;
00116 };
00117
00118 CondVar::CondVar() {
00119 ADR_GUARD("CondVar::CondVar");
00120 m_impl = new Impl;
00121 m_impl->event = CreateEvent(0, FALSE, FALSE, 0);
00122 if (!m_impl->event) {
00123 ADR_LOG("CreateEvent() failed");
00124 abort();
00125 }
00126 }
00127
00128 CondVar::~CondVar() {
00129 CloseHandle(m_impl->event);
00130 delete m_impl;
00131 }
00132
00133 void CondVar::wait(Mutex& mutex, float seconds) {
00134 mutex.unlock();
00135 WaitForSingleObject(m_impl->event, int(seconds * 1000));
00136 mutex.lock();
00137 }
00138
00139 void CondVar::notify() {
00140 SetEvent(m_impl->event);
00141 }
00142
00143 }