raster pushed a commit to branch master.

http://git.enlightenment.org/apps/rage.git/commit/?id=712d88dbf04bd78dabdc0a2065c01a8bc3ed3d4f

commit 712d88dbf04bd78dabdc0a2065c01a8bc3ed3d4f
Author: Carsten Haitzler (Rasterman) <[email protected]>
Date:   Sat Jul 29 00:54:12 2017 +0900

    rage browser mode thumbs - imrpove handling of child thum processes
    
    dont overload the machin and leave thumb procs around and handle their
    death better with tmp files+ atomic rename etc.
---
 src/bin/albumart.c   |  22 ++++--
 src/bin/thumb.c      |  43 +++++++----
 src/bin/videothumb.c | 207 ++++++++++++++++++++++++++++++++++-----------------
 3 files changed, 181 insertions(+), 91 deletions(-)

diff --git a/src/bin/albumart.c b/src/bin/albumart.c
index f98ee51..abdc4da 100644
--- a/src/bin/albumart.c
+++ b/src/bin/albumart.c
@@ -17,6 +17,7 @@ static Eina_Strbuf *sb_result = NULL;
 static Eina_Bool fetch_image = EINA_FALSE;
 static char *fetchfile = NULL;
 static char *fetchpath = NULL;
+static char *fetchpath2 = NULL;
 static FILE *fout = NULL;
 static void (*_fetch_done) (void *data) = NULL;
 static void *_fetch_data = NULL;
@@ -113,10 +114,14 @@ _cb_http_complete(void *data EINA_UNUSED, int type 
EINA_UNUSED, void *event)
         fetch_image = EINA_FALSE;
         fclose(fout);
         fout = NULL;
-        if (ecore_file_size(fetchpath) < 0)
-          {
-             ecore_file_unlink(fetchpath);
-          }
+        if (ecore_file_size(fetchpath2) < 0)
+          ecore_file_unlink(fetchpath2);
+        else
+          ecore_file_mv(fetchpath2, fetchpath);
+        free(fetchpath);
+        free(fetchpath2);
+        fetchpath = NULL;
+        fetchpath2 = NULL;
      }
    else
      {
@@ -156,7 +161,7 @@ _cb_http_complete(void *data EINA_UNUSED, int type 
EINA_UNUSED, void *event)
                     }
                   if (ok)
                     {
-                       char *path;
+                       char *path, *path2;
 
                        ecore_con_url_free(fetch);
                        fetch = NULL;
@@ -164,13 +169,18 @@ _cb_http_complete(void *data EINA_UNUSED, int type 
EINA_UNUSED, void *event)
                        path = _thumbpath(fetchfile);
                        if (path)
                          {
-                            fout = fopen(path, "wb");
+                            path2 = alloca(strlen(path) + 4  + 1);
+                            sprintf(path2, "%s.tmo", path);
+
+                            fout = fopen(path2, "wb");
                             if (fout)
                               {
                                  fetch_image = EINA_TRUE;
                                  fetch = _fetch(sb);
                                  free(fetchpath);
+                                 free(fetchpath2);
                                  fetchpath = strdup(path);
+                                 fetchpath2 = strdup(path2);
                               }
                             free(path);
                          }
diff --git a/src/bin/thumb.c b/src/bin/thumb.c
index deddeef..e961785 100644
--- a/src/bin/thumb.c
+++ b/src/bin/thumb.c
@@ -25,7 +25,7 @@ _cb_fetched(void *data EINA_UNUSED)
         int w, h;
         evas_object_image_file_set(im, path, NULL);
         evas_object_image_size_get(im, &w, &h);
-        if ((w < 1) || (h < 0)) ecore_file_unlink(path);
+        if ((w < 1) || (h < 1)) ecore_file_unlink(path);
         free(path);
      }
    exit(0);
