and fix async load thing hanging around... put in shared queue and be able to

remove targets from the queue.



SVN revision: 42754
This commit is contained in:
Carsten Haitzler 2009-09-28 03:51:21 +00:00
parent 449bdb7bc6
commit 526b6e8f3b
4 changed files with 127 additions and 62 deletions

View File

@ -329,9 +329,6 @@ _evas_cache_image_async_call__locked(Image_Entry *im)
{ {
Evas_Cache_Target *tmp = im->targets; Evas_Cache_Target *tmp = im->targets;
// FIXME: bug bug bug bug. hrrrm.
// FIXME: this is a little bad if obj gets deleted before preload
// async event comes in... boom!
evas_async_events_put(tmp->target, EVAS_CALLBACK_IMAGE_PRELOADED, NULL, evas_async_events_put(tmp->target, EVAS_CALLBACK_IMAGE_PRELOADED, NULL,
(void (*)(void*, Evas_Callback_Type, void*))evas_object_event_callback_call); (void (*)(void*, Evas_Callback_Type, void*))evas_object_event_callback_call);
im->targets = (Evas_Cache_Target*) eina_inlist_remove(EINA_INLIST_GET(im->targets), EINA_INLIST_GET(im->targets)); im->targets = (Evas_Cache_Target*) eina_inlist_remove(EINA_INLIST_GET(im->targets), EINA_INLIST_GET(im->targets));
@ -414,6 +411,7 @@ _evas_cache_image_entry_preload_remove(Image_Entry *ie, const void *target)
if (running) if (running)
{ {
pthread_mutex_lock(&mutex); pthread_mutex_lock(&mutex);
if (target) evas_async_target_del(target);
if (ie->flags.preload) if (ie->flags.preload)
{ {
if (current == ie) if (current == ie)
@ -425,6 +423,7 @@ _evas_cache_image_entry_preload_remove(Image_Entry *ie, const void *target)
else else
{ {
Evas_Cache_Preload *l; Evas_Cache_Preload *l;
EINA_INLIST_FOREACH(preload, l) EINA_INLIST_FOREACH(preload, l)
{ {
if (l->ie == ie) if (l->ie == ie)
@ -450,6 +449,7 @@ _evas_cache_image_entry_preload_remove(Image_Entry *ie, const void *target)
while (ie->targets) while (ie->targets)
{ {
tg = ie->targets; tg = ie->targets;
evas_async_target_del(tg->target);
ie->targets = (Evas_Cache_Target*) eina_inlist_remove(EINA_INLIST_GET(ie->targets), EINA_INLIST_GET(tg)); ie->targets = (Evas_Cache_Target*) eina_inlist_remove(EINA_INLIST_GET(ie->targets), EINA_INLIST_GET(tg));
free(tg); free(tg);
} }

View File

@ -15,6 +15,7 @@ static int _init_evas_event = 0;
static pthread_mutex_t _mutex = PTHREAD_MUTEX_INITIALIZER; static pthread_mutex_t _mutex = PTHREAD_MUTEX_INITIALIZER;
typedef struct _Evas_Event_Async Evas_Event_Async; typedef struct _Evas_Event_Async Evas_Event_Async;
struct _Evas_Event_Async struct _Evas_Event_Async
{ {
const void *target; const void *target;
@ -23,25 +24,29 @@ struct _Evas_Event_Async
Evas_Callback_Type type; Evas_Callback_Type type;
}; };
static int queue_num = 0;
static int queue_alloc = 0;
static Evas_Event_Async *queue = NULL;
int int
evas_async_events_init(void) evas_async_events_init(void)
{ {
int filedes[2]; int filedes[2];
_init_evas_event++; _init_evas_event++;
if (_init_evas_event > 1) return _init_evas_event; if (_init_evas_event > 1) return _init_evas_event;
if (pipe(filedes) == -1) if (pipe(filedes) == -1)
{ {
_init_evas_event = 0; _init_evas_event = 0;
return 0; return 0;
} }
_fd_read = filedes[0]; _fd_read = filedes[0];
_fd_write = filedes[1]; _fd_write = filedes[1];
fcntl(_fd_read, F_SETFL, O_NONBLOCK); fcntl(_fd_read, F_SETFL, O_NONBLOCK);
return _init_evas_event; return _init_evas_event;
} }
@ -50,7 +55,7 @@ evas_async_events_shutdown(void)
{ {
_init_evas_event--; _init_evas_event--;
if (_init_evas_event > 0) return _init_evas_event; if (_init_evas_event > 0) return _init_evas_event;
close(_fd_read); close(_fd_read);
close(_fd_write); close(_fd_write);
_fd_read = -1; _fd_read = -1;
@ -59,6 +64,36 @@ evas_async_events_shutdown(void)
return _init_evas_event; return _init_evas_event;
} }
int
evas_async_target_del(const void *target)
{
int i, j, d = 0;
pthread_mutex_lock(&_mutex);
if (queue)
{
for (i = 0; i < queue_num; i++)
{
if (queue[i].target == target)
{
for (j = i + 1; j < queue_num; j++)
memcpy(&(queue[j - 1]), &(queue[j]), sizeof(Evas_Event_Async));
i--;
queue_num--;
d++;
}
}
if (queue_num == 0)
{
free(queue);
queue = NULL;
queue_alloc = 0;
}
}
pthread_mutex_unlock(&_mutex);
return d;
}
#endif #endif
/** /**
@ -109,40 +144,46 @@ EAPI int
evas_async_events_process(void) evas_async_events_process(void)
{ {
#ifdef BUILD_ASYNC_EVENTS #ifdef BUILD_ASYNC_EVENTS
static Evas_Event_Async current; Evas_Event_Async *ev;
static int size = 0; unsigned char buf[1];
int i;
int check; int check;
int count = 0; int count = 0;
if (_fd_read == -1) return 0; if (_fd_read == -1) return 0;
pthread_mutex_lock(&_mutex);
do do
{ {
check = read(_fd_read, ((char*) &current) + size, sizeof(current) - size); check = read(_fd_read, buf, 1);
if (check > 0)
{
size += check;
if (size == sizeof(current))
{
if (current.func) current.func((void*) current.target, current.type, current.event_info);
size = 0;
count++;
}
}
} }
while (check > 0); while (check > 0);
if (queue)
{
for (i = 0; i < queue_num; i++)
{
ev = &(queue[i]);
if (ev->func) ev->func((void *)ev->target, ev->type, ev->event_info);
count++;
}
free(queue);
queue = NULL;
queue_num = 0;
queue_alloc = 0;
}
pthread_mutex_unlock(&_mutex);
if (check < 0) if (check < 0)
switch (errno) switch (errno)
{ {
case EBADF: case EBADF:
case EINVAL: case EINVAL:
case EIO: case EIO:
case EISDIR: case EISDIR:
_fd_read = -1; _fd_read = -1;
} }
evas_cache_pending_process(); evas_cache_pending_process();
return count; return count;
#else #else
@ -151,7 +192,7 @@ evas_async_events_process(void)
} }
/** /**
* Insert asynchronous events on the canvas. * Insert asynchronous events on the canvas.
* *
* @param target The target to be affected by the events. * @param target The target to be affected by the events.
* @param type The type of callback function. * @param type The type of callback function.
@ -168,46 +209,59 @@ EAPI Eina_Bool
evas_async_events_put(const void *target, Evas_Callback_Type type, void *event_info, void (*func)(void *target, Evas_Callback_Type type, void *event_info)) evas_async_events_put(const void *target, Evas_Callback_Type type, void *event_info, void (*func)(void *target, Evas_Callback_Type type, void *event_info))
{ {
#ifdef BUILD_ASYNC_EVENTS #ifdef BUILD_ASYNC_EVENTS
Evas_Event_Async new; Evas_Event_Async *ev;
ssize_t check; ssize_t check;
int offset = 0;
Eina_Bool result = EINA_FALSE; Eina_Bool result = EINA_FALSE;
if (!func) return 0; if (!func) return 0;
if (_fd_write == -1) return 0; if (_fd_write == -1) return 0;
memset(&new, 0, sizeof (new));
new.func = func;
new.target = target;
new.type = type;
new.event_info = event_info;
pthread_mutex_lock(&_mutex); pthread_mutex_lock(&_mutex);
queue_num++;
if (queue_num > queue_alloc)
{
Evas_Event_Async *q2;
queue_alloc += 32; // 32 slots at a time for async events
q2 = realloc(queue, queue_alloc * sizeof(Evas_Event_Async));
if (!q2)
{
queue_alloc -= 32;
queue_num--;
return 0;
}
queue = q2;
}
ev = &(queue[queue_num - 1]);
memset(ev, 0, sizeof(Evas_Event_Async));
ev->func = func;
ev->target = target;
ev->type = type;
ev->event_info = event_info;
do { do
check = write(_fd_write, ((char*)&new) + offset, sizeof(new) - offset); {
offset += check; unsigned char buf[1] = { 0xf0 };
} while (offset != sizeof(new) && (errno == EINTR || errno == EAGAIN)); check = write(_fd_write, buf, 1);
} while ((check != 1) && ((errno == EINTR) || (errno == EAGAIN)));
if (offset == sizeof(new)) if (check == 1)
result = EINA_TRUE; result = EINA_TRUE;
else else
switch (errno) switch (errno)
{ {
case EBADF: case EBADF:
case EINVAL: case EINVAL:
case EIO: case EIO:
case EPIPE: case EPIPE:
_fd_write = -1; _fd_write = -1;
} }
pthread_mutex_unlock(&_mutex); pthread_mutex_unlock(&_mutex);
return result; return result;
#else #else
func(target, type, event_info); func(target, type, event_info);
return EINA_TRUE; return EINA_TRUE;
#endif #endif
} }

View File

@ -297,8 +297,13 @@ evas_object_image_file_set(Evas_Object *obj, const char *file, const char *key)
o->prev.file = NULL; o->prev.file = NULL;
o->prev.key = NULL; o->prev.key = NULL;
if (o->engine_data) if (o->engine_data)
obj->layer->evas->engine.func->image_free(obj->layer->evas->engine.data.output, {
o->engine_data); obj->layer->evas->engine.func->image_data_preload_cancel(obj->layer->evas->engine.data.output,
o->engine_data,
obj);
obj->layer->evas->engine.func->image_free(obj->layer->evas->engine.data.output,
o->engine_data);
}
o->load_error = EVAS_LOAD_ERROR_NONE; o->load_error = EVAS_LOAD_ERROR_NONE;
lo.scale_down_by = o->load_opts.scale_down_by; lo.scale_down_by = o->load_opts.scale_down_by;
lo.dpi = o->load_opts.dpi; lo.dpi = o->load_opts.dpi;
@ -710,7 +715,7 @@ evas_object_image_fill_spread_get(const Evas_Object *obj)
} }
EAPI void EAPI void
evas_object_image_fill_transform_set (Evas_Object *obj, Evas_Transform *t) evas_object_image_fill_transform_set(Evas_Object *obj, Evas_Transform *t)
{ {
Evas_Object_Image *o; Evas_Object_Image *o;
@ -764,7 +769,7 @@ evas_object_image_fill_transform_set (Evas_Object *obj, Evas_Transform *t)
/*FIXME: To be documented*/ /*FIXME: To be documented*/
EAPI void EAPI void
evas_object_image_fill_transform_get (const Evas_Object *obj, Evas_Transform *t) evas_object_image_fill_transform_get(const Evas_Object *obj, Evas_Transform *t)
{ {
Evas_Object_Image *o; Evas_Object_Image *o;
@ -2261,8 +2266,13 @@ evas_object_image_free(Evas_Object *obj)
if (o->cur.file) eina_stringshare_del(o->cur.file); if (o->cur.file) eina_stringshare_del(o->cur.file);
if (o->cur.key) eina_stringshare_del(o->cur.key); if (o->cur.key) eina_stringshare_del(o->cur.key);
if (o->engine_data) if (o->engine_data)
obj->layer->evas->engine.func->image_free(obj->layer->evas->engine.data.output, {
o->engine_data); obj->layer->evas->engine.func->image_data_preload_cancel(obj->layer->evas->engine.data.output,
o->engine_data,
obj);
obj->layer->evas->engine.func->image_free(obj->layer->evas->engine.data.output,
o->engine_data);
}
o->engine_data = NULL; o->engine_data = NULL;
o->magic = 0; o->magic = 0;
EINA_LIST_FREE(o->pixel_updates, r) EINA_LIST_FREE(o->pixel_updates, r)

View File

@ -789,7 +789,8 @@ struct _Evas_Imaging_Font
int evas_async_events_init(void); int evas_async_events_init(void);
int evas_async_events_shutdown(void); int evas_async_events_shutdown(void);
int evas_async_target_del(const void *target);
void _evas_walk(Evas *e); void _evas_walk(Evas *e);
void _evas_unwalk(Evas *e); void _evas_unwalk(Evas *e);