doxy error fixes
[profile/ivi/ecore.git] / src / lib / ecore / ecore_thread.c
1 #ifdef HAVE_CONFIG_H
2 # include <config.h>
3 #endif
4
5 #ifdef HAVE_EVIL
6 # include <Evil.h>
7 #endif
8
9 #ifdef EFL_HAVE_PTHREAD
10 # include <pthread.h>
11 # ifdef __linux__
12 #  ifndef _GNU_SOURCE
13 #   define _GNU_SOURCE 1
14 #  endif
15 #  include <sched.h>
16 #  include <sys/time.h>
17 #  include <sys/resource.h>
18 #  include <unistd.h>
19 #  include <sys/syscall.h>
20 #  include <errno.h>
21 # endif
22 #endif
23
24 #include "Ecore.h"
25 #include "ecore_private.h"
26
27 typedef struct _Ecore_Pthread_Worker Ecore_Pthread_Worker;
28 typedef struct _Ecore_Pthread Ecore_Pthread;
29 typedef struct _Ecore_Thread_Data  Ecore_Thread_Data;
30
31 struct _Ecore_Thread_Data
32 {
33    void *data;
34    Eina_Free_Cb cb;
35 };
36
37 struct _Ecore_Pthread_Worker
38 {
39    union {
40       struct {
41          Ecore_Cb func_blocking;
42       } short_run;
43       struct {
44          Ecore_Thread_Heavy_Cb func_heavy;
45          Ecore_Thread_Notify_Cb func_notify;
46          Ecore_Pipe *notify;
47       } long_run;
48    } u;
49    
50    Ecore_Cb func_cancel;
51    Ecore_Cb func_end;
52 #ifdef EFL_HAVE_PTHREAD
53    pthread_t self;
54    Eina_Hash *hash;
55    pthread_cond_t cond;
56    pthread_mutex_t mutex;
57 #endif
58    
59    const void *data;
60    
61    Eina_Bool cancel : 1;
62    Eina_Bool long_run : 1;
63 };
64
65 #ifdef EFL_HAVE_PTHREAD
66 typedef struct _Ecore_Pthread_Data Ecore_Pthread_Data;
67
68 struct _Ecore_Pthread_Data
69 {
70    Ecore_Pipe *p;
71    void *data;
72    pthread_t thread;
73 };
74 #endif
75
76 static int _ecore_thread_count_max = 0;
77 static int ECORE_THREAD_PIPE_DEL = 0;
78
79 #ifdef EFL_HAVE_PTHREAD
80 static int _ecore_thread_count = 0;
81
82 static Eina_List *_ecore_active_job_threads = NULL;
83 static Eina_List *_ecore_pending_job_threads = NULL;
84 static Eina_List *_ecore_pending_job_threads_long = NULL;
85 static Ecore_Event_Handler *del_handler = NULL;
86 static pthread_mutex_t _ecore_pending_job_threads_mutex = PTHREAD_MUTEX_INITIALIZER;
87
88 static Eina_Hash *_ecore_thread_global_hash = NULL;
89 static pthread_rwlock_t _ecore_thread_global_hash_lock = PTHREAD_RWLOCK_INITIALIZER;
90 static pthread_mutex_t _ecore_thread_global_hash_mutex = PTHREAD_MUTEX_INITIALIZER;
91 static pthread_cond_t _ecore_thread_global_hash_cond = PTHREAD_COND_INITIALIZER;
92 static pthread_t main_loop_thread;
93 static Eina_Bool have_main_loop_thread = 0;
94 static void
95 _ecore_thread_data_free(void *data)
96 {
97    Ecore_Thread_Data *d = data;
98
99    if (d->cb) d->cb(d->data);
100    free(d);
101 }
102
103 static void
104 _ecore_thread_pipe_free(void *data __UNUSED__, void *event)
105 {
106    Ecore_Pipe *p = event;
107
108    ecore_pipe_del(p);
109 }
110
111 static Eina_Bool
112 _ecore_thread_pipe_del(void *data __UNUSED__, int type __UNUSED__, void *event __UNUSED__)
113 {
114    /* This is a hack to delay pipe destruction until we are out of its internal loop. */
115    return ECORE_CALLBACK_CANCEL;
116 }
117
118 static void
119 _ecore_thread_end(Ecore_Pthread_Data *pth)
120 {
121    Ecore_Pipe *p;
122
123    if (pthread_join(pth->thread, (void **) &p) != 0)
124      return ;
125
126    _ecore_active_job_threads = eina_list_remove(_ecore_active_job_threads, pth);
127
128    ecore_event_add(ECORE_THREAD_PIPE_DEL, pth->p, _ecore_thread_pipe_free, NULL);
129    free(pth);
130 }
131
132 static void
133 _ecore_thread_handler(void *data __UNUSED__, void *buffer, unsigned int nbyte)
134 {
135    Ecore_Pthread_Worker *work;
136
137    if (nbyte != sizeof (Ecore_Pthread_Worker *)) return ;
138
139    work = *(Ecore_Pthread_Worker **)buffer;
140
141    if (work->cancel)
142      {
143         if (work->func_cancel)
144           work->func_cancel((void *) work->data);
145      }
146    else
147      {
148         if (work->func_end)
149           work->func_end((void *) work->data);
150      }
151
152    if (work->long_run)
153         ecore_pipe_del(work->u.long_run.notify);
154    pthread_cond_destroy(&work->cond);
155    pthread_mutex_destroy(&work->mutex);
156    if (work->hash)
157      eina_hash_free(work->hash);
158    free(work);
159 }
160
161 static void
162 _ecore_notify_handler(void *data, void *buffer, unsigned int nbyte)
163 {
164    Ecore_Pthread_Worker *work = data;
165    void *user_data;
166
167    if (nbyte != sizeof (Ecore_Pthread_Worker *)) return ;
168
169    user_data = *(void **)buffer;
170
171    if (work->u.long_run.func_notify)
172      work->u.long_run.func_notify((Ecore_Thread *) work, user_data, (void *) work->data);
173 }
174
175 static void
176 _ecore_short_job(Ecore_Pipe *end_pipe)
177 {
178    Ecore_Pthread_Worker *work;
179
180    while (_ecore_pending_job_threads)
181      {
182         pthread_mutex_lock(&_ecore_pending_job_threads_mutex);
183
184         if (!_ecore_pending_job_threads)
185           {
186              pthread_mutex_unlock(&_ecore_pending_job_threads_mutex);
187              break;
188           }
189
190         work = eina_list_data_get(_ecore_pending_job_threads);
191         _ecore_pending_job_threads = eina_list_remove_list(_ecore_pending_job_threads, _ecore_pending_job_threads);
192
193         pthread_mutex_unlock(&_ecore_pending_job_threads_mutex);
194
195         if (!work->cancel)
196           work->u.short_run.func_blocking((void *) work->data);
197
198         ecore_pipe_write(end_pipe, &work, sizeof (Ecore_Pthread_Worker *));
199      }
200 }
201
202 static void
203 _ecore_long_job(Ecore_Pipe *end_pipe, pthread_t thread)
204 {
205    Ecore_Pthread_Worker *work;
206
207    while (_ecore_pending_job_threads_long)
208      {
209         pthread_mutex_lock(&_ecore_pending_job_threads_mutex);
210
211         if (!_ecore_pending_job_threads_long)
212           {
213              pthread_mutex_unlock(&_ecore_pending_job_threads_mutex);
214              break;
215           }
216
217         work = eina_list_data_get(_ecore_pending_job_threads_long);
218         _ecore_pending_job_threads_long = eina_list_remove_list(_ecore_pending_job_threads_long, _ecore_pending_job_threads_long);
219
220         pthread_mutex_unlock(&_ecore_pending_job_threads_mutex);
221
222         work->self = thread;
223         if (!work->cancel)
224           work->u.long_run.func_heavy((Ecore_Thread *) work, (void *) work->data);
225
226         ecore_pipe_write(end_pipe, &work, sizeof (Ecore_Pthread_Worker *));
227      }
228 }
229
230 /* Lower priority of current thread.
231  *
232  * It's used by worker threads so they use up "bg cpu" as it was really intended
233  * to work. If current thread is running with real-time priority, we decrease
234  * our priority by 5. This is done in a portable way.  Otherwise we are
235  * running with SCHED_OTHER policy and there's no portable way to set the nice
236  * level on current thread. In Linux, it does work and it's the only one that is
237  * implemented.
238  */
239 static void
240 _ecore_thread_pri_drop(void)
241 {
242    struct sched_param param;
243    int pol, prio, ret;
244    pid_t tid;
245    pthread_t pthread_id;
246
247    pthread_id = pthread_self();
248    ret = pthread_getschedparam(pthread_id, &pol, &param);
249    if (ret)
250      {
251         ERR("Unable to query sched parameters");
252         return;
253      }
254
255    if (EINA_UNLIKELY(pol == SCHED_RR || pol == SCHED_FIFO))
256      {
257         prio = sched_get_priority_max(pol);
258         param.sched_priority += 5;
259         if (prio > 0 && param.sched_priority > prio)
260            param.sched_priority = prio;
261
262         pthread_setschedparam(pthread_id, pol, &param);
263      }
264 #ifdef __linux__
265    else
266      {
267         errno = 0;
268         prio = getpriority(PRIO_PROCESS, 0);
269         if (errno == 0)
270           {
271              prio += 5;
272              if (prio > 19)
273                 prio = 19;
274
275              setpriority(PRIO_PROCESS, 0, prio);
276           }
277      }
278 #endif
279 }
280
281 static void *
282 _ecore_direct_worker(Ecore_Pthread_Worker *work)
283 {
284    Ecore_Pthread_Data *pth;
285
286    pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
287    pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL);
288    _ecore_thread_pri_drop();
289
290    pth = malloc(sizeof (Ecore_Pthread_Data));
291    if (!pth) return NULL;
292
293    pth->p = ecore_pipe_add(_ecore_thread_handler, NULL);
294    if (!pth->p)
295      {
296         free(pth);
297         return NULL;
298      }
299    pth->thread = pthread_self();
300
301    work->self = pth->thread;
302    work->u.long_run.func_heavy((Ecore_Thread *) work, (void *) work->data);
303
304    ecore_pipe_write(pth->p, &work, sizeof (Ecore_Pthread_Worker *));
305
306    work = malloc(sizeof (Ecore_Pthread_Worker));
307    if (!work)
308      {
309         ecore_pipe_del(pth->p);
310         free(pth);
311         return NULL;
312      }
313
314    work->data = pth;
315    work->u.short_run.func_blocking = NULL;
316    work->func_end = (void *) _ecore_thread_end;
317    work->func_cancel = NULL;
318    work->cancel = EINA_FALSE;
319    work->long_run = EINA_FALSE;
320    work->hash = NULL;
321    pthread_cond_init(&work->cond, NULL);
322    pthread_mutex_init(&work->mutex, NULL);
323
324    ecore_pipe_write(pth->p, &work, sizeof (Ecore_Pthread_Worker *));
325
326    return pth->p;
327 }
328
329 static void *
330 _ecore_thread_worker(Ecore_Pthread_Data *pth)
331 {
332    Ecore_Pthread_Worker *work;
333
334    pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
335    pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL);
336    _ecore_thread_pri_drop();
337
338    pthread_mutex_lock(&_ecore_pending_job_threads_mutex);
339    _ecore_thread_count++;
340    pthread_mutex_unlock(&_ecore_pending_job_threads_mutex);
341
342  on_error:
343    if (_ecore_pending_job_threads) _ecore_short_job(pth->p);
344    if (_ecore_pending_job_threads_long) _ecore_long_job(pth->p, pth->thread);
345
346    /* FIXME: Check if there is long running task todo, and switch to long run handler. */
347
348    pthread_mutex_lock(&_ecore_pending_job_threads_mutex);
349    if (_ecore_pending_job_threads)
350      {
351         pthread_mutex_unlock(&_ecore_pending_job_threads_mutex);
352         goto on_error;
353      }
354    if (_ecore_pending_job_threads_long)
355      {
356         pthread_mutex_unlock(&_ecore_pending_job_threads_mutex);
357         goto on_error;
358      }
359
360    _ecore_thread_count--;
361
362    pthread_mutex_unlock(&_ecore_pending_job_threads_mutex);
363
364    work = malloc(sizeof (Ecore_Pthread_Worker));
365    if (!work) return NULL;
366
367    work->data = pth;
368    work->u.short_run.func_blocking = NULL;
369    work->func_end = (void *) _ecore_thread_end;
370    work->func_cancel = NULL;
371    work->cancel = EINA_FALSE;
372    work->long_run = EINA_FALSE;
373    work->hash = NULL;
374    pthread_cond_init(&work->cond, NULL);
375    pthread_mutex_init(&work->mutex, NULL);
376
377    ecore_pipe_write(pth->p, &work, sizeof (Ecore_Pthread_Worker *));
378
379    return pth->p;
380 }
381
382 #endif
383
384 void
385 _ecore_thread_init(void)
386 {
387    _ecore_thread_count_max = eina_cpu_count();
388    if (_ecore_thread_count_max <= 0)
389      _ecore_thread_count_max = 1;
390
391    ECORE_THREAD_PIPE_DEL = ecore_event_type_new();
392 #ifdef EFL_HAVE_PTHREAD
393    del_handler = ecore_event_handler_add(ECORE_THREAD_PIPE_DEL, _ecore_thread_pipe_del, NULL);
394    main_loop_thread = pthread_self();
395    have_main_loop_thread = 1;
396 #endif
397 }
398
399 void
400 _ecore_thread_shutdown(void)
401 {
402    /* FIXME: If function are still running in the background, should we kill them ? */
403 #ifdef EFL_HAVE_PTHREAD
404    Ecore_Pthread_Worker *work;
405    Ecore_Pthread_Data *pth;
406
407    pthread_mutex_lock(&_ecore_pending_job_threads_mutex);
408
409    EINA_LIST_FREE(_ecore_pending_job_threads, work)
410      {
411         if (work->func_cancel)
412           work->func_cancel((void *)work->data);
413         free(work);
414      }
415
416    pthread_mutex_unlock(&_ecore_pending_job_threads_mutex);
417
418    EINA_LIST_FREE(_ecore_active_job_threads, pth)
419      {
420         Ecore_Pipe *p;
421
422         pthread_cancel(pth->thread);
423         pthread_join(pth->thread, (void **) &p);
424
425         ecore_pipe_del(pth->p);
426      }
427    if (_ecore_thread_global_hash)
428      eina_hash_free(_ecore_thread_global_hash);
429    ecore_event_handler_del(del_handler);
430    have_main_loop_thread = 0;
431    del_handler = NULL;
432 #endif
433 }
434 /**
435  * @addtogroup Ecore_Thread Ecore Thread Functions
436  * These functions allow for ecore-managed threads which integrate with ecore's main loop.
437  * @{
438  */
439
440 /**
441  * @brief Run some blocking code in a parallel thread to avoid locking the main loop.
442  * @param func_blocking The function that should run in another thread.
443  * @param func_end The function that will be called in the main loop if the thread terminate correctly.
444  * @param func_cancel The function that will be called in the main loop if the thread is cancelled.
445  * @param data User context data to pass to all callback.
446  * @return A reference to the newly created thread instance, or NULL if it failed.
447  *
448  * ecore_thread_run provide a facility for easily managing blocking task in a
449  * parallel thread. You should provide three function. The first one, func_blocking,
450  * that will do the blocking work in another thread (so you should not use the
451  * EFL in it except Eina if you are careful). The second one, func_end,
452  * that will be called in Ecore main loop when func_blocking is done. So you
453  * can use all the EFL inside this function. The last one, func_cancel, will
454  * be called in the main loop if the thread is cancelled or could not run at all.
455  *
456  * Be aware, that you can't make assumption on the result order of func_end
457  * after many call to ecore_thread_run, as we start as much thread as the
458  * host CPU can handle.
459  */
460 EAPI Ecore_Thread *
461 ecore_thread_run(Ecore_Cb func_blocking,
462                  Ecore_Cb func_end,
463                  Ecore_Cb func_cancel,
464                  const void *data)
465 {
466 #ifdef EFL_HAVE_PTHREAD
467    Ecore_Pthread_Worker *work;
468    Ecore_Pthread_Data *pth = NULL;
469
470    if (!func_blocking) return NULL;
471
472    work = malloc(sizeof (Ecore_Pthread_Worker));
473    if (!work)
474      {
475         func_cancel((void *) data);
476         return NULL;
477      }
478
479    work->u.short_run.func_blocking = func_blocking;
480    work->hash = NULL;
481    pthread_cond_init(&work->cond, NULL);
482    pthread_mutex_init(&work->mutex, NULL);
483    work->func_end = func_end;
484    work->func_cancel = func_cancel;
485    work->cancel = EINA_FALSE;
486    work->long_run = EINA_FALSE;
487    work->data = data;
488
489    pthread_mutex_lock(&_ecore_pending_job_threads_mutex);
490    _ecore_pending_job_threads = eina_list_append(_ecore_pending_job_threads, work);
491
492    if (_ecore_thread_count == _ecore_thread_count_max)
493      {
494         pthread_mutex_unlock(&_ecore_pending_job_threads_mutex);
495         return (Ecore_Thread *) work;
496      }
497
498    pthread_mutex_unlock(&_ecore_pending_job_threads_mutex);
499
500    /* One more thread could be created. */
501    pth = malloc(sizeof (Ecore_Pthread_Data));
502    if (!pth) goto on_error;
503
504    pth->p = ecore_pipe_add(_ecore_thread_handler, NULL);
505    if (!pth->p) goto on_error;
506
507    if (pthread_create(&pth->thread, NULL, (void *) _ecore_thread_worker, pth) == 0)
508       return (Ecore_Thread *) work;
509
510  on_error:
511    if (pth)
512      {
513         if (pth->p) ecore_pipe_del(pth->p);
514         free(pth);
515      }
516
517    if (_ecore_thread_count == 0)
518      {
519         if (work->func_cancel)
520           work->func_cancel((void *) work->data);
521         free(work);
522         work = NULL;
523      }
524    return (Ecore_Thread *) work;
525 #else
526    /*
527      If no thread and as we don't want to break app that rely on this
528      facility, we will lock the interface until we are done.
529     */
530    func_blocking((void *)data);
531    func_end((void *)data);
532
533    return NULL;
534 #endif
535 }
536
537 /**
538  * @brief Cancel a running thread.
539  * @param thread The thread to cancel.
540  * @return Will return EINA_TRUE if the thread has been cancelled,
541  *         EINA_FALSE if it is pending.
542  *
543  * ecore_thread_cancel give the possibility to cancel a task still running. It
544  * will return EINA_FALSE, if the destruction is delayed or EINA_TRUE if it is
545  * cancelled after this call.
546  *
547  * You should use this function only in the main loop.
548  *
549  * func_end, func_cancel will destroy the handler, so don't use it after.
550  * And if ecore_thread_cancel return EINA_TRUE, you should not use Ecore_Thread also.
551  */
552 EAPI Eina_Bool
553 ecore_thread_cancel(Ecore_Thread *thread)
554 {
555 #ifdef EFL_HAVE_PTHREAD
556    Ecore_Pthread_Worker *work = (Ecore_Pthread_Worker *)thread;
557    Eina_List *l;
558    
559    if (!work)
560       return EINA_TRUE;
561    
562    pthread_mutex_lock(&_ecore_pending_job_threads_mutex);
563    
564    if ((have_main_loop_thread) &&
565        (pthread_equal(main_loop_thread, pthread_self())))
566      {
567         EINA_LIST_FOREACH(_ecore_pending_job_threads, l, work)
568           {
569              if ((void *) work == (void *) thread)
570                {
571                   _ecore_pending_job_threads = eina_list_remove_list(_ecore_pending_job_threads, l);
572                   
573                   pthread_mutex_unlock(&_ecore_pending_job_threads_mutex);
574                   
575                   if (work->func_cancel)
576                      work->func_cancel((void *) work->data);
577                   free(work);
578                   
579                   return EINA_TRUE;
580                }
581           }
582      }
583
584    pthread_mutex_unlock(&_ecore_pending_job_threads_mutex);
585
586    /* Delay the destruction */
587    ((Ecore_Pthread_Worker *)thread)->cancel = EINA_TRUE;
588    return EINA_FALSE;
589 #else
590    return EINA_TRUE;
591 #endif
592 }
593
594 /**
595  * @brief Tell if a thread was canceled or not.
596  * @param thread The thread to test.
597  * @return EINA_TRUE if the thread is cancelled,
598  *         EINA_FALSE if it is not.
599  *
600  * You can use this function in main loop and in the thread.
601  */
602 EAPI Eina_Bool
603 ecore_thread_check(Ecore_Thread *thread)
604 {
605    Ecore_Pthread_Worker *worker = (Ecore_Pthread_Worker *) thread;
606
607    if (!worker) return EINA_TRUE;
608    return worker->cancel;
609 }
610
611 /**
612  * @brief Run some heavy code in a parallel thread to avoid locking the main loop.
613  * @param func_heavy The function that should run in another thread.
614  * @param func_notify The function that will receive the data send by func_heavy in the main loop.
615  * @param func_end The function that will be called in the main loop if the thread terminate correctly.
616  * @param func_cancel The function that will be called in the main loop if the thread is cancelled.
617  * @param data User context data to pass to all callback.
618  * @param try_no_queue If you wan't to run outside of the thread pool.
619  * @return A reference to the newly created thread instance, or NULL if it failed.
620  *
621  * ecore_long_run provide a facility for easily managing heavy task in a
622  * parallel thread. You should provide four functions. The first one, func_heavy,
623  * that will do the heavy work in another thread (so you should not use the
624  * EFL in it except Eina and Eet if you are careful). The second one, func_notify,
625  * will receive the data send from the thread function (func_heavy) by ecore_thread_notify
626  * in the main loop (and so, can use all the EFL). Tje third, func_end,
627  * that will be called in Ecore main loop when func_heavy is done. So you
628  * can use all the EFL inside this function. The last one, func_cancel, will
629  * be called in the main loop also, if the thread is cancelled or could not run at all.
630  *
631  * Be aware, that you can't make assumption on the result order of func_end
632  * after many call to ecore_long_run, as we start as much thread as the
633  * host CPU can handle.
634  *
635  * If you set try_no_queue, it will try to run outside of the thread pool, this can bring
636  * the CPU down, so be careful with that. Of course if it can't start a new thread, it will
637  * try to use one from the pool.
638  */
639 EAPI Ecore_Thread *ecore_long_run(Ecore_Thread_Heavy_Cb func_heavy,
640                                   Ecore_Thread_Notify_Cb func_notify,
641                                   Ecore_Cb func_end,
642                                   Ecore_Cb func_cancel,
643                                   const void *data,
644                                   Eina_Bool try_no_queue)
645 {
646
647 #ifdef EFL_HAVE_PTHREAD
648    Ecore_Pthread_Worker *worker;
649    Ecore_Pthread_Data *pth = NULL;
650
651    if (!func_heavy) return NULL;
652
653    worker = malloc(sizeof (Ecore_Pthread_Worker));
654    if (!worker) goto on_error;
655
656    worker->u.long_run.func_heavy = func_heavy;
657    worker->u.long_run.func_notify = func_notify;
658    worker->hash = NULL;
659    pthread_cond_init(&worker->cond, NULL);
660    pthread_mutex_init(&worker->mutex, NULL);
661    worker->func_cancel = func_cancel;
662    worker->func_end = func_end;
663    worker->data = data;
664    worker->cancel = EINA_FALSE;
665    worker->long_run = EINA_TRUE;
666
667    worker->u.long_run.notify = ecore_pipe_add(_ecore_notify_handler, worker);
668
669    if (!try_no_queue)
670      {
671         pthread_t t;
672
673         if (pthread_create(&t, NULL, (void *) _ecore_direct_worker, worker) == 0)
674            return (Ecore_Thread *) worker;
675      }
676
677    pthread_mutex_lock(&_ecore_pending_job_threads_mutex);
678    _ecore_pending_job_threads_long = eina_list_append(_ecore_pending_job_threads_long, worker);
679
680    if (_ecore_thread_count == _ecore_thread_count_max)
681      {
682         pthread_mutex_unlock(&_ecore_pending_job_threads_mutex);
683         return (Ecore_Thread *) worker;
684      }
685
686    pthread_mutex_unlock(&_ecore_pending_job_threads_mutex);
687
688    /* One more thread could be created. */
689    pth = malloc(sizeof (Ecore_Pthread_Data));
690    if (!pth) goto on_error;
691
692    pth->p = ecore_pipe_add(_ecore_thread_handler, NULL);
693    if (!pth->p) goto on_error;
694
695    if (pthread_create(&pth->thread, NULL, (void *) _ecore_thread_worker, pth) == 0)
696       return (Ecore_Thread *) worker;
697
698  on_error:
699    if (pth)
700      {
701         if (pth->p) ecore_pipe_del(pth->p);
702         free(pth);
703      }
704
705    if (_ecore_thread_count == 0)
706      {
707         if (func_cancel) func_cancel((void *) data);
708
709         if (worker)
710           {
711              ecore_pipe_del(worker->u.long_run.notify);
712              free(worker);
713              worker = NULL;
714           }
715      }
716
717    return (Ecore_Thread *) worker;
718 #else
719    Ecore_Pthread_Worker worker;
720
721    (void) try_no_queue;
722
723    /*
724      If no thread and as we don't want to break app that rely on this
725      facility, we will lock the interface until we are done.
726     */
727    worker.u.long_run.func_heavy = func_heavy;
728    worker.u.long_run.func_notify = func_notify;
729    worker.u.long_run.notify = NULL;
730    worker.func_cancel = func_cancel;
731    worker.func_end = func_end;
732    worker.data = data;
733    worker.cancel = EINA_FALSE;
734    worker.long_run = EINA_TRUE;
735
736    func_heavy((Ecore_Thread *) &worker, (void *)data);
737
738    if (worker.cancel) func_cancel((void *)data);
739    else func_end((void *)data);
740
741    return NULL;
742 #endif
743 }
744
745 /**
746  * @brief Send data to main loop from worker thread.
747  * @param thread The current Ecore_Thread context to send data from
748  * @param data Data to be transmitted to the main loop
749  * @return EINA_TRUE if data was successfully send to main loop,
750  *         EINA_FALSE if anything goes wrong.
751  *
752  * After a succesfull call, the data should be considered owned
753  * by the main loop.
754  *
755  * You should use this function only in the func_heavy call.
756  */
757 EAPI Eina_Bool
758 ecore_thread_notify(Ecore_Thread *thread, const void *data)
759 {
760    Ecore_Pthread_Worker *worker = (Ecore_Pthread_Worker *) thread;
761
762    if (!worker) return EINA_FALSE;
763    if (!worker->long_run) return EINA_FALSE;
764
765 #ifdef EFL_HAVE_PTHREAD
766    if (!pthread_equal(worker->self, pthread_self())) return EINA_FALSE;
767
768    ecore_pipe_write(worker->u.long_run.notify, &data, sizeof (void *));
769
770    return EINA_TRUE;
771 #else
772    worker->u.long_run.func_notify(thread, (void*) data, (void*) worker->data);
773
774    return EINA_TRUE;
775 #endif
776 }
777
778 /**
779  * @brief Get number of active thread jobs
780  * @return Number of active threads running jobs
781  * This returns the number of threads currently running jobs through the
782  * ecore_thread api.
783  */
784 EAPI int
785 ecore_thread_active_get(void)
786 {
787 #ifdef EFL_HAVE_PTHREAD
788    return _ecore_thread_count;
789 #else
790    return 0;
791 #endif
792 }
793
794 /**
795  * @brief Get number of pending (short) thread jobs
796  * @return Number of pending threads running "short" jobs
797  * This returns the number of threads currently running jobs through the
798  * ecore_thread_run api call.
799  */
800 EAPI int
801 ecore_thread_pending_get(void)
802 {
803    int ret;
804 #ifdef EFL_HAVE_PTHREAD
805    pthread_mutex_lock(&_ecore_pending_job_threads_mutex);
806    ret = eina_list_count(_ecore_pending_job_threads);
807    pthread_mutex_unlock(&_ecore_pending_job_threads_mutex);
808    return ret;
809 #else
810    return 0;
811 #endif
812 }
813
814 /**
815  * @brief Get number of pending long thread jobs
816  * @return Number of pending threads running "long" jobs
817  * This returns the number of threads currently running jobs through the
818  * ecore_long_run api call.
819  */
820 EAPI int
821 ecore_thread_pending_long_get(void)
822 {
823    int ret;
824 #ifdef EFL_HAVE_PTHREAD
825    pthread_mutex_lock(&_ecore_pending_job_threads_mutex);
826    ret = eina_list_count(_ecore_pending_job_threads_long);
827    pthread_mutex_unlock(&_ecore_pending_job_threads_mutex);
828    return ret;
829 #else
830    return 0;
831 #endif
832 }
833
834 /**
835  * @brief Get number of pending thread jobs
836  * @return Number of pending threads running jobs
837  * This returns the number of threads currently running jobs through the
838  * ecore_thread_run and ecore_long_run api calls combined.
839  */
840 EAPI int
841 ecore_thread_pending_total_get(void)
842 {
843    int ret;
844 #ifdef EFL_HAVE_PTHREAD
845    pthread_mutex_lock(&_ecore_pending_job_threads_mutex);
846    ret = eina_list_count(_ecore_pending_job_threads) + eina_list_count(_ecore_pending_job_threads_long);
847    pthread_mutex_unlock(&_ecore_pending_job_threads_mutex);
848    return ret;
849 #else
850    return 0;
851 #endif
852 }
853
854 /**
855  * @brief Get the max number of threads that can run simultaneously
856  * @return Max number of threads ecore will run
857  * This returns the total number of threads that ecore will attempt to run
858  * simultaneously.
859  */
860 EAPI int
861 ecore_thread_max_get(void)
862 {
863    return _ecore_thread_count_max;
864 }
865
866 /**
867  * @brief Set the max number of threads that can run simultaneously
868  * @param num The new maximum
869  * This sets the maximum number of threads that ecore will try to run
870  * simultaneously.  This number cannot be < 1 or >= 2x the number of active cpus.
871  */
872 EAPI void
873 ecore_thread_max_set(int num)
874 {
875    if (num < 1) return;
876    /* avoid doing something hilarious by blocking dumb users */
877    if (num >= (2 * eina_cpu_count())) return;
878
879    _ecore_thread_count_max = num;
880 }
881
882 /**
883  * @brief Reset the max number of threads that can run simultaneously
884  * This resets the maximum number of threads that ecore will try to run
885  * simultaneously to the number of active cpus.
886  */
887 EAPI void
888 ecore_thread_max_reset(void)
889 {
890    _ecore_thread_count_max = eina_cpu_count();
891 }
892
893 /**
894  * @brief Get the number of threads which are available to be used
895  * @return The number of available threads
896  * This returns the number of threads slots that ecore has currently available.
897  * Assuming that you haven't changed the max number of threads with @ref ecore_thread_max_set
898  * this should be equal to (num_cpus - (active_running + active_long_running))
899  */
900 EAPI int
901 ecore_thread_available_get(void)
902 {
903    int ret;
904 #ifdef EFL_HAVE_PTHREAD
905    pthread_mutex_lock(&_ecore_pending_job_threads_mutex);
906    ret = _ecore_thread_count_max - _ecore_thread_count;
907    pthread_mutex_unlock(&_ecore_pending_job_threads_mutex);
908    return ret;
909 #else
910    return 0;
911 #endif
912 }
913
914 /**
915  * @brief Add data to the thread for subsequent use
916  * @param thread The thread context to add to
917  * @param key The name string to add the data with
918  * @param value The data to add
919  * @param cb The callback to free the data with
920  * @param direct If true, this will not copy the key string (like eina_hash_direct_add)
921  * @return EINA_TRUE on success, EINA_FALSE on failure
922  * This adds data to the thread context, allowing the thread
923  * to retrieve and use it without complicated mutexing.  This function can only be called by a
924  * *_run thread INSIDE the thread and will return EINA_FALSE in any case but success.
925  * All data added to the thread will be freed with its associated callback (if present)
926  * upon thread termination.  If no callback is specified, it is expected that the user will free the
927  * data, but this is most likely not what you want.
928  */
929 EAPI Eina_Bool
930 ecore_thread_local_data_add(Ecore_Thread *thread, const char *key, void *value, Eina_Free_Cb cb, Eina_Bool direct)
931 {
932    Ecore_Pthread_Worker *worker = (Ecore_Pthread_Worker *) thread;
933    Ecore_Thread_Data *d;
934    Eina_Bool ret;
935
936    if ((!thread) || (!key) || (!value))
937      return EINA_FALSE;
938 #ifdef EFL_HAVE_PTHREAD
939    if (!pthread_equal(worker->self, pthread_self())) return EINA_FALSE;
940
941    if (!worker->hash)
942      worker->hash = eina_hash_string_small_new(_ecore_thread_data_free);
943
944    if (!worker->hash)
945      return EINA_FALSE;
946
947    if (!(d = malloc(sizeof(Ecore_Thread_Data))))
948      return EINA_FALSE;
949
950    d->data = value;
951    d->cb = cb;
952
953    if (direct)
954      ret = eina_hash_direct_add(worker->hash, key, d);
955    else
956      ret = eina_hash_add(worker->hash, key, d);
957    pthread_cond_broadcast(&worker->cond);
958    return ret;
959 #else
960    return EINA_TRUE;
961 #endif
962 }
963
964 /**
965  * @brief Modify data in the thread, or add if not found
966  * @param thread The thread context
967  * @param key The name string to add the data with
968  * @param value The data to add
969  * @param cb The callback to free the data with
970  * @return The old data associated with @p key on success if modified, NULL if added
971  * This adds/modifies data in the thread context, adding only if modify fails.
972  * This function can only be called by a *_run thread INSIDE the thread.
973  * All data added to the thread pool will be freed with its associated callback (if present)
974  * upon thread termination.  If no callback is specified, it is expected that the user will free the
975  * data, but this is most likely not what you want.
976  */
977 EAPI void *
978 ecore_thread_local_data_set(Ecore_Thread *thread, const char *key, void *value, Eina_Free_Cb cb)
979 {
980    Ecore_Pthread_Worker *worker = (Ecore_Pthread_Worker *) thread;
981    Ecore_Thread_Data *d, *r;
982    void *ret;
983    if ((!thread) || (!key) || (!value))
984      return NULL;
985 #ifdef EFL_HAVE_PTHREAD
986    if (!pthread_equal(worker->self, pthread_self())) return NULL;
987
988    if (!worker->hash)
989      worker->hash = eina_hash_string_small_new(_ecore_thread_data_free);
990
991    if (!worker->hash)
992      return NULL;
993
994    if (!(d = malloc(sizeof(Ecore_Thread_Data))))
995      return NULL;
996
997    d->data = value;
998    d->cb = cb;
999
1000    r = eina_hash_set(worker->hash, key, d);
1001    pthread_cond_broadcast(&worker->cond);
1002    ret = r->data;
1003    free(r);
1004    return ret;
1005 #else
1006    return NULL;
1007 #endif
1008 }
1009
1010 /**
1011  * @brief Find data in the thread's data
1012  * @param thread The thread context
1013  * @param key The name string the data is associated with
1014  * @return The value, or NULL on error
1015  * This finds data in the thread context that has been previously added with @ref ecore_thread_local_data_add
1016  * This function can only be called by a *_run thread INSIDE the thread, and will return NULL
1017  * in any case but success.
1018  */
1019
1020 EAPI void *
1021 ecore_thread_local_data_find(Ecore_Thread *thread, const char *key)
1022 {
1023    Ecore_Pthread_Worker *worker = (Ecore_Pthread_Worker *) thread;
1024    Ecore_Thread_Data *d;
1025
1026    if ((!thread) || (!key))
1027      return NULL;
1028 #ifdef EFL_HAVE_PTHREAD
1029    if (!pthread_equal(worker->self, pthread_self())) return NULL;
1030
1031    if (!worker->hash)
1032      return NULL;
1033
1034    d = eina_hash_find(worker->hash, key);
1035    return d->data;
1036 #else
1037    return NULL;
1038 #endif
1039 }
1040
1041 /**
1042  * @brief Delete data from the thread's data
1043  * @param thread The thread context
1044  * @param key The name string the data is associated with
1045  * @return EINA_TRUE on success, EINA_FALSE on failure
1046  * This deletes the data pointer from the thread context which was previously added with @ref ecore_thread_local_data_add
1047  * This function can only be called by a *_run thread INSIDE the thread, and will return EINA_FALSE
1048  * in any case but success.  Note that this WILL free the data if a callback was specified.
1049  */
1050 EAPI Eina_Bool
1051 ecore_thread_local_data_del(Ecore_Thread *thread, const char *key)
1052 {
1053    Ecore_Pthread_Worker *worker = (Ecore_Pthread_Worker *) thread;
1054    Ecore_Thread_Data *d;
1055    if ((!thread) || (!key))
1056      return EINA_FALSE;
1057 #ifdef EFL_HAVE_PTHREAD
1058    if (!pthread_equal(worker->self, pthread_self())) return EINA_FALSE;
1059
1060    if (!worker->hash)
1061      return EINA_FALSE;
1062    if ((d = eina_hash_find(worker->hash, key)))
1063      _ecore_thread_data_free(d);
1064    return eina_hash_del_by_key(worker->hash, key);
1065 #else
1066    return EINA_TRUE;
1067 #endif
1068 }
1069
1070 /**
1071  * @brief Add data to the global data
1072  * @param key The name string to add the data with
1073  * @param value The data to add
1074  * @param cb The optional callback to free the data with once ecore is shut down
1075  * @param direct If true, this will not copy the key string (like eina_hash_direct_add)
1076  * @return EINA_TRUE on success, EINA_FALSE on failure
1077  * This adds data to the global thread data, and will return EINA_FALSE in any case but success.
1078  * All data added to global can be manually freed, or a callback can be provided with @p cb which will
1079  * be called upon ecore_thread shutting down.  Note that if you have manually freed data that a callback
1080  * was specified for, you will most likely encounter a segv later on.
1081  */
1082 EAPI Eina_Bool
1083 ecore_thread_global_data_add(const char *key, void *value, Eina_Free_Cb cb, Eina_Bool direct)
1084 {
1085    Eina_Bool ret;
1086    Ecore_Thread_Data *d;
1087
1088    if ((!key) || (!value))
1089      return EINA_FALSE;
1090 #ifdef EFL_HAVE_PTHREAD
1091    pthread_rwlock_wrlock(&_ecore_thread_global_hash_lock);
1092    if (!_ecore_thread_global_hash)
1093      _ecore_thread_global_hash = eina_hash_string_small_new(_ecore_thread_data_free);
1094    pthread_rwlock_unlock(&_ecore_thread_global_hash_lock);
1095
1096    if (!(d = malloc(sizeof(Ecore_Thread_Data))))
1097      return EINA_FALSE;
1098
1099    d->data = value;
1100    d->cb = cb;
1101
1102    if (!_ecore_thread_global_hash)
1103      return EINA_FALSE;
1104    pthread_rwlock_wrlock(&_ecore_thread_global_hash_lock);
1105    if (direct)
1106      ret = eina_hash_direct_add(_ecore_thread_global_hash, key, d);
1107    else
1108      ret = eina_hash_add(_ecore_thread_global_hash, key, d);
1109    pthread_rwlock_unlock(&_ecore_thread_global_hash_lock);
1110    pthread_cond_broadcast(&_ecore_thread_global_hash_cond);
1111    return ret;
1112 #else
1113    return EINA_TRUE;
1114 #endif
1115 }
1116
1117 /**
1118  * @brief Add data to the global data
1119  * @param key The name string to add the data with
1120  * @param value The data to add
1121  * @param cb The optional callback to free the data with once ecore is shut down
1122  * @return An Ecore_Thread_Data on success, NULL on failure
1123  * This adds data to the global thread data and returns NULL, or replaces the previous data
1124  * associated with @p key and returning the previous data if it existed.  To see if an error occurred,
1125  * one must use eina_error_get.
1126  * All data added to global can be manually freed, or a callback can be provided with @p cb which will
1127  * be called upon ecore_thread shutting down.  Note that if you have manually freed data that a callback
1128  * was specified for, you will most likely encounter a segv later on.
1129  */
1130 EAPI void *
1131 ecore_thread_global_data_set(const char *key, void *value, Eina_Free_Cb cb)
1132 {
1133    Ecore_Thread_Data *d, *r;
1134    void *ret;
1135
1136    if ((!key) || (!value))
1137      return NULL;
1138 #ifdef EFL_HAVE_PTHREAD
1139    pthread_rwlock_wrlock(&_ecore_thread_global_hash_lock);
1140    if (!_ecore_thread_global_hash)
1141      _ecore_thread_global_hash = eina_hash_string_small_new(_ecore_thread_data_free);
1142    pthread_rwlock_unlock(&_ecore_thread_global_hash_lock);
1143
1144    if (!_ecore_thread_global_hash)
1145      return NULL;
1146
1147    if (!(d = malloc(sizeof(Ecore_Thread_Data))))
1148      return NULL;
1149
1150    d->data = value;
1151    d->cb = cb;
1152
1153    pthread_rwlock_wrlock(&_ecore_thread_global_hash_lock);
1154    r = eina_hash_set(_ecore_thread_global_hash, key, d);
1155    pthread_rwlock_unlock(&_ecore_thread_global_hash_lock);
1156    pthread_cond_broadcast(&_ecore_thread_global_hash_cond);
1157
1158    ret = r->data;
1159    free(r);
1160    return ret;
1161 #else
1162    return NULL;
1163 #endif
1164 }
1165
1166 /**
1167  * @brief Find data in the global data
1168  * @param key The name string the data is associated with
1169  * @return The value, or NULL on error
1170  * This finds data in the global data that has been previously added with @ref ecore_thread_global_data_add
1171  * This function will return NULL in any case but success.
1172  * All data added to global can be manually freed, or a callback can be provided with @p cb which will
1173  * be called upon ecore_thread shutting down.  Note that if you have manually freed data that a callback
1174  * was specified for, you will most likely encounter a segv later on.
1175  * @note Keep in mind that the data returned can be used by multiple threads at a time, so you will most likely want to mutex
1176  * if you will be doing anything with it.
1177  */
1178
1179 EAPI void *
1180 ecore_thread_global_data_find(const char *key)
1181 {
1182    Ecore_Thread_Data *ret;
1183    if (!key)
1184      return NULL;
1185 #ifdef EFL_HAVE_PTHREAD
1186    if (!_ecore_thread_global_hash) return NULL;
1187
1188    pthread_rwlock_rdlock(&_ecore_thread_global_hash_lock);
1189    ret = eina_hash_find(_ecore_thread_global_hash, key);
1190    pthread_rwlock_unlock(&_ecore_thread_global_hash_lock);
1191    return ret->data;
1192 #else
1193    return NULL;
1194 #endif
1195 }
1196
1197 /**
1198  * @brief Delete data from the global data
1199  * @param key The name string the data is associated with
1200  * @return EINA_TRUE on success, EINA_FALSE on failure
1201  * This deletes the data pointer from the global data which was previously added with @ref ecore_thread_global_data_add
1202  * This function will return EINA_FALSE in any case but success.
1203  * Note that this WILL free the data if an @c Eina_Free_Cb was specified when the data was added.
1204  */
1205 EAPI Eina_Bool
1206 ecore_thread_global_data_del(const char *key)
1207 {
1208    Eina_Bool ret;
1209    Ecore_Thread_Data *d;
1210
1211    if (!key)
1212      return EINA_FALSE;
1213 #ifdef EFL_HAVE_PTHREAD
1214    if (!_ecore_thread_global_hash)
1215      return EINA_FALSE;
1216
1217    pthread_rwlock_wrlock(&_ecore_thread_global_hash_lock);
1218    if ((d = eina_hash_find(_ecore_thread_global_hash, key)))
1219      _ecore_thread_data_free(d);
1220    ret = eina_hash_del_by_key(_ecore_thread_global_hash, key);
1221    pthread_rwlock_unlock(&_ecore_thread_global_hash_lock);
1222    return ret;
1223 #else
1224    return EINA_TRUE;
1225 #endif
1226 }
1227
1228 /**
1229  * @brief Find data in the global data and optionally wait for the data if not found
1230  * @param key The name string the data is associated with
1231  * @param seconds The amount of time in seconds to wait for the data.  If 0, the call will be async and not wait for data.
1232  * If < 0 the call will wait indefinitely for the data.
1233  * @return The value, or NULL on failure
1234  * This finds data in the global data that has been previously added with @ref ecore_thread_global_data_add
1235  * This function will return NULL in any case but success.
1236  * Use @p seconds to specify the amount of time to wait.  Use > 0 for an actual wait time, 0 to not wait, and < 0 to wait indefinitely.
1237  * @note Keep in mind that the data returned can be used by multiple threads at a time, so you will most likely want to mutex
1238  * if you will be doing anything with it.
1239  */
1240 EAPI void *
1241 ecore_thread_global_data_wait(const char *key, double seconds)
1242 {
1243    double time = 0;
1244    Ecore_Thread_Data *ret = NULL;
1245    if (!key)
1246      return NULL;
1247 #ifdef EFL_HAVE_PTHREAD
1248    if (!_ecore_thread_global_hash)
1249      return NULL;
1250    if (seconds > 0)
1251      time = ecore_time_get() + seconds;
1252
1253    while (1)
1254      {
1255         struct timespec t = { 0, 0 };
1256
1257         t.tv_sec = (long int)time;
1258         t.tv_nsec = (long int)((time - (double)t.tv_sec) * 1000000000);
1259         pthread_rwlock_rdlock(&_ecore_thread_global_hash_lock);
1260         ret = eina_hash_find(_ecore_thread_global_hash, key);
1261         pthread_rwlock_unlock(&_ecore_thread_global_hash_lock);
1262         if ((ret) || (!seconds) || ((seconds > 0) && (time <= ecore_time_get())))
1263           break;
1264         pthread_mutex_lock(&_ecore_thread_global_hash_mutex);
1265         pthread_cond_timedwait(&_ecore_thread_global_hash_cond, &_ecore_thread_global_hash_mutex, &t);
1266         pthread_mutex_unlock(&_ecore_thread_global_hash_mutex);
1267      }
1268    if (ret) return ret->data;
1269    return NULL;
1270 #else
1271    return NULL;
1272 #endif
1273 }
1274
1275 /**
1276  * @}
1277  */