@@ -33,7 +33,7 @@ _cb_fetched(void *data EINA_UNUSED)
 
 static Evas_Object *
 _media_artwork(Evas_Object *obj, const char *path)
-{ 
+{
    emotion_object_file_set(obj, path);
    Evas_Object *art = emotion_file_meta_artwork_get(obj, path, 
EMOTION_ARTWORK_PREVIEW_IMAGE);
    if (!art) art = emotion_file_meta_artwork_get(obj, path, 
EMOTION_ARTWORK_IMAGE);
@@ -48,7 +48,7 @@ _cb_loaded(void *data, Evas_Object *obj, void *info 
EINA_UNUSED)
 
    if (vid_timeout) ecore_timer_del(vid_timeout);
    vid_timeout = NULL;
-   
+
    file = data;
    title = emotion_object_meta_info_get(obj, EMOTION_META_INFO_TRACK_TITLE);
    artist = emotion_object_meta_info_get(obj, EMOTION_META_INFO_TRACK_ARTIST);
@@ -90,6 +90,7 @@ _cb_loaded(void *data, Evas_Object *obj, void *info 
EINA_UNUSED)
      {
         char buf_base[PATH_MAX];
         char buf_file[PATH_MAX];
+        char buf_file2[PATH_MAX];
         unsigned int pos;
 
         vidimage = evas_object_image_filled_add(evas_object_evas_get(subwin));
@@ -101,7 +102,7 @@ _cb_loaded(void *data, Evas_Object *obj, void *info 
EINA_UNUSED)
         if (!efreet_cache_home_get()) exit(3);
         snprintf(buf_base, sizeof(buf_base), "%s/rage/thumb/%02x",
                  efreet_cache_home_get(), sum[0]);
-        snprintf(buf_file, sizeof(buf_base),
+        snprintf(buf_file, sizeof(buf_file),
                  "%s/%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x"
                  "%02x%02x%02x%02x%02x%02x%02x%02x.eet",
                  buf_base,
@@ -110,8 +111,9 @@ _cb_loaded(void *data, Evas_Object *obj, void *info 
EINA_UNUSED)
                  sum[8], sum[9], sum[10], sum[11],
                  sum[12], sum[13], sum[14], sum[15],
                  sum[16], sum[17], sum[18], sum[19]);
+        snprintf(buf_file2, sizeof(buf_file2), "%s.tmp", buf_file);
         if (!ecore_file_mkpath(buf_base)) exit(4);
-        ef = eet_open(buf_file, EET_FILE_MODE_WRITE);
+        ef = eet_open(buf_file2, EET_FILE_MODE_WRITE);
         if (!ef) exit(5);
         pos = 0;
         for (pos = 0; ; pos += incr)
@@ -125,16 +127,16 @@ _cb_loaded(void *data, Evas_Object *obj, void *info 
EINA_UNUSED)
              evas_object_image_size_get(vidimage, &iw, &ih);
              if ((iw <= 1) || (ih <= 1))
                {
-                  eet_close(ef);
-                  exit(6);
+                  if (pos <= 0) goto err;
+                  else goto ok;
                }
              w = 320;
              h = (ih * 320) / iw;
              if (h < 1) h = 1;
              if ((w > 4096) || (h > 4096))
                {
-                  eet_close(ef);
-                  exit(6);
+                  if (pos <= 0) goto err;
+                  else goto ok;
                }
              evas_object_resize(vidimage, w, h);
              evas_object_resize(subwin, w, h);
@@ -145,12 +147,19 @@ _cb_loaded(void *data, Evas_Object *obj, void *info 
EINA_UNUSED)
                                     0, 0, 70, EET_IMAGE_JPEG);
              else
                {
-                  eet_close(ef);
-                  exit(6);
+                  if (pos <= 0) goto err;
+                  else goto ok;
                }
              evas_object_image_data_set(image, pixels);
           }
+ok:
+        eet_close(ef);
+        ecore_file_mv(buf_file2, buf_file);
+        exit(0);
+err:
         eet_close(ef);
+        ecore_file_unlink(buf_file2);
+        exit(6);
      }
 }
 
