forked from enlightenment/efl
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:
parent
449bdb7bc6
commit
526b6e8f3b
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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*) ¤t) + 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
|
||||||
}
|
}
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue