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