@@ -169,7 +178,7 @@ _local_artwork_poster(Evas_Object *win, const char 
*path_to_file)
 
    emotion_object_init(em, NULL);
    emotion_object_file_set(em, path_to_file);
-   
+
    char *path = albumart_file_get(path_to_file);
    if (path)
      {
@@ -182,10 +191,14 @@ _local_artwork_poster(Evas_Object *win, const char 
*path_to_file)
        Evas_Object *artwork = _media_artwork(em, path_to_file);
        if (artwork)
          {
-            evas_object_image_save(artwork, path, NULL, NULL);
+            char *path2 = alloca(strlen(path) + 4 + 1);
+
+            sprintf(path2, "%s.tmp", path);
+            evas_object_image_save(artwork, path2, NULL, NULL);
             evas_object_del(artwork);
             free(path);
             /* This speeds things up */
+            ecore_file_mv(path2, path);
             exit(0);
          }
 
@@ -236,9 +249,9 @@ elm_main(int argc, char **argv)
           }
      }
 
-   if (poster && _local_artwork_poster(win, file)) 
+   if ((poster) && (_local_artwork_poster(win, file)))
      {
-       goto out; 
+        goto out;
      }
 
    if (emotion_object_init(vid, NULL))
diff --git a/src/bin/videothumb.c b/src/bin/videothumb.c
index fab434c..51b39df 100644
--- a/src/bin/videothumb.c
+++ b/src/bin/videothumb.c
@@ -4,13 +4,13 @@
 #include "albumart.h"
 
 typedef struct _Videothumb Videothumb;
+typedef struct _Pending Pending;
 
 struct _Videothumb
 {
    Evas_Object_Smart_Clipped_Data __clipped_data;
    Evas_Object *o_img, *o_img2;
-   Ecore_Exe *thumb_exe;
-   Ecore_Event_Handler *exe_handler;
+   Pending *pending;
    Ecore_Timer *cycle_timer;
    Ecore_Timer *launch_timer;
    const char *file;
@@ -20,49 +20,115 @@ struct _Videothumb
    unsigned int realpos;
    int iw, ih;
    Evas_Coord w, h;
+   int tried;
    Eina_Bool seen : 1;
    Eina_Bool poster_mode : 1;
    Eina_Bool poster : 1;
 };
 
+struct _Pending
+{
+   Ecore_Exe *exe;
+   Evas_Object *obj;
+   Eina_Stringshare *realpath;
+};
+
 static Evas_Smart *_smart = NULL;
 static Evas_Smart_Class _parent_sc = EVAS_SMART_CLASS_INIT_NULL;
 
+static Ecore_Event_Handler *exe_handler = NULL;
 static Eina_List *busy_thumbs = NULL;
 static Eina_List *vidthumbs = NULL;
 
-static int        _thumb_running = 0;
-
 static Eina_Bool _cb_thumb_exe(void *data, int type EINA_UNUSED, void *event);
+static void _videothumb_image_load(Evas_Object *obj);
 static void _videothumb_eval(Evas_Object *obj, Eina_Bool force);
 static void _smart_calculate(Evas_Object *obj);
 
