forked from enlightenment/efl
lots of cleanups... actually tested! :)
SVN revision: 52030
This commit is contained in:
parent
679d566fde
commit
c4ee82f6a7
|
@ -14,7 +14,10 @@
|
|||
#include "evas_private.h"
|
||||
#include "Evas.h"
|
||||
|
||||
static int _threads_max = 0;
|
||||
|
||||
#ifdef BUILD_ASYNC_PRELOAD
|
||||
|
||||
typedef struct _Evas_Preload_Pthread_Worker Evas_Preload_Pthread_Worker;
|
||||
typedef struct _Evas_Preload_Pthread_Data Evas_Preload_Pthread_Data;
|
||||
|
||||
|
@ -25,9 +28,7 @@ struct _Evas_Preload_Pthread_Worker
|
|||
_evas_preload_pthread_func func_heavy;
|
||||
_evas_preload_pthread_func func_end;
|
||||
_evas_preload_pthread_func func_cancel;
|
||||
|
||||
const void *data;
|
||||
|
||||
void *data;
|
||||
Eina_Bool cancel : 1;
|
||||
};
|
||||
|
||||
|
@ -35,89 +36,73 @@ struct _Evas_Preload_Pthread_Data
|
|||
{
|
||||
pthread_t thread;
|
||||
};
|
||||
#endif
|
||||
|
||||
static int _evas_preload_thread_count_max = 0;
|
||||
|
||||
#ifdef BUILD_ASYNC_PRELOAD
|
||||
static int _evas_preload_thread_count = 0;
|
||||
static Eina_List *_evas_preload_thread_data = NULL;
|
||||
static Eina_List *_evas_preload_thread = NULL;
|
||||
static int _threads_count = 0;
|
||||
static Eina_List *_workers = NULL;
|
||||
|
||||
static LK(_mutex) = PTHREAD_MUTEX_INITIALIZER;
|
||||
|
||||
static void
|
||||
_evas_preload_thread_end(Evas_Preload_Pthread_Data *pth)
|
||||
_evas_preload_thread_end(void *data)
|
||||
{
|
||||
Evas_Preload_Pthread_Data *p;
|
||||
Evas_Preload_Pthread_Data *pth = data;
|
||||
Evas_Preload_Pthread_Data *p = NULL;
|
||||
|
||||
if (pthread_join(pth->thread, (void **) &p) != 0)
|
||||
return ;
|
||||
|
||||
_evas_preload_thread = eina_list_remove(_evas_preload_thread, pth);
|
||||
if (pthread_join(pth->thread, (void **)&p) != 0) free(p);
|
||||
}
|
||||
|
||||
static void
|
||||
_evas_preload_thread_done(void *target __UNUSED__, Evas_Callback_Type type __UNUSED__, void *event_info)
|
||||
{
|
||||
Evas_Preload_Pthread_Worker *work;
|
||||
|
||||
work = event_info;
|
||||
|
||||
Evas_Preload_Pthread_Worker *work = event_info;
|
||||
if (work->cancel)
|
||||
{
|
||||
if (work->func_cancel)
|
||||
work->func_cancel((void *) work->data);
|
||||
if (work->func_cancel) work->func_cancel(work->data);
|
||||
}
|
||||
else
|
||||
{
|
||||
work->func_end((void *) work->data);
|
||||
}
|
||||
|
||||
work->func_end(work->data);
|
||||
free(work);
|
||||
}
|
||||
|
||||
static void *
|
||||
_evas_preload_thread_worker(Evas_Preload_Pthread_Data *pth)
|
||||
_evas_preload_thread_worker(void *data)
|
||||
{
|
||||
Evas_Preload_Pthread_Data *pth = data;
|
||||
Evas_Preload_Pthread_Worker *work;
|
||||
|
||||
|
||||
pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
|
||||
pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL);
|
||||
|
||||
on_error:
|
||||
|
||||
while (_evas_preload_thread_data)
|
||||
on_error:
|
||||
for (;;)
|
||||
{
|
||||
LKL(_mutex);
|
||||
|
||||
if (!_evas_preload_thread_data)
|
||||
if (!_workers)
|
||||
{
|
||||
LKU(_mutex);
|
||||
break;
|
||||
}
|
||||
|
||||
work = eina_list_data_get(_evas_preload_thread_data);
|
||||
_evas_preload_thread_data = eina_list_remove_list(_evas_preload_thread_data, _evas_preload_thread_data);
|
||||
work = eina_list_data_get(_workers);
|
||||
_workers = eina_list_remove_list(_workers, _workers);
|
||||
|
||||
LKU(_mutex);
|
||||
|
||||
work->func_heavy((void *) work->data);
|
||||
|
||||
if (work->func_heavy) work->func_heavy(work->data);
|
||||
evas_async_events_put(pth, 0, work, _evas_preload_thread_done);
|
||||
}
|
||||
|
||||
LKL(_mutex);
|
||||
if (_evas_preload_thread_data)
|
||||
if (_workers)
|
||||
{
|
||||
LKU(_mutex);
|
||||
goto on_error;
|
||||
}
|
||||
_evas_preload_thread_count--;
|
||||
_threads_count--;
|
||||
|
||||
LKU(_mutex);
|
||||
|
||||
work = malloc(sizeof (Evas_Preload_Pthread_Worker));
|
||||
// dummy worker to wake things up
|
||||
work = malloc(sizeof(Evas_Preload_Pthread_Worker));
|
||||
if (!work) return NULL;
|
||||
|
||||
work->data = pth;
|
||||
|
@ -135,9 +120,8 @@ _evas_preload_thread_worker(Evas_Preload_Pthread_Data *pth)
|
|||
void
|
||||
_evas_preload_thread_init(void)
|
||||
{
|
||||
_evas_preload_thread_count_max = eina_cpu_count();
|
||||
if (_evas_preload_thread_count_max <= 0)
|
||||
_evas_preload_thread_count_max = 1;
|
||||
_threads_max = eina_cpu_count();
|
||||
if (_threads_max <= 0) _threads_max = 1;
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -153,22 +137,13 @@ _evas_preload_thread_shutdown(void)
|
|||
|
||||
LKL(_mutex);
|
||||
|
||||
EINA_LIST_FREE(_evas_preload_thread_data, work)
|
||||
EINA_LIST_FREE(_workers, work)
|
||||
{
|
||||
if (work->func_cancel)
|
||||
work->func_cancel((void *)work->data);
|
||||
if (work->func_cancel) work->func_cancel(work->data);
|
||||
free(work);
|
||||
}
|
||||
|
||||
|
||||
LKU(_mutex);
|
||||
|
||||
EINA_LIST_FREE(_evas_preload_thread, pth)
|
||||
{
|
||||
Evas_Preload_Pthread_Data *p;
|
||||
|
||||
pthread_cancel(pth->thread);
|
||||
pthread_join(pth->thread, (void **) &p);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -182,7 +157,7 @@ evas_preload_thread_run(void (*func_heavy) (void *data),
|
|||
Evas_Preload_Pthread_Worker *work;
|
||||
Evas_Preload_Pthread_Data *pth;
|
||||
|
||||
work = malloc(sizeof (Evas_Preload_Pthread_Worker));
|
||||
work = malloc(sizeof(Evas_Preload_Pthread_Worker));
|
||||
if (!work)
|
||||
{
|
||||
func_cancel((void *)data);
|
||||
|
@ -193,25 +168,24 @@ evas_preload_thread_run(void (*func_heavy) (void *data),
|
|||
work->func_end = func_end;
|
||||
work->func_cancel = func_cancel;
|
||||
work->cancel = EINA_FALSE;
|
||||
work->data = data;
|
||||
work->data = (void *)data;
|
||||
|
||||
LKL(_mutex);
|
||||
_evas_preload_thread_data = eina_list_append(_evas_preload_thread_data, work);
|
||||
_workers = eina_list_append(_workers, work);
|
||||
|
||||
if (_evas_preload_thread_count == _evas_preload_thread_count_max)
|
||||
if (_threads_count == _threads_max)
|
||||
{
|
||||
pthread_mutex_unlock(&_mutex);
|
||||
return (Evas_Preload_Pthread*) work;
|
||||
return (Evas_Preload_Pthread *)work;
|
||||
}
|
||||
|
||||
LKU(_mutex);
|
||||
|
||||
/* One more thread could be created. */
|
||||
pth = malloc(sizeof (Evas_Preload_Pthread_Data));
|
||||
if (!pth)
|
||||
goto on_error;
|
||||
|
||||
if (pthread_create(&pth->thread, NULL, (void *) _evas_preload_thread_worker, pth) == 0)
|
||||
pth = malloc(sizeof(Evas_Preload_Pthread_Data));
|
||||
if (!pth) goto on_error;
|
||||
|
||||
if (pthread_create(&pth->thread, NULL, _evas_preload_thread_worker, pth) == 0)
|
||||
{
|
||||
#ifdef __linux__
|
||||
struct sched_param param;
|
||||
|
@ -239,27 +213,25 @@ evas_preload_thread_run(void (*func_heavy) (void *data),
|
|||
#endif
|
||||
|
||||
LKL(_mutex);
|
||||
_evas_preload_thread_count++;
|
||||
_threads_count++;
|
||||
LKU(_mutex);
|
||||
return (Evas_Preload_Pthread*) work;
|
||||
return (Evas_Preload_Pthread*)work;
|
||||
}
|
||||
|
||||
on_error:
|
||||
if (_evas_preload_thread_count == 0)
|
||||
if (_threads_count == 0)
|
||||
{
|
||||
if (work->func_cancel)
|
||||
work->func_cancel((void *) work->data);
|
||||
if (work->func_cancel) work->func_cancel(work->data);
|
||||
free(work);
|
||||
}
|
||||
return NULL;
|
||||
#else
|
||||
/*
|
||||
If no thread and as we don't want to break app that rely on this
|
||||
facility, we will lock the interface until we are done.
|
||||
If no thread and as we don't want to break app that rely on this
|
||||
facility, we will lock the interface until we are done.
|
||||
*/
|
||||
func_heavy((void *) data);
|
||||
func_end((void *) data);
|
||||
|
||||
func_heavy((void *)data);
|
||||
func_end((void *)data);
|
||||
return EINA_TRUE;
|
||||
#endif
|
||||
}
|
||||
|
@ -272,25 +244,21 @@ evas_preload_thread_cancel(Evas_Preload_Pthread *thread)
|
|||
Eina_List *l;
|
||||
|
||||
LKL(_mutex);
|
||||
|
||||
EINA_LIST_FOREACH(_evas_preload_thread_data, l, work)
|
||||
if ((void *) work == (void *) thread)
|
||||
{
|
||||
_evas_preload_thread_data = eina_list_remove_list(_evas_preload_thread_data, l);
|
||||
|
||||
LKU(_mutex);
|
||||
|
||||
if (work->func_cancel)
|
||||
work->func_cancel((void *) work->data);
|
||||
free(work);
|
||||
|
||||
return EINA_TRUE;
|
||||
}
|
||||
|
||||
EINA_LIST_FOREACH(_workers, l, work)
|
||||
{
|
||||
if (work == (Evas_Preload_Pthread_Worker *)thread)
|
||||
{
|
||||
_workers = eina_list_remove_list(_workers, l);
|
||||
LKU(_mutex);
|
||||
if (work->func_cancel) work->func_cancel(work->data);
|
||||
free(work);
|
||||
return EINA_TRUE;
|
||||
}
|
||||
}
|
||||
LKU(_mutex);
|
||||
|
||||
|
||||
/* Delay the destruction */
|
||||
work = (Evas_Preload_Pthread_Worker *) thread;
|
||||
work = (Evas_Preload_Pthread_Worker *)thread;
|
||||
work->cancel = EINA_TRUE;
|
||||
return EINA_FALSE;
|
||||
#else
|
||||
|
|
Loading…
Reference in New Issue