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)