summaryrefslogtreecommitdiff
path: root/src/lib/eina/eina_thread.c
diff options
context:
space:
mode:
authorAdrien Nader <adrien@notk.org>2015-02-11 12:15:43 +0100
committerCedric BAIL <cedric@osg.samsung.com>2015-02-11 16:38:10 +0100
commit2cb0c1cadc46e1d89fea4e27399b36ce9f1526ff (patch)
tree1a0f4235fb31992073ad2f42369e1b2daea3cd69 /src/lib/eina/eina_thread.c
parentc0683bc2dd361612a8e285f4966e715aed690b85 (diff)
eina: remove Windows specific thread implementation and rely on posix compliant library instead.
Diffstat (limited to '')
-rw-r--r--src/lib/eina/eina_thread.c231
1 files changed, 0 insertions, 231 deletions
diff --git a/src/lib/eina/eina_thread.c b/src/lib/eina/eina_thread.c
index cd7d48e510..2924fc7360 100644
--- a/src/lib/eina/eina_thread.c
+++ b/src/lib/eina/eina_thread.c
@@ -25,238 +25,10 @@
25#include "eina_config.h" 25#include "eina_config.h"
26#include "eina_thread.h" 26#include "eina_thread.h"
27#include "eina_sched.h" 27#include "eina_sched.h"
28#ifdef _WIN32
29# include "eina_list.h"
30# include "eina_lock.h"
31#endif
32 28
33/* undefs EINA_ARG_NONULL() so NULL checks are not compiled out! */ 29/* undefs EINA_ARG_NONULL() so NULL checks are not compiled out! */
34#include "eina_safety_checks.h" 30#include "eina_safety_checks.h"
35 31
36#ifdef _WIN32
37# define WIN32_LEAN_AND_MEAN
38# include <windows.h>
39# undef WIN32_LEAN_AND_MEAN
40
41#include <process.h>
42
43typedef struct _Eina_TLS_Cbs_Win32 Eina_TLS_Cbs_Win32;
44struct _Eina_TLS_Cbs_Win32
45{
46 Eina_TLS key;
47 Eina_TLS_Delete_Cb cb;
48};
49typedef struct _Eina_Thread_Win32 Eina_Thread_Win32;
50struct _Eina_Thread_Win32
51{
52 HANDLE thread;
53 void *(*func)(void *data);
54 void *data;
55 void *ret;
56 Eina_List *tls_keys;
57
58 Eina_Thread index;
59};
60
61/* FIXME: For the moment Eina_Thread is considered not
62 thread safe, wondering if it's worth it */
63static unsigned long int _current_index = 1; /* start from one as the main loop == 0 */
64static Eina_List *_thread_pool = NULL;
65static Eina_List *_thread_running = NULL;
66static Eina_List *_tls_keys_cbs = NULL;
67
68static inline Eina_TLS_Cbs_Win32 *
69_eina_thread_tls_cb_find(Eina_TLS key)
70{
71 Eina_TLS_Cbs_Win32 *cb;
72 Eina_List *l;
73
74 EINA_LIST_FOREACH(_tls_keys_cbs, l, cb)
75 if (cb->key == key)
76 return cb;
77
78 return NULL;
79}
80
81static inline void
82_eina_thread_tls_keys_clean(Eina_Thread_Win32 *tw)
83{
84 void *data;
85 Eina_TLS_Cbs_Win32 *cb;
86
87 EINA_LIST_FREE(tw->tls_keys, data)
88 {
89 Eina_TLS key = (Eina_TLS)(uintptr_t)data;
90 cb = _eina_thread_tls_cb_find(key);
91 if (cb)
92 cb->cb(eina_tls_get(key));
93 }
94 tw->tls_keys = NULL;
95}
96
97EAPI Eina_Bool
98_eina_thread_tls_cb_register(Eina_TLS key, Eina_TLS_Delete_Cb cb)
99{
100 Eina_TLS_Cbs_Win32 *tls_cb;
101
102 if (!cb) return EINA_FALSE;
103
104 tls_cb = malloc(sizeof(Eina_TLS_Cbs_Win32));
105 if (!tls_cb) return EINA_FALSE;
106
107 tls_cb->key = key;
108 tls_cb->cb = cb;
109 _tls_keys_cbs = eina_list_append(_tls_keys_cbs, tls_cb);
110
111 return EINA_TRUE;
112}
113
114EAPI Eina_Bool
115_eina_thread_tls_cb_unregister(Eina_TLS key)
116{
117 Eina_TLS_Cbs_Win32 *cb = _eina_thread_tls_cb_find(key);
118 if (!cb) return EINA_FALSE;
119
120 _tls_keys_cbs = eina_list_remove(_tls_keys_cbs, cb);
121 free(cb);
122
123 return EINA_TRUE;
124}
125
126EAPI Eina_Bool
127_eina_thread_tls_key_add(Eina_TLS key)
128{
129 HANDLE t;
130 Eina_Thread_Win32 *tw;
131 Eina_List *l;
132
133 t = GetCurrentThread();
134 EINA_LIST_FOREACH(_thread_running, l, tw)
135 if (tw->thread == t)
136 {
137 void *data = (void *)(uintptr_t)key;
138 if (!eina_list_data_find(tw->tls_keys, data))
139 tw->tls_keys = eina_list_append(tw->tls_keys, data);
140 return EINA_TRUE;
141 }
142
143 return EINA_FALSE;
144}
145
146static Eina_Thread_Win32 *
147_eina_thread_win32_find(Eina_Thread index)
148{
149 Eina_Thread_Win32 *tw;
150 Eina_List *l;
151
152 EINA_LIST_FOREACH(_thread_running, l, tw)
153 if (tw->index == index)
154 return tw;
155 return NULL;
156}
157
158static inline Eina_Thread
159_eina_thread_self(void)
160{
161 HANDLE t;
162 Eina_Thread_Win32 *tw;
163 Eina_List *l;
164
165 t = GetCurrentThread();
166 EINA_LIST_FOREACH(_thread_running, l, tw)
167 if (tw->thread == t)
168 return tw->index;
169
170 /* We assume main loop == 0 on Windows */
171 return 0;
172}
173
174static inline Eina_Bool
175_eina_thread_equal(Eina_Thread t1, Eina_Thread t2)
176{
177 if (t1 == t2) return EINA_TRUE;
178 return EINA_FALSE;
179}
180
181static unsigned int WINAPI
182_eina_thread_win32_cb(LPVOID lpParam)
183{
184 Eina_Thread_Win32 *tw = lpParam;
185
186 tw->ret = tw->func(tw->data);
187
188 return 0;
189}
190
191static inline Eina_Bool
192_eina_thread_create(Eina_Thread *t,
193 int affinity,
194 void *(*func)(void *data),
195 const void *data)
196{
197 Eina_Thread_Win32 *tw;
198
199 tw = eina_list_data_get(_thread_pool);
200 _thread_pool = eina_list_remove_list(_thread_pool, _thread_pool);
201
202 if (!tw)
203 {
204 tw = malloc(sizeof (Eina_Thread_Win32));
205 if (!tw) goto on_error;
206
207 do {
208 tw->index = _current_index++;
209 } while (tw->index == 0); /* prevent having a "false" main loop */
210 }
211
212 tw->func = func;
213 tw->data = (void *)data;
214 tw->tls_keys = NULL;
215
216 tw->thread = (HANDLE)_beginthreadex(NULL, 0, _eina_thread_win32_cb, tw, 0, NULL);
217 if (!tw->thread) goto on_error;
218
219 /* affinity is an hint, if we fail, we continue without */
220 if (affinity >= 0)
221 SetThreadAffinityMask(tw->thread, 1 << affinity);
222
223 _thread_running = eina_list_append(_thread_running, tw);
224
225 *t = tw->index;
226 return EINA_TRUE;
227
228 on_error:
229 _thread_pool = eina_list_append(_thread_pool, tw);
230 return EINA_FALSE;
231}
232
233static inline void *
234_eina_thread_join(Eina_Thread t)
235{
236 Eina_Thread_Win32 *tw;
237 void *ret;
238
239 tw = _eina_thread_win32_find(t);
240 if (!tw) return NULL;
241
242 WaitForSingleObject(tw->thread, INFINITE);
243 CloseHandle(tw->thread);
244
245 ret = tw->ret;
246
247 tw->ret = NULL;
248 tw->thread = NULL;
249 tw->func = NULL;
250 tw->data = NULL;
251 _eina_thread_tls_keys_clean(tw);
252
253 _thread_running = eina_list_remove(_thread_running, tw);
254 _thread_pool = eina_list_append(_thread_pool, _thread_pool);
255
256 return ret;
257}
258
259#elif defined(EFL_HAVE_POSIX_THREADS)
260# include <pthread.h> 32# include <pthread.h>
261# include <errno.h> 33# include <errno.h>
262 34
@@ -312,9 +84,6 @@ _eina_thread_self(void)
312 return (Eina_Thread)pthread_self(); 84 return (Eina_Thread)pthread_self();
313} 85}
314 86
315#else
316# error "Not supported any more"
317#endif
318 87
319typedef struct _Eina_Thread_Call Eina_Thread_Call; 88typedef struct _Eina_Thread_Call Eina_Thread_Call;
320struct _Eina_Thread_Call 89struct _Eina_Thread_Call