actually revert that - not enough testing. need to work on it.

SVN revision: 52029
This commit is contained in:
Carsten Haitzler 2010-09-09 06:36:01 +00:00
parent 4975395633
commit 679d566fde
3 changed files with 84 additions and 71 deletions

View File

@ -15,6 +15,8 @@
#include "Evas.h" #include "Evas.h"
#ifdef BUILD_ASYNC_PRELOAD #ifdef BUILD_ASYNC_PRELOAD
typedef struct _Evas_Preload_Pthread_Worker Evas_Preload_Pthread_Worker;
typedef struct _Evas_Preload_Pthread_Data Evas_Preload_Pthread_Data;
typedef void (*_evas_preload_pthread_func)(void *data); typedef void (*_evas_preload_pthread_func)(void *data);
@ -24,7 +26,7 @@ struct _Evas_Preload_Pthread_Worker
_evas_preload_pthread_func func_end; _evas_preload_pthread_func func_end;
_evas_preload_pthread_func func_cancel; _evas_preload_pthread_func func_cancel;
void *data; const void *data;
Eina_Bool cancel : 1; Eina_Bool cancel : 1;
}; };
@ -39,22 +41,18 @@ static int _evas_preload_thread_count_max = 0;
#ifdef BUILD_ASYNC_PRELOAD #ifdef BUILD_ASYNC_PRELOAD
static int _evas_preload_thread_count = 0; static int _evas_preload_thread_count = 0;
static Eina_List *_evas_preload_thread_workers = NULL; static Eina_List *_evas_preload_thread_data = NULL;
static Eina_List *_evas_preload_thread = NULL; static Eina_List *_evas_preload_thread = NULL;
static LK(_mutex) = PTHREAD_MUTEX_INITIALIZER; static LK(_mutex) = PTHREAD_MUTEX_INITIALIZER;
static void static void
_evas_preload_thread_end(void *data) _evas_preload_thread_end(Evas_Preload_Pthread_Data *pth)
{ {
Evas_Preload_Pthread_Data *pth = data;
Evas_Preload_Pthread_Data *p; Evas_Preload_Pthread_Data *p;
if (pthread_join(pth->thread, (void **)&p) != 0) if (pthread_join(pth->thread, (void **) &p) != 0)
{ return ;
free(p);
return;
}
_evas_preload_thread = eina_list_remove(_evas_preload_thread, pth); _evas_preload_thread = eina_list_remove(_evas_preload_thread, pth);
} }
@ -68,47 +66,49 @@ _evas_preload_thread_done(void *target __UNUSED__, Evas_Callback_Type type __UNU
if (work->cancel) if (work->cancel)
{ {
if (work->func_cancel) work->func_cancel(work->data); if (work->func_cancel)
work->func_cancel((void *) work->data);
} }
else else
{ {
work->func_end(work->data); work->func_end((void *) work->data);
} }
free(work); free(work);
} }
static void * static void *
_evas_preload_thread_worker(void *data) _evas_preload_thread_worker(Evas_Preload_Pthread_Data *pth)
{ {
Evas_Preload_Pthread_Data *pth = data;
Evas_Preload_Pthread_Worker *work; Evas_Preload_Pthread_Worker *work;
pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL); pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL); pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL);
on_error: on_error:
for (;;) while (_evas_preload_thread_data)
{ {
LKL(_mutex); LKL(_mutex);
if (!_evas_preload_thread_workers) if (!_evas_preload_thread_data)
{ {
LKU(_mutex); LKU(_mutex);
break; break;
} }
work = eina_list_data_get(_evas_preload_thread_workers); work = eina_list_data_get(_evas_preload_thread_data);
_evas_preload_thread_workers = eina_list_remove_list _evas_preload_thread_data = eina_list_remove_list(_evas_preload_thread_data, _evas_preload_thread_data);
(_evas_preload_thread_workers, _evas_preload_thread_workers);
LKU(_mutex); LKU(_mutex);
work->func_heavy(work->data);
work->func_heavy((void *) work->data);
evas_async_events_put(pth, 0, work, _evas_preload_thread_done); evas_async_events_put(pth, 0, work, _evas_preload_thread_done);
} }
LKL(_mutex); LKL(_mutex);
if (_evas_preload_thread_workers) if (_evas_preload_thread_data)
{ {
LKU(_mutex); LKU(_mutex);
goto on_error; goto on_error;
@ -116,6 +116,18 @@ on_error:
_evas_preload_thread_count--; _evas_preload_thread_count--;
LKU(_mutex); LKU(_mutex);
work = malloc(sizeof (Evas_Preload_Pthread_Worker));
if (!work) return NULL;
work->data = pth;
work->func_heavy = NULL;
work->func_end = (_evas_preload_pthread_func) _evas_preload_thread_end;
work->func_cancel = NULL;
work->cancel = EINA_FALSE;
evas_async_events_put(pth, 0, work, _evas_preload_thread_done);
return pth; return pth;
} }
#endif #endif
@ -125,7 +137,7 @@ _evas_preload_thread_init(void)
{ {
_evas_preload_thread_count_max = eina_cpu_count(); _evas_preload_thread_count_max = eina_cpu_count();
if (_evas_preload_thread_count_max <= 0) if (_evas_preload_thread_count_max <= 0)
_evas_preload_thread_count_max = 1; _evas_preload_thread_count_max = 1;
} }
void void
@ -141,26 +153,26 @@ _evas_preload_thread_shutdown(void)
LKL(_mutex); LKL(_mutex);
EINA_LIST_FREE(_evas_preload_thread_workers, work) EINA_LIST_FREE(_evas_preload_thread_data, work)
{ {
if (work->func_cancel) work->func_cancel(work->data); if (work->func_cancel)
work->func_cancel((void *)work->data);
free(work); free(work);
} }
LKU(_mutex); LKU(_mutex);
EINA_LIST_FREE(_evas_preload_thread, pth) EINA_LIST_FREE(_evas_preload_thread, pth)
{ {
Evas_Preload_Pthread_Data *p; Evas_Preload_Pthread_Data *p;
pthread_cancel(pth->thread); pthread_cancel(pth->thread);
pthread_join(pth->thread, (void **)&p); pthread_join(pth->thread, (void **) &p);
free(p);
} }
#endif #endif
} }
Evas_Preload_Pthread_Worker * Evas_Preload_Pthread *
evas_preload_thread_run(void (*func_heavy) (void *data), evas_preload_thread_run(void (*func_heavy) (void *data),
void (*func_end) (void *data), void (*func_end) (void *data),
void (*func_cancel) (void *data), void (*func_cancel) (void *data),
@ -170,7 +182,7 @@ evas_preload_thread_run(void (*func_heavy) (void *data),
Evas_Preload_Pthread_Worker *work; Evas_Preload_Pthread_Worker *work;
Evas_Preload_Pthread_Data *pth; Evas_Preload_Pthread_Data *pth;
work = malloc(sizeof(Evas_Preload_Pthread_Worker)); work = malloc(sizeof (Evas_Preload_Pthread_Worker));
if (!work) if (!work)
{ {
func_cancel((void *)data); func_cancel((void *)data);
@ -181,25 +193,25 @@ evas_preload_thread_run(void (*func_heavy) (void *data),
work->func_end = func_end; work->func_end = func_end;
work->func_cancel = func_cancel; work->func_cancel = func_cancel;
work->cancel = EINA_FALSE; work->cancel = EINA_FALSE;
work->data = (void *)data; work->data = data;
LKL(_mutex); LKL(_mutex);
_evas_preload_thread_workers = eina_list_append _evas_preload_thread_data = eina_list_append(_evas_preload_thread_data, work);
(_evas_preload_thread_workers, work);
if (_evas_preload_thread_count == _evas_preload_thread_count_max) if (_evas_preload_thread_count == _evas_preload_thread_count_max)
{ {
LKU(_mutex); pthread_mutex_unlock(&_mutex);
return work; return (Evas_Preload_Pthread*) work;
} }
LKU(_mutex); LKU(_mutex);
/* One more thread could be created. */ /* One more thread could be created. */
pth = malloc(sizeof(Evas_Preload_Pthread_Data)); pth = malloc(sizeof (Evas_Preload_Pthread_Data));
if (!pth) goto on_error; if (!pth)
goto on_error;
if (!pthread_create(&pth->thread, NULL, _evas_preload_thread_worker, pth)) if (pthread_create(&pth->thread, NULL, (void *) _evas_preload_thread_worker, pth) == 0)
{ {
#ifdef __linux__ #ifdef __linux__
struct sched_param param; struct sched_param param;
@ -229,13 +241,14 @@ evas_preload_thread_run(void (*func_heavy) (void *data),
LKL(_mutex); LKL(_mutex);
_evas_preload_thread_count++; _evas_preload_thread_count++;
LKU(_mutex); LKU(_mutex);
return work; return (Evas_Preload_Pthread*) work;
} }
on_error: on_error:
if (_evas_preload_thread_count == 0) if (_evas_preload_thread_count == 0)
{ {
if (work->func_cancel) work->func_cancel(work->data); if (work->func_cancel)
work->func_cancel((void *) work->data);
free(work); free(work);
} }
return NULL; return NULL;
@ -244,39 +257,41 @@ evas_preload_thread_run(void (*func_heavy) (void *data),
If no thread and as we don't want to break app that rely on this 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. facility, we will lock the interface until we are done.
*/ */
func_heavy(data); func_heavy((void *) data);
func_end(data); func_end((void *) data);
return NULL; return EINA_TRUE;
#endif #endif
} }
Eina_Bool Eina_Bool
evas_preload_thread_cancel(Evas_Preload_Pthread_Worker *wk) evas_preload_thread_cancel(Evas_Preload_Pthread *thread)
{ {
#ifdef BUILD_ASYNC_PRELOAD #ifdef BUILD_ASYNC_PRELOAD
Evas_Preload_Pthread_Worker *work; Evas_Preload_Pthread_Worker *work;
Eina_List *l; Eina_List *l;
if (!wk) return EINA_TRUE;
LKL(_mutex); LKL(_mutex);
EINA_LIST_FOREACH(_evas_preload_thread_workers, l, work)
{
if (work != wk) continue;
_evas_preload_thread_workers = eina_list_remove_list EINA_LIST_FOREACH(_evas_preload_thread_data, l, work)
(_evas_preload_thread_workers, l); if ((void *) work == (void *) thread)
LKU(_mutex); {
if (work->func_cancel) work->func_cancel(work->data); _evas_preload_thread_data = eina_list_remove_list(_evas_preload_thread_data, l);
free(work);
return EINA_TRUE; LKU(_mutex);
}
if (work->func_cancel)
work->func_cancel((void *) work->data);
free(work);
return EINA_TRUE;
}
LKU(_mutex); LKU(_mutex);
/* Delay the destruction */ /* Delay the destruction */
wk->cancel = EINA_TRUE; work = (Evas_Preload_Pthread_Worker *) thread;
work->cancel = EINA_TRUE;
return EINA_FALSE; return EINA_FALSE;
#else #else
return EINA_TRUE; return EINA_TRUE;

View File

@ -374,8 +374,7 @@ typedef struct _Image_Entry Image_Entry;
typedef struct _Image_Entry_Flags Image_Entry_Flags; typedef struct _Image_Entry_Flags Image_Entry_Flags;
typedef struct _Engine_Image_Entry Engine_Image_Entry; typedef struct _Engine_Image_Entry Engine_Image_Entry;
typedef struct _Evas_Cache_Target Evas_Cache_Target; typedef struct _Evas_Cache_Target Evas_Cache_Target;
typedef struct _Evas_Preload_Pthread_Worker Evas_Preload_Pthread_Worker; typedef struct _Evas_Preload_Pthread Evas_Preload_Pthread;
typedef struct _Evas_Preload_Pthread_Data Evas_Preload_Pthread_Data;
typedef struct _RGBA_Image_Loadopts RGBA_Image_Loadopts; typedef struct _RGBA_Image_Loadopts RGBA_Image_Loadopts;
#ifdef BUILD_PIPE_RENDER #ifdef BUILD_PIPE_RENDER
@ -530,8 +529,8 @@ struct _Image_Entry
const char *file; const char *file;
const char *key; const char *key;
Evas_Cache_Target *targets; Evas_Cache_Target *targets;
Evas_Preload_Pthread_Worker *preload; Evas_Preload_Pthread *preload;
time_t timestamp; time_t timestamp;
time_t laststat; time_t laststat;

View File

@ -801,12 +801,11 @@ int evas_async_target_del(const void *target);
void _evas_preload_thread_init(void); void _evas_preload_thread_init(void);
void _evas_preload_thread_shutdown(void); void _evas_preload_thread_shutdown(void);
Evas_Preload_Pthread_Worker *evas_preload_thread_run Evas_Preload_Pthread *evas_preload_thread_run(void (*func_heavy)(void *data),
(void (*func_heavy)(void *data), void (*func_end)(void *data),
void (*func_end)(void *data), void (*func_cancel)(void *data),
void (*func_cancel)(void *data), const void *data);
const void *data); Eina_Bool evas_preload_thread_cancel(Evas_Preload_Pthread *thread);
Eina_Bool evas_preload_thread_cancel(Evas_Preload_Pthread_Worker *thread);
void _evas_walk(Evas *e); void _evas_walk(Evas *e);
void _evas_unwalk(Evas *e); void _evas_unwalk(Evas *e);