Mercurial > almixer_isolated
comparison Isolated/SimpleThreadWindows.c @ 60:f7acef5a80fe
Bug and casting fixes to SimpleThreadWindows.c. Thanks to Johnson Lin for testing and reporting these issues!
Johnson Lin < arch . jslin - at - gmail . com >
author | Eric Wing <ewing . public |-at-| gmail . com> |
---|---|
date | Tue, 19 Jun 2012 00:23:35 -0700 |
parents | 7d508c8cd75a |
children |
comparison
equal
deleted
inserted
replaced
59:7d508c8cd75a | 60:f7acef5a80fe |
---|---|
3 #include "SimpleThread.h" | 3 #include "SimpleThread.h" |
4 | 4 |
5 #define WIN32_LEAN_AND_MEAN | 5 #define WIN32_LEAN_AND_MEAN |
6 #include <process.h> | 6 #include <process.h> |
7 #include <windows.h> | 7 #include <windows.h> |
8 #include <stdlib.h> | |
8 | 9 |
9 #if defined(DEBUG) | 10 #if defined(DEBUG) |
10 #include <stdio.h> | 11 #include <stdio.h> |
11 #define THRDDBG(x) printf x | 12 #define THRDDBG(x) printf x |
12 #else | 13 #else |
15 | 16 |
16 | 17 |
17 struct SimpleThread | 18 struct SimpleThread |
18 { | 19 { |
19 unsigned threadID; | 20 unsigned threadID; |
20 uintptr_t nativeThread; | 21 HANDLE nativeThread; |
21 unsigned threadStatus; | 22 unsigned threadStatus; |
22 // void* userData; | |
23 }; | 23 }; |
24 | 24 |
25 typedef struct SimpleThreadArguments | 25 typedef struct SimpleThreadArguments |
26 { | 26 { |
27 int (*userFunction)(void*); | 27 int (*userFunction)(void*); |
29 SimpleThread* simpleThread; | 29 SimpleThread* simpleThread; |
30 } SimpleThreadArguments; | 30 } SimpleThreadArguments; |
31 | 31 |
32 | 32 |
33 | 33 |
34 static unsigned Internal_RunThread(void* user_data) | 34 static unsigned __stdcall Internal_RunThread(void* user_data) |
35 { | 35 { |
36 int (*user_function)(void*); | 36 int (*user_function)(void*); |
37 void* function_user_data; | 37 void* function_user_data; |
38 int* status_val; | 38 unsigned* status_val; |
39 | 39 |
40 #if 0 | 40 #if 0 |
41 /* disable signals */ | 41 /* disable signals */ |
42 sigset_t disable_set; | 42 sigset_t disable_set; |
43 | 43 |
70 | 70 |
71 user_function = simple_thread_arguments->userFunction; | 71 user_function = simple_thread_arguments->userFunction; |
72 function_user_data = simple_thread_arguments->userData; | 72 function_user_data = simple_thread_arguments->userData; |
73 status_val = &simple_thread_arguments->simpleThread->threadStatus; | 73 status_val = &simple_thread_arguments->simpleThread->threadStatus; |
74 | 74 |
75 | 75 |
76 /* I hope this is safe to delete on a different thread than it was created for. */ | 76 /* I hope this is safe to delete on a different thread than it was created for. */ |
77 free(simple_thread_arguments); | 77 free(simple_thread_arguments); |
78 | 78 |
79 *status_val = user_function(function_user_data); | 79 *status_val = user_function(function_user_data); |
80 | 80 |
81 _endthreadex( 0 ); | 81 _endthreadex( 0 ); |
82 | 82 |
83 return NULL; | 83 return 0; |
84 } | 84 } |
85 | 85 |
86 | 86 |
87 SimpleThread* SimpleThread_CreateThread(int (*user_function)(void*), void* user_data) | 87 SimpleThread* SimpleThread_CreateThread(int (*user_function)(void*), void* user_data) |
88 { | 88 { |
89 int ret_val; | |
90 SimpleThread* new_thread; | 89 SimpleThread* new_thread; |
91 SimpleThreadArguments* simple_thread_arguments; | 90 SimpleThreadArguments* simple_thread_arguments; |
92 | 91 |
93 new_thread = (SimpleThread*)malloc(sizeof(SimpleThread)); | 92 new_thread = (SimpleThread*)malloc(sizeof(SimpleThread)); |
94 if(NULL == new_thread) | 93 if(NULL == new_thread) |
95 { | 94 { |
96 THRDDBG(("Out of memory.\n")); | 95 THRDDBG(("Out of memory.\n")); |
97 return NULL; | 96 return NULL; |
98 } | 97 } |
99 | 98 |
100 simple_thread_arguments = (SimpleThreadArguments*)malloc(sizeof(SimpleThreadArguments)); | 99 simple_thread_arguments = (SimpleThreadArguments*)malloc(sizeof(SimpleThreadArguments)); |
101 if(NULL == simple_thread_arguments) | 100 if(NULL == simple_thread_arguments) |
102 { | 101 { |
103 THRDDBG(("Out of memory.\n")); | 102 THRDDBG(("Out of memory.\n")); |
104 free(new_thread); | 103 free(new_thread); |
105 return NULL; | 104 return NULL; |
106 } | 105 } |
107 simple_thread_arguments->userFunction = user_function; | 106 simple_thread_arguments->userFunction = user_function; |
108 simple_thread_arguments->userData = user_data; | 107 simple_thread_arguments->userData = user_data; |
109 simple_thread_arguments->simpleThread = new_thread; | 108 simple_thread_arguments->simpleThread = new_thread; |
110 | 109 |
111 | 110 |
112 new_thread->nativeThread = _beginthreadex(NULL, 0, &Internal_RunThread, simple_thread_arguments, 0, &new_thread->threadID); | 111 new_thread->nativeThread = (HANDLE)_beginthreadex(NULL, 0, &Internal_RunThread, simple_thread_arguments, 0, &new_thread->threadID); |
113 if(0 == ret_val) | 112 if(0 == new_thread->nativeThread) |
114 { | 113 { |
115 THRDDBG(("_beginthreadex failed with: %d\n", errno)); | 114 THRDDBG(("_beginthreadex failed with: %d\n", errno)); |
116 free(simple_thread_arguments); | 115 free(simple_thread_arguments); |
117 free(new_thread); | 116 free(new_thread); |
118 return NULL; | 117 return NULL; |
119 } | 118 } |
120 | 119 |
121 return new_thread; | 120 return new_thread; |
122 } | 121 } |
123 | 122 |
124 | 123 |
125 | 124 |
128 return (size_t)GetCurrentThreadId(); | 127 return (size_t)GetCurrentThreadId(); |
129 } | 128 } |
130 | 129 |
131 void SimpleThread_WaitThread(SimpleThread* simple_thread, int* thread_status) | 130 void SimpleThread_WaitThread(SimpleThread* simple_thread, int* thread_status) |
132 { | 131 { |
133 int ret_val; | |
134 if(NULL == simple_thread) | 132 if(NULL == simple_thread) |
135 { | 133 { |
136 THRDDBG(("SimpleThread_WaitThread was passed NULL\n")); | 134 THRDDBG(("SimpleThread_WaitThread was passed NULL\n")); |
137 return; | 135 return; |
138 } | 136 } |
139 | 137 |
140 WaitForSingleObject(simple_thread->nativeThread, INFINITE); | 138 WaitForSingleObject(simple_thread->nativeThread, INFINITE); |
141 CloseHandle(simple_thread->nativeThread); | 139 CloseHandle(simple_thread->nativeThread); |
149 | 147 |
150 size_t SimpleThread_GetThreadID(SimpleThread* simple_thread) | 148 size_t SimpleThread_GetThreadID(SimpleThread* simple_thread) |
151 { | 149 { |
152 if(NULL == simple_thread) | 150 if(NULL == simple_thread) |
153 { | 151 { |
154 THRDDBG(("SimpleThread_GetThreadID was passed NULL\n")); | 152 THRDDBG(("SimpleThread_GetThreadID was passed NULL\n")); |
155 return 0; | 153 return 0; |
156 } | 154 } |
157 return (size_t)simple_thread->threadID; | 155 return (size_t)simple_thread->threadID; |
158 } | 156 } |
159 | 157 |
160 /* TODO: Figure out portable/normalized range for levels */ | 158 /* TODO: Figure out portable/normalized range for levels */ |
161 int SimpleThread_GetThreadPriority(SimpleThread* simple_thread) | 159 int SimpleThread_GetThreadPriority(SimpleThread* simple_thread) |
162 { | 160 { |
163 struct sched_param schedule_param; | 161 int ret_val = 0; |
164 int sched_policy; | 162 |
165 int ret_val; | |
166 | |
167 if(NULL == simple_thread) | 163 if(NULL == simple_thread) |
168 { | 164 { |
169 THRDDBG(("SimpleThread_GetThreadPriority was passed NULL\n")); | 165 THRDDBG(("SimpleThread_GetThreadPriority was passed NULL\n")); |
170 return THREAD_PRIORITY_ERROR_RETURN; /* Windows ranges seem to go from -15 to +15 */ | 166 return THREAD_PRIORITY_ERROR_RETURN; /* Windows ranges seem to go from -15 to +15 */ |
171 } | 167 } |
172 ret_val = GetThreadPriority(simple_thread->nativeThread); | 168 ret_val = GetThreadPriority(simple_thread->nativeThread); |
173 if(THREAD_PRIORITY_ERROR_RETURN == ret_val) | 169 if(THREAD_PRIORITY_ERROR_RETURN == ret_val) |
174 { | 170 { |
179 } | 175 } |
180 | 176 |
181 /* TODO: Figure out portable/normalized range for levels */ | 177 /* TODO: Figure out portable/normalized range for levels */ |
182 void SimpleThread_SetThreadPriority(SimpleThread* simple_thread, int priority_level) | 178 void SimpleThread_SetThreadPriority(SimpleThread* simple_thread, int priority_level) |
183 { | 179 { |
184 struct sched_param schedule_param; | |
185 BOOL ret_val; | 180 BOOL ret_val; |
186 | 181 |
187 if(NULL == simple_thread) | 182 if(NULL == simple_thread) |
188 { | 183 { |
189 THRDDBG(("SimpleThread_SetThreadPriority was passed NULL\n")); | 184 THRDDBG(("SimpleThread_SetThreadPriority was passed NULL\n")); |
190 return; | 185 return; |
191 } | 186 } |
192 | 187 |
193 ret_val = SetThreadPriority(simple_thread->nativeThread, priority_level); | 188 ret_val = SetThreadPriority(simple_thread->nativeThread, priority_level); |
194 if(0 == ret_val) | 189 if(0 == ret_val) |