1 /* EINA - EFL data type library
2 * Copyright (C) 2012 Cedric Bail
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library;
16 * if not, see <http://www.gnu.org/licenses/>.
29 #include "eina_config.h"
30 #include "eina_thread.h"
31 #include "eina_sched.h"
33 #ifdef EINA_HAVE_THREADS
36 # elif defined(_WIN32)
38 # define WIN32_LEAN_AND_MEAN
40 # undef WIN32_LEAN_AND_MEAN
42 typedef struct _Eina_Thread_Win32 Eina_Thread_Win32;
43 struct _Eina_Thread_Win32
53 /* FIXME: For the moment Eina_Thread is considered not
54 thread safe, wondering if it's worth it */
55 static unsigned long int _current_index = 1; /* start from one as the main loop == 0 */
56 static Eina_List *_thread_pool = NULL;
57 static Eina_List *_thread_running = NULL;
59 static Eina_Thread_Win32 *
60 _eina_thread_win32_find(Eina_Thread index)
62 Eina_Thread_Win32 *tw;
65 EINA_LIST_FOREACH(_thread_running, l, tw)
66 if (tw->index == index)
72 _eina_thread_win32_self(void)
76 t = GetCurrentThread();
77 EINA_LIST_FOREACH(_thread_running, l, tw)
81 /* We assume main loop == 0 on Windows */
86 _eina_thread_win32_equal(Eina_Thread t1, Eina_Thread t2)
88 if (t1 == t2) return EINA_TRUE;
93 _eina_thread_win32_cb(LPVOID lpParam)
95 Eina_Thread_Win32 *tw = lpParam;
97 tw->ret = tw->func(tw->data, tw->index);
103 _eina_thread_win32_create(Eina_Thread *t,
107 Eina_Thread_Win32 *tw;
110 tw = eina_list_data_get(_thread_pool);
111 _thread_pool = eina_list_remove_list(_thread_pool, _thread_pool);
115 tw = malloc(sizeof (Eina_Thread_Win32));
116 if (!tw) goto on_error;
119 tw->index = _current_index++;
120 } while (tw->index == 0); /* prevent having a "false" main loop */
126 tw->thread = CreateThread(NULL, 0, _eina_thread_win32_cb, tw, 0, NULL);
127 if (!tw->thread) goto on_error;
129 _thread_running = eina_list_append(_thread_running, tw);
135 _thread_pool = eina_list_append(_thread_pool, tw);
140 _eina_thread_win32_join(Eina_Thread t)
142 Eina_Thread_Win32 *tw;
145 tw = _eina_thread_win32_find(index);
146 if (!tw) return NULL;
148 WaitForSingleObject(tw->thread, INFINITE);
149 CloseHandle(tw->thread);
158 _thread_running = eina_list_remove(_thread_running, tw);
159 _thread_pool = eina_list_append(_thread_pool, _thread_pool);
164 # define PHE(x, y) _eina_thread_win32_equal(x, y)
165 # define PHS() _eina_thread_win32_self()
166 # define PHC(x, f, d) _eina_thread_win32_create(x, f, d)
167 # define PHJ(x) _eina_thread_win32_join(x)
170 # include <pthread.h>
174 # include <sys/resource.h>
176 # include <sys/syscall.h>
181 _eina_thread_join(Eina_Thread t)
185 if (!pthread_join(t, &ret))
190 # define PHE(x, y) pthread_equal(x, y)
191 # define PHS() pthread_self()
192 # define PHC(x, f, d) pthread_create(x, NULL, (void*) f, d)
193 # define PHJ(x) _eina_thread_join(x)
197 # error "Not supported any more"
200 typedef struct _Eina_Thread_Call Eina_Thread_Call;
201 struct _Eina_Thread_Call
206 Eina_Thread_Priority prio;
210 #include "eina_thread.h"
213 _eina_internal_call(void *context)
215 Eina_Thread_Call *c = context;
218 if (c->prio == EINA_THREAD_BACKGROUND ||
219 c->prio == EINA_THREAD_IDLE)
220 eina_sched_prio_drop();
222 /* FIXME: set priority and affinity */
223 r = c->func((void*) c->data, eina_thread_self());
231 eina_thread_self(void)
237 eina_thread_equal(Eina_Thread t1, Eina_Thread t2)
239 return !!(PHE(t1, t2));
243 eina_thread_create(Eina_Thread *t,
244 Eina_Thread_Priority prio, Eina_Bool affinity,
245 Eina_Thread_Cb func, const void *data)
249 c = malloc(sizeof (Eina_Thread_Call));
250 if (!c) return EINA_FALSE;
255 c->affinity = affinity;
257 if (PHC(t, _eina_internal_call, c) == 0)
266 eina_thread_join(Eina_Thread t)
272 eina_thread_init(void)
277 eina_thread_shutdown(void)