+static Pending *
+_busy_realpath_find(const char *realpath)
+{
+   Eina_List *l;
+   Pending *p;
+
+   EINA_LIST_FOREACH(busy_thumbs, l, p)
+     {
+        if (!strcmp(realpath, p->realpath)) return p;
+     }
+   return NULL;
+}
+
+static Pending *
+_busy_exe_find(Ecore_Exe *exe)
+{
+   Eina_List *l;
+   Pending *p;
+
+   EINA_LIST_FOREACH(busy_thumbs, l, p)
+     {
+        if (exe == p->exe) return p;
+     }
+   return NULL;
+}
+
+static Pending *
+_busy_add(Evas_Object *obj, Ecore_Exe *exe, const char *realpath)
+{
+   Pending *p;
+
+   p = calloc(1, sizeof(Pending));
+   if (!p) return NULL;
+   p->exe = exe;
+   p->obj = obj;
+   p->realpath = eina_stringshare_add(realpath);
+   busy_thumbs = eina_list_append(busy_thumbs, p);
+   return p;
+}
+
+static void
+_busy_pending_del(Pending *p)
+{
+   eina_stringshare_del(p->realpath);
+   free(p);
+   busy_thumbs = eina_list_remove(busy_thumbs, p);
+}
+
 static Eina_Bool
-_busy_add(const char *file)
+_busy_del(Ecore_Exe *exe)
 {
    Eina_List *l;
-   const char *s;
+   Pending *p;
 
-   EINA_LIST_FOREACH(busy_thumbs, l, s)
+   EINA_LIST_FOREACH(busy_thumbs, l, p)
      {
-        if (!strcmp(file, s)) return EINA_FALSE;
+        if (p->exe == exe)
+          {
+             _busy_pending_del(p);
+             return EINA_TRUE;
+          }
      }
-   busy_thumbs = eina_list_append(busy_thumbs, eina_stringshare_add(file));
-   return EINA_TRUE;
+   return EINA_FALSE;
+}
+
+static void
+_busy_kill(Pending *p)
+{
+   ecore_exe_kill(p->exe);
+   ecore_exe_free(p->exe);
+   _busy_pending_del(p);
 }
 
 static Eina_Bool
