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 struct AI_CriticalSectionStruct {
00014 CRITICAL_SECTION cs;
00015 };
00016
00017
00018 static DWORD WINAPI InternalThreadRoutine(void* opaque);
00019
00020
00021 bool SupportsThreadPriority() {
00022
00023
00024
00025
00026 OSVERSIONINFO info;
00027 info.dwOSVersionInfoSize = sizeof(info);
00028 if (GetVersionEx(&info) &&
00029 info.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS) {
00030 return false;
00031 } else {
00032 return true;
00033 }
00034 }
00035
00036
00037 int GetWin32Priority(int priority) {
00038 if (priority < -2) {
00039 return THREAD_PRIORITY_IDLE;
00040 } else if (priority == -2) {
00041 return THREAD_PRIORITY_LOWEST;
00042 } else if (priority == -1) {
00043 return THREAD_PRIORITY_BELOW_NORMAL;
00044 } else if (priority == 0) {
00045 return THREAD_PRIORITY_NORMAL;
00046 } else if (priority == 1) {
00047 return THREAD_PRIORITY_ABOVE_NORMAL;
00048 } else {
00049 return THREAD_PRIORITY_HIGHEST;
00050 }
00051 }
00052
00053
00054 bool AI_CreateThread(AI_ThreadRoutine routine, void* opaque, int priority) {
00055
00056 ThreadInternal* internal = new ThreadInternal;
00057 internal->routine = routine;
00058 internal->opaque = opaque;
00059
00060
00061
00062 DWORD threadid;
00063 HANDLE handle = CreateThread(
00064 0, 0, InternalThreadRoutine, internal,
00065 CREATE_SUSPENDED, &threadid);
00066 if (handle) {
00067 if (SupportsThreadPriority()) {
00068 SetThreadPriority(handle, GetWin32Priority(priority));
00069 }
00070 ResumeThread(handle);
00071 CloseHandle(handle);
00072 return true;
00073 } else {
00074 return false;
00075 }
00076 }
00077
00078
00079 DWORD WINAPI InternalThreadRoutine(void* opaque) {
00080 ThreadInternal* internal = (ThreadInternal*)opaque;
00081
00082
00083 internal->routine(internal->opaque);
00084 delete internal;
00085 return 0;
00086 }
00087
00088
00089 void AI_Sleep(unsigned milliseconds) {
00090 ::Sleep(milliseconds);
00091 }
00092
00093
00094 AI_CriticalSection AI_CreateCriticalSection() {
00095 AI_CriticalSectionStruct* cs = new AI_CriticalSectionStruct;
00096 ::InitializeCriticalSection(&cs->cs);
00097 return cs;
00098 }
00099
00100
00101 void AI_DestroyCriticalSection(AI_CriticalSection cs) {
00102 ::DeleteCriticalSection(&cs->cs);
00103 delete cs;
00104 }
00105
00106
00107 void AI_EnterCriticalSection(AI_CriticalSection cs) {
00108 ::EnterCriticalSection(&cs->cs);
00109 }
00110
00111
00112 void AI_LeaveCriticalSection(AI_CriticalSection cs) {
00113 ::LeaveCriticalSection(&cs->cs);
00114 }
00115
00116 }