and fix async load thing hanging around... put in shared queue and be able to
authorraster <raster@7cbeb6ba-43b4-40fd-8cce-4c39aea84d33>
Mon, 28 Sep 2009 03:51:21 +0000 (03:51 +0000)
committerraster <raster@7cbeb6ba-43b4-40fd-8cce-4c39aea84d33>
Mon, 28 Sep 2009 03:51:21 +0000 (03:51 +0000)
remove targets from the queue.

git-svn-id: http://svn.enlightenment.org/svn/e/trunk/evas@42754 7cbeb6ba-43b4-40fd-8cce-4c39aea84d33

src/lib/cache/evas_cache_image.c
src/lib/canvas/evas_async_events.c
src/lib/canvas/evas_object_image.c
src/lib/include/evas_private.h

index 6607146..71d2648 100644 (file)
@@ -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);
                                    }
index f4fecb6..57555f4 100644 (file)
@@ -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*) &current) + 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
 }
index 28c1014..c822c77 100644 (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.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)
index ba1d009..eb9c844 100644 (file)
@@ -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);