-_busy_del(const char *file)
+_busy_obj_del(Evas_Object *obj)
 {
    Eina_List *l;
-   const char *s;
+   Pending *p;
 
-   EINA_LIST_FOREACH(busy_thumbs, l, s)
+   EINA_LIST_FOREACH(busy_thumbs, l, p)
      {
-        if (!strcmp(file, s))
+        if (p->obj == obj)
           {
-             eina_stringshare_del(s);
-             busy_thumbs = eina_list_remove_list(busy_thumbs, l);
+             _busy_kill(p);
              return EINA_TRUE;
           }
      }
@@ -73,18 +139,21 @@ static void
 _thumb_update(Evas_Object *obj)
 {
    Videothumb *sd = evas_object_smart_data_get(obj);
+   Evas_Object *o;
    char buf[PATH_MAX];
 
    if (!sd) return;
    snprintf(buf, sizeof(buf), "%u", sd->realpos);
-   if (sd->o_img2)
+   o = sd->o_img;
+   if (o)
      {
-        evas_object_image_file_set(sd->o_img2, NULL, NULL);
-        evas_object_image_file_set(sd->o_img2, sd->realfile,
+        evas_object_image_file_set(o, NULL, NULL);
+        evas_object_image_file_set(o, sd->realfile,
                                    sd->poster ? NULL : buf);
-        evas_object_image_preload(sd->o_img2, EINA_FALSE);
+        evas_object_image_preload(o, EINA_FALSE);
         evas_object_smart_callback_call(obj, "loaded", NULL);
      }
+   _videothumb_image_load(obj);
 }
 
 static void
@@ -107,34 +176,37 @@ _videothumb_launch_do(Evas_Object *obj)
 
    if (!sd) return;
    ecore_exe_run_priority_set(10);
-   if (sd->thumb_exe)
+   if (sd->pending)
      {
-        _busy_del(sd->realpath);
-        ecore_exe_kill(sd->thumb_exe);
-        ecore_exe_free(sd->thumb_exe);
-        sd->thumb_exe = NULL;
-        _thumb_running--;
+        while (_busy_obj_del(obj));
+        sd->pending = NULL;
      }
+   // tried too many times BEFORE... DON'T TRY AGAIN.
+   if (sd->tried > 5) return;
    s = ecore_file_escape_name(sd->realpath);
    if (s)
      {
         libdir = elm_app_lib_dir_get();
         if (libdir)
           {
-             if (_busy_add(sd->realpath))
+             if (!_busy_realpath_find(sd->realpath))
                {
-                  if (!sd->exe_handler)
-                    sd->exe_handler = 
ecore_event_handler_add(ECORE_EXE_EVENT_DEL,
-                                                              _cb_thumb_exe, 
obj);
+                  Ecore_Exe *exe;
+
+                  if (!exe_handler)
+                    exe_handler = ecore_event_handler_add(ECORE_EXE_EVENT_DEL,
+                                                          _cb_thumb_exe, NULL);
                   snprintf(buf, sizeof(buf),
-                           "%s/rage/utils/rage_thumb %s 10000 %i 1> /dev/null 
2>&1",
+                           "%s/rage/utils/rage_thumb %s 10000 %i",
                            libdir, s, sd->poster_mode ? 1 : 0);
-                  sd->thumb_exe = ecore_exe_pipe_run(buf,
-                                                     ECORE_EXE_USE_SH |
-                                                     
ECORE_EXE_TERM_WITH_PARENT |
-                                                     ECORE_EXE_NOT_LEADER,
-                                                     obj);
-                  _thumb_running++;
+                  exe = ecore_exe_pipe_run(buf,
+                                           ECORE_EXE_TERM_WITH_PARENT |
+                                           ECORE_EXE_NOT_LEADER,
+                                           obj);
+                  if (exe)
+                    {
+                       sd->pending = _busy_add(obj, exe, sd->realpath);
+                    }
                }
              else return;
           }
@@ -154,7 +226,7 @@ _have_active_thumb(const char *path)
 
         if (sd)
           {
-             if ((sd->thumb_exe) && (!strcmp(path, sd->realpath)))
+             if ((sd->pending) && (!strcmp(path, sd->realpath)))
                return EINA_TRUE;
           }
      }
@@ -166,9 +238,9 @@ _cb_videothumb_delay(void *data)
 {
    Evas_Object *obj = data;
    Videothumb *sd = evas_object_smart_data_get(obj);
-   int maxnum = (eina_cpu_count() / 2) + 1;
+   unsigned int maxnum = (eina_cpu_count() / 2) + 1;
    if (!sd) return EINA_FALSE;
-   if (_thumb_running < maxnum)
+   if (eina_list_count(busy_thumbs) < maxnum)
      {
         if (!_have_active_thumb(sd->realpath))
           {
@@ -192,35 +264,35 @@ _videothumb_launch(Evas_Object *obj)
 
    if (!sd) return;
    if (sd->launch_timer) return;
-   sd->launch_timer = ecore_timer_add(0.5, _cb_videothumb_delay, obj);
+   sd->launch_timer = ecore_timer_add(0.2, _cb_videothumb_delay, obj);
 }
 
 static Eina_Bool
-_cb_thumb_exe(void *data, int type EINA_UNUSED, void *event)
+_cb_thumb_exe(void *data EINA_UNUSED, int type EINA_UNUSED, void *event)
 {
-   Ecore_Exe_Event_Del *ev;
-   Videothumb *sd = evas_object_smart_data_get(data);
+   Ecore_Exe_Event_Del *ev = event;
+   Pending *p = _busy_exe_find(ev->exe);
 
-   if (!sd) return EINA_TRUE;
-   ev = event;
-   if (ev->exe == sd->thumb_exe)
+   if (p)
      {
         Eina_List *l;
-        Evas_Object *o;
+        Evas_Object *o, *o2 = p->obj;
 
-        _busy_del(sd->realpath);
-        sd->thumb_exe = NULL;
-        _thumb_running--;
-        EINA_LIST_FOREACH(vidthumbs, l, o)
+        if (o2)
           {
-             _thumb_match_update(o, sd->realpath);
+             Videothumb *sd = evas_object_smart_data_get(o2);
+             if (sd)
+               {
+                  sd->pending = NULL;
+                  sd->tried++;
+               }
           }
-        if (sd->exe_handler)
+
+        EINA_LIST_FOREACH(vidthumbs, l, o)
           {
-             ecore_event_handler_del(sd->exe_handler);
-             sd->exe_handler = NULL;
+             _thumb_match_update(o, p->realpath);
           }
-        return EINA_FALSE;
+        _busy_del(p->exe);
      }
    return EINA_TRUE;
 }
@@ -234,7 +306,9 @@ _cb_preload(void *data, Evas *e EINA_UNUSED, Evas_Object 
*obj EINA_UNUSED, void
    if (sd->o_img) evas_object_del(sd->o_img);
    sd->o_img = sd->o_img2;
    sd->o_img2 = NULL;
-   evas_object_image_size_get(sd->o_img, &(sd->iw), &(sd->ih));
+   sd->iw = 0;
+   sd->ih = 0;
+   if (sd->o_img) evas_object_image_size_get(sd->o_img, &(sd->iw), &(sd->ih));
    if ((sd->iw <= 0) || (sd->ih <= 0))
      {
         if (sd->cycle_timer)
@@ -246,7 +320,7 @@ _cb_preload(void *data, Evas *e EINA_UNUSED, Evas_Object 
*obj EINA_UNUSED, void
              else
                {
                   sd->pos = 0.0;
-                  if (!sd->thumb_exe) _videothumb_eval(data, EINA_TRUE);
+                  if (!sd->pending) _videothumb_eval(data, EINA_TRUE);
                }
           }
         else
@@ -291,6 +365,7 @@ _videothumb_image_load(Evas_Object *obj)
 
    if (!sd) return;
    if (!sd->file) return;
+   if (sd->pending) return;
    sd->o_img2 = evas_object_image_filled_add(evas_object_evas_get(obj));
    evas_object_image_load_head_skip_set(sd->o_img2, EINA_TRUE);
    evas_object_smart_member_add(sd->o_img2, obj);
@@ -415,29 +490,21 @@ _smart_del(Evas_Object *obj)
 
    if (!sd) return;
    vidthumbs = eina_list_remove(vidthumbs, obj);
-   if (sd->thumb_exe)
-     {
-        if (sd->realpath) _busy_del(sd->realpath);
-        _thumb_running--;
-        ecore_exe_kill(sd->thumb_exe);
-        ecore_exe_free(sd->thumb_exe);
-     }
+   while (_busy_obj_del(obj));
    if (sd->launch_timer) ecore_timer_del(sd->launch_timer);
    if (sd->file) eina_stringshare_del(sd->file);
    if (sd->realfile) eina_stringshare_del(sd->realfile);
    if (sd->realpath) free(sd->realpath);
    if (sd->o_img) evas_object_del(sd->o_img);
    if (sd->o_img2) evas_object_del(sd->o_img2);
-   if (sd->exe_handler) ecore_event_handler_del(sd->exe_handler);
    if (sd->cycle_timer) ecore_timer_del(sd->cycle_timer);
 
-   sd->thumb_exe = NULL;
+   sd->pending = NULL;
    sd->file = NULL;
    sd->realfile = NULL;
    sd->realpath = NULL;
    sd->o_img = NULL;
    sd->o_img2 = NULL;
-   sd->exe_handler = NULL;
    sd->cycle_timer = NULL;
 
    _parent_sc.del(obj);
@@ -563,7 +630,7 @@ _cb_cycle(void *data)
         return EINA_FALSE;
      }
    sd->pos += 10.0;
-   if (!sd->thumb_exe)
+   if (!sd->pending)
      {
         _videothumb_eval(obj, EINA_TRUE);
         if (sd->iw <= 0)

-- 


Reply via email to