diff --git a/legacy/evas/src/lib/cache/evas_cache_image.c b/legacy/evas/src/lib/cache/evas_cache_image.c index 66071463a9..71d26484f2 100644 --- a/legacy/evas/src/lib/cache/evas_cache_image.c +++ b/legacy/evas/src/lib/cache/evas_cache_image.c @@ -329,9 +329,6 @@ _evas_cache_image_async_call__locked(Image_Entry *im) { 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, (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)); @@ -414,6 +411,7 @@ _evas_cache_image_entry_preload_remove(Image_Entry *ie, const void *target) if (running) { pthread_mutex_lock(&mutex); + if (target) evas_async_target_del(target); if (ie->flags.preload) { if (current == ie) @@ -425,6 +423,7 @@ _evas_cache_image_entry_preload_remove(Image_Entry *ie, const void *target) else { Evas_Cache_Preload *l; + EINA_INLIST_FOREACH(preload, l) { if (l->ie == ie) @@ -450,6 +449,7 @@ _evas_cache_image_entry_preload_remove(Image_Entry *ie, const void *target) while (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)); free(tg); } diff --git a/legacy/evas/src/lib/canvas/evas_async_events.c b/legacy/evas/src/lib/canvas/evas_async_events.c index f4fecb645a..57555f426e 100644 --- a/legacy/evas/src/lib/canvas/evas_async_events.c +++ b/legacy/evas/src/lib/canvas/evas_async_events.c @@ -15,6 +15,7 @@ static int _init_evas_event = 0; static pthread_mutex_t _mutex = PTHREAD_MUTEX_INITIALIZER; typedef struct _Evas_Event_Async Evas_Event_Async; + struct _Evas_Event_Async { const void *target; @@ -23,25 +24,29 @@ struct _Evas_Event_Async Evas_Callback_Type type; }; +static int queue_num = 0; +static int queue_alloc = 0; +static Evas_Event_Async *queue = NULL; + int evas_async_events_init(void) { int filedes[2]; - + _init_evas_event++; if (_init_evas_event > 1) return _init_evas_event; - + if (pipe(filedes) == -1) { _init_evas_event = 0; return 0; } - + _fd_read = filedes[0]; _fd_write = filedes[1]; - + fcntl(_fd_read, F_SETFL, O_NONBLOCK); - + return _init_evas_event; } @@ -50,7 +55,7 @@ evas_async_events_shutdown(void) { _init_evas_event--; if (_init_evas_event > 0) return _init_evas_event; - + close(_fd_read); close(_fd_write); _fd_read = -1; @@ -59,6 +64,36 @@ evas_async_events_shutdown(void) 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 /** @@ -109,40 +144,46 @@ EAPI int evas_async_events_process(void) { #ifdef BUILD_ASYNC_EVENTS - static Evas_Event_Async current; - static int size = 0; + Evas_Event_Async *ev; + unsigned char buf[1]; + int i; int check; int count = 0; - + if (_fd_read == -1) return 0; - + + pthread_mutex_lock(&_mutex); do { - check = read(_fd_read, ((char*) ¤t) + size, sizeof(current) - size); - - 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++; - } - } + check = read(_fd_read, buf, 1); } 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) switch (errno) { - case EBADF: - case EINVAL: - case EIO: - case EISDIR: - _fd_read = -1; + case EBADF: + case EINVAL: + case EIO: + case EISDIR: + _fd_read = -1; } - + evas_cache_pending_process(); return count; #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 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)) { #ifdef BUILD_ASYNC_EVENTS - Evas_Event_Async new; + Evas_Event_Async *ev; ssize_t check; - int offset = 0; Eina_Bool result = EINA_FALSE; if (!func) 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); + + 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 { - check = write(_fd_write, ((char*)&new) + offset, sizeof(new) - offset); - offset += check; - } while (offset != sizeof(new) && (errno == EINTR || errno == EAGAIN)); + do + { + unsigned char buf[1] = { 0xf0 }; + check = write(_fd_write, buf, 1); + } while ((check != 1) && ((errno == EINTR) || (errno == EAGAIN))); - if (offset == sizeof(new)) + if (check == 1) result = EINA_TRUE; else switch (errno) { - case EBADF: - case EINVAL: - case EIO: - case EPIPE: - _fd_write = -1; + case EBADF: + case EINVAL: + case EIO: + case EPIPE: + _fd_write = -1; } - + pthread_mutex_unlock(&_mutex); - return result; #else func(target, type, event_info); - return EINA_TRUE; #endif } diff --git a/legacy/evas/src/lib/canvas/evas_object_image.c b/legacy/evas/src/lib/canvas/evas_object_image.c index 28c1014786..c822c779de 100644 --- a/legacy/evas/src/lib/canvas/evas_object_image.c +++ b/legacy/evas/src/lib/canvas/evas_object_image.c @@ -297,8 +297,13 @@ evas_object_image_file_set(Evas_Object *obj, const char *file, const char *key) o->prev.file = NULL; o->prev.key = NULL; 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; lo.scale_down_by = o->load_opts.scale_down_by; lo.dpi = o->load_opts.dpi; @@ -710,7 +715,7 @@ evas_object_image_fill_spread_get(const Evas_Object *obj) } 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; @@ -764,7 +769,7 @@ evas_object_image_fill_transform_set (Evas_Object *obj, Evas_Transform *t) /*FIXME: To be documented*/ 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; @@ -2261,8 +2266,13 @@ evas_object_image_free(Evas_Object *obj) if (o->cur.file) eina_stringshare_del(o->cur.file); if (o->cur.key) eina_stringshare_del(o->cur.key); 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->magic = 0; EINA_LIST_FREE(o->pixel_updates, r) diff --git a/legacy/evas/src/lib/include/evas_private.h b/legacy/evas/src/lib/include/evas_private.h index ba1d0095c0..eb9c844fdf 100644 --- a/legacy/evas/src/lib/include/evas_private.h +++ b/legacy/evas/src/lib/include/evas_private.h @@ -789,7 +789,8 @@ struct _Evas_Imaging_Font int evas_async_events_init(void); int evas_async_events_shutdown(void); - +int evas_async_target_del(const void *target); + void _evas_walk(Evas *e); void _evas_unwalk(Evas *e);