eio: add internal function able to build array instead of triggering a callback per...
authorCedric Bail <cedric@osg.samsung.com>
Mon, 1 Aug 2016 04:39:39 +0000 (21:39 -0700)
committerCedric BAIL <cedric@osg.samsung.com>
Thu, 8 Sep 2016 21:58:06 +0000 (14:58 -0700)
src/lib/eio/eio_dir.c
src/lib/eio/eio_file.c
src/lib/eio/eio_private.h

index 9d0c72e..e275ae9 100644 (file)
@@ -742,29 +742,6 @@ _eio_dir_direct_find_heavy(void *data, Ecore_Thread *thread)
 }
 
 static void
-_eio_dir_stat_find_notify(void *data, Ecore_Thread *thread EINA_UNUSED, void *msg_data)
-{
-   Eio_File_Dir_Ls *async = data;
-   Eina_List *pack = msg_data;
-   Eio_File_Direct_Info *info;
-
-   EINA_LIST_FREE(pack, info)
-     {
-        async->ls.common.main.associated = info->associated;
-
-        async->main_cb((void*) async->ls.common.data, &async->ls.common, &info->info);
-
-        if (async->ls.common.main.associated)
-          {
-             eina_hash_free(async->ls.common.main.associated);
-             async->ls.common.main.associated = NULL;
-          }
-
-        eio_direct_info_free(info);
-     }
-}
-
-static void
 _eio_dir_stat_done(void *data, Ecore_Thread *thread EINA_UNUSED)
 {
    Eio_File_Ls *async = data;
@@ -919,18 +896,18 @@ eio_dir_unlink(const char *path,
    return &rmrf->progress.common;
 }
 
-EAPI Eio_File *
-eio_dir_stat_ls(const char *dir,
-                Eio_Filter_Direct_Cb filter_cb,
-                Eio_Main_Direct_Cb main_cb,
-                Eio_Done_Cb done_cb,
-                Eio_Error_Cb error_cb,
-                const void *data)
+static Eio_File *
+_eio_dir_stat_internal_ls(const char *dir,
+                          Eio_Filter_Direct_Cb filter_cb,
+                          Eio_Main_Direct_Cb main_cb,
+                          Eio_Array_Cb main_internal_cb,
+                          Eio_Done_Cb done_cb,
+                          Eio_Error_Cb error_cb,
+                          const void *data)
 {
    Eio_File_Dir_Ls *async;
 
    EINA_SAFETY_ON_NULL_RETURN_VAL(dir, NULL);
-   EINA_SAFETY_ON_NULL_RETURN_VAL(main_cb, NULL);
    EINA_SAFETY_ON_NULL_RETURN_VAL(done_cb, NULL);
    EINA_SAFETY_ON_NULL_RETURN_VAL(error_cb, NULL);
 
@@ -942,16 +919,24 @@ eio_dir_stat_ls(const char *dir,
     * where info can be modified, but in our case it's already doing
     * stat() then it shouldn't be needed!
     */
-   async->filter_cb = (Eio_Filter_Dir_Cb)filter_cb;
-   async->main_cb = main_cb;
    async->ls.directory = eina_stringshare_add(dir);
+   async->filter_cb = (Eio_Filter_Dir_Cb)filter_cb;
+   if (main_internal_cb)
+     {
+        async->main_internal_cb = main_internal_cb;
+        async->ls.gather = EINA_TRUE;
+     }
+   else
+     {
+        async->main_cb = main_cb;
+     }
 
    if (!eio_long_file_set(&async->ls.common,
                           done_cb,
                           error_cb,
                           data,
                           _eio_dir_stat_find_heavy,
-                          _eio_dir_stat_find_notify,
+                          _eio_direct_notify,
                           _eio_dir_stat_done,
                           _eio_dir_stat_error))
      return NULL;
@@ -960,36 +945,94 @@ eio_dir_stat_ls(const char *dir,
 }
 
 EAPI Eio_File *
-eio_dir_direct_ls(const char *dir,
-                 Eio_Filter_Dir_Cb filter_cb,
-                 Eio_Main_Direct_Cb main_cb,
-                 Eio_Done_Cb done_cb,
-                 Eio_Error_Cb error_cb,
-                 const void *data)
+eio_dir_stat_ls(const char *dir,
+                Eio_Filter_Direct_Cb filter_cb,
+                Eio_Main_Direct_Cb main_cb,
+                Eio_Done_Cb done_cb,
+                Eio_Error_Cb error_cb,
+                const void *data)
+{
+   EINA_SAFETY_ON_NULL_RETURN_VAL(main_cb, NULL);
+
+   return _eio_dir_stat_internal_ls(dir, filter_cb, main_cb, NULL, done_cb, error_cb, data);
+}
+
+Eio_File *
+_eio_dir_stat_ls(const char *dir,
+                 Eio_Array_Cb main_internal_cb,
+                 Eio_Done_Cb done_cb,
+                 Eio_Error_Cb error_cb,
+                 const void *data)
+{
+   EINA_SAFETY_ON_NULL_RETURN_VAL(main_internal_cb, NULL);
+
+   return _eio_dir_stat_internal_ls(dir, NULL, NULL, main_internal_cb, done_cb, error_cb, data);
+}
+
+static Eio_File *
+_eio_dir_direct_internal_ls(const char *dir,
+                            Eio_Filter_Dir_Cb filter_cb,
+                            Eio_Main_Direct_Cb main_cb,
+                            Eio_Array_Cb main_internal_cb,
+                            Eio_Done_Cb done_cb,
+                            Eio_Error_Cb error_cb,
+                            const void *data)
 {
    Eio_File_Dir_Ls *async;
 
    EINA_SAFETY_ON_NULL_RETURN_VAL(dir, NULL);
-   EINA_SAFETY_ON_NULL_RETURN_VAL(main_cb, NULL);
    EINA_SAFETY_ON_NULL_RETURN_VAL(done_cb, NULL);
    EINA_SAFETY_ON_NULL_RETURN_VAL(error_cb, NULL);
 
    async = malloc(sizeof(Eio_File_Dir_Ls));
    EINA_SAFETY_ON_NULL_RETURN_VAL(async, NULL);
 
-   async->filter_cb = filter_cb;
-   async->main_cb = main_cb;
    async->ls.directory = eina_stringshare_add(dir);
+   async->filter_cb = filter_cb;
+   if (main_internal_cb)
+     {
+        async->main_internal_cb = main_internal_cb;
+        async->ls.gather = EINA_TRUE;
+     }
+   else
+     {
+        async->main_cb = main_cb;
+     }
 
    if (!eio_long_file_set(&async->ls.common,
                           done_cb,
                           error_cb,
                           data,
                           _eio_dir_direct_find_heavy,
-                          _eio_dir_stat_find_notify,
+                          _eio_direct_notify,
                           _eio_dir_stat_done,
                           _eio_dir_stat_error))
      return NULL;
 
    return &async->ls.common;
 }
+
+EAPI Eio_File *
+eio_dir_direct_ls(const char *dir,
+                 Eio_Filter_Dir_Cb filter_cb,
+                 Eio_Main_Direct_Cb main_cb,
+                 Eio_Done_Cb done_cb,
+                 Eio_Error_Cb error_cb,
+                 const void *data)
+{
+   EINA_SAFETY_ON_NULL_RETURN_VAL(main_cb, NULL);
+
+   return _eio_dir_direct_internal_ls(dir, filter_cb, main_cb, NULL, done_cb, error_cb, data);
+}
+
+Eio_File *
+_eio_dir_direct_ls(const char *dir,
+                   Eio_Array_Cb main_internal_cb,
+                   Eio_Done_Cb done_cb,
+                   Eio_Error_Cb error_cb,
+                   const void *data)
+{
+   EINA_SAFETY_ON_NULL_RETURN_VAL(main_internal_cb, NULL);
+
+   return _eio_dir_direct_internal_ls(dir, NULL, NULL, main_internal_cb, done_cb, error_cb, data);
+}
index a7c02b9..1afa4ab 100644 (file)
@@ -95,8 +95,8 @@ _eio_file_heavy(void *data, Ecore_Thread *thread)
    async->ls.ls = ls;
 }
 
-static void
-_eio_file_notify(void *data, Ecore_Thread *thread EINA_UNUSED, void *msg_data)
+void
+_eio_string_notify(void *data, Ecore_Thread *thread EINA_UNUSED, void *msg_data)
 {
    Eio_File_Char_Ls *async = data;
    Eina_List *pack = msg_data;
@@ -104,6 +104,29 @@ _eio_file_notify(void *data, Ecore_Thread *thread EINA_UNUSED, void *msg_data)
 
    async->ls.common.length += eina_list_count(pack);
 
+   // Check if it is an internal use
+   if (async->ls.gather)
+     {
+        Eina_Array *gather;
+
+        gather = eina_array_new(eina_list_count(pack));
+        EINA_LIST_FREE(pack, info)
+          {
+             if (!gather)
+               eina_stringshare_del(info->filename);
+             else
+               eina_array_push(gather, info->filename);
+             eio_char_free(info);
+          }
+
+        // transfer ownership to caller
+        async->main_internal_cb((void*) async->ls.common.data,
+                                &async->ls.common,
+                                gather);
+
+        return ;
+     }
+
    EINA_LIST_FREE(pack, info)
      {
         async->ls.common.main.associated = info->associated;
@@ -201,8 +224,8 @@ _eio_file_stat_heavy(void *data, Ecore_Thread *thread)
    _eio_file_eina_ls_heavy(thread, async, ls);
 }
 
-static void
-_eio_file_direct_notify(void *data, Ecore_Thread *thread EINA_UNUSED, void *msg_data)
+void
+_eio_direct_notify(void *data, Ecore_Thread *thread EINA_UNUSED, void *msg_data)
 {
    Eio_File_Direct_Ls *async = data;
    Eina_List *pack = msg_data;
@@ -210,6 +233,23 @@ _eio_file_direct_notify(void *data, Ecore_Thread *thread EINA_UNUSED, void *msg_
 
    async->ls.common.length += eina_list_count(pack);
 
+   // Check if it is an internal use
+   if (async->ls.gather)
+     {
+        Eina_Array *gather;
+
+        gather = eina_array_new(eina_list_count(pack));
+        EINA_LIST_FREE(pack, info)
+          eina_array_push(gather, &info->info);
+
+        // transfer ownership to caller
+        async->main_internal_cb((void*) async->ls.common.data,
+                                &async->ls.common,
+                                gather);
+
+        return ;
+     }
+
    EINA_LIST_FREE(pack, info)
      {
         async->ls.common.main.associated = info->associated;
@@ -491,35 +531,42 @@ eio_async_error(void *data, Ecore_Thread *thread EINA_UNUSED)
 /*============================================================================*
  *                                   API                                      *
  *============================================================================*/
-
-EAPI Eio_File *
-eio_file_ls(const char *dir,
-           Eio_Filter_Cb filter_cb,
-           Eio_Main_Cb main_cb,
-           Eio_Done_Cb done_cb,
-           Eio_Error_Cb error_cb,
-           const void *data)
+static Eio_File *
+_eio_file_internal_ls(const char *dir,
+                      Eio_Filter_Cb filter_cb,
+                      Eio_Main_Cb main_cb,
+                      Eio_Array_Cb main_internal_cb,
+                      Eio_Done_Cb done_cb,
+                      Eio_Error_Cb error_cb,
+                      const void *data)
 {
    Eio_File_Char_Ls *async;
 
    EINA_SAFETY_ON_NULL_RETURN_VAL(dir, NULL);
-   EINA_SAFETY_ON_NULL_RETURN_VAL(main_cb, NULL);
    EINA_SAFETY_ON_NULL_RETURN_VAL(done_cb, NULL);
    EINA_SAFETY_ON_NULL_RETURN_VAL(error_cb, NULL);
 
    async = eio_common_alloc(sizeof(Eio_File_Char_Ls));
    EINA_SAFETY_ON_NULL_RETURN_VAL(async, NULL);
 
-   async->filter_cb = filter_cb;
-   async->main_cb = main_cb;
    async->ls.directory = eina_stringshare_add(dir);
+   async->filter_cb = filter_cb;
+   if (main_internal_cb)
+     {
+        async->main_internal_cb = main_internal_cb;
+        async->ls.gather = EINA_TRUE;
+     }
+   else
+     {
+        async->main_cb = main_cb;
+     }
 
    if (!eio_long_file_set(&async->ls.common,
                          done_cb,
                          error_cb,
                          data,
                          _eio_file_heavy,
-                         _eio_file_notify,
+                         _eio_string_notify,
                          eio_async_end,
                          eio_async_error))
      return NULL;
@@ -528,33 +575,66 @@ eio_file_ls(const char *dir,
 }
 
 EAPI Eio_File *
-eio_file_direct_ls(const char *dir,
-                  Eio_Filter_Direct_Cb filter_cb,
-                  Eio_Main_Direct_Cb main_cb,
-                  Eio_Done_Cb done_cb,
-                  Eio_Error_Cb error_cb,
-                  const void *data)
+eio_file_ls(const char *dir,
+           Eio_Filter_Cb filter_cb,
+           Eio_Main_Cb main_cb,
+           Eio_Done_Cb done_cb,
+           Eio_Error_Cb error_cb,
+           const void *data)
+{
+   EINA_SAFETY_ON_NULL_RETURN_VAL(main_cb, NULL);
+
+   return _eio_file_internal_ls(dir, filter_cb, main_cb, NULL, done_cb, error_cb, data);
+}
+
+Eio_File *
+_eio_file_ls(const char *dir,
+             Eio_Array_Cb main_internal_cb,
+             Eio_Done_Cb done_cb,
+             Eio_Error_Cb error_cb,
+             const void *data)
+{
+   EINA_SAFETY_ON_NULL_RETURN_VAL(main_internal_cb, NULL);
+
+   return _eio_file_internal_ls(dir, NULL, NULL, main_internal_cb, done_cb, error_cb, data);
+}
+
+static Eio_File *
+_eio_file_direct_internal_ls(const char *dir,
+                             Eio_Filter_Direct_Cb filter_cb,
+                             Eio_Main_Direct_Cb main_cb,
+                             Eio_Array_Cb main_internal_cb,
+                             Eio_Done_Cb done_cb,
+                             Eio_Error_Cb error_cb,
+                             const void *data)
 {
    Eio_File_Direct_Ls *async;
 
    EINA_SAFETY_ON_NULL_RETURN_VAL(dir, NULL);
-   EINA_SAFETY_ON_NULL_RETURN_VAL(main_cb, NULL);
    EINA_SAFETY_ON_NULL_RETURN_VAL(done_cb, NULL);
    EINA_SAFETY_ON_NULL_RETURN_VAL(error_cb, NULL);
 
    async = eio_common_alloc(sizeof(Eio_File_Direct_Ls));
    EINA_SAFETY_ON_NULL_RETURN_VAL(async, NULL);
 
-   async->filter_cb = filter_cb;
-   async->main_cb = main_cb;
    async->ls.directory = eina_stringshare_add(dir);
+   async->filter_cb = filter_cb;
+   if (main_internal_cb)
+     {
+        async->main_internal_cb = main_internal_cb;
+        async->ls.gather = EINA_TRUE;
+     }
+   else
+     {
+        async->main_cb = main_cb;
+     }
 
    if (!eio_long_file_set(&async->ls.common,
                          done_cb,
                          error_cb,
                          data,
                          _eio_file_direct_heavy,
-                         _eio_file_direct_notify,
+                         _eio_direct_notify,
                          eio_async_end,
                          eio_async_error))
      return NULL;
@@ -563,33 +643,66 @@ eio_file_direct_ls(const char *dir,
 }
 
 EAPI Eio_File *
-eio_file_stat_ls(const char *dir,
-                 Eio_Filter_Direct_Cb filter_cb,
-                 Eio_Main_Direct_Cb main_cb,
-                 Eio_Done_Cb done_cb,
-                 Eio_Error_Cb error_cb,
-                 const void *data)
+eio_file_direct_ls(const char *dir,
+                  Eio_Filter_Direct_Cb filter_cb,
+                  Eio_Main_Direct_Cb main_cb,
+                  Eio_Done_Cb done_cb,
+                  Eio_Error_Cb error_cb,
+                  const void *data)
+{
+   EINA_SAFETY_ON_NULL_RETURN_VAL(main_cb, NULL);
+
+   return _eio_file_direct_internal_ls(dir, filter_cb, main_cb, NULL, done_cb, error_cb, data);
+}
+
+Eio_File *
+_eio_file_direct_ls(const char *dir,
+                    Eio_Array_Cb main_internal_cb,
+                    Eio_Done_Cb done_cb,
+                    Eio_Error_Cb error_cb,
+                    const void *data)
+{
+   EINA_SAFETY_ON_NULL_RETURN_VAL(main_internal_cb, NULL);
+
+   return _eio_file_direct_internal_ls(dir, NULL, NULL, main_internal_cb, done_cb, error_cb, data);
+}
+
+static Eio_File *
+_eio_file_stat_internal_ls(const char *dir,
+                           Eio_Filter_Direct_Cb filter_cb,
+                           Eio_Main_Direct_Cb main_cb,
+                           Eio_Array_Cb main_internal_cb,
+                           Eio_Done_Cb done_cb,
+                           Eio_Error_Cb error_cb,
+                           const void *data)
 {
    Eio_File_Direct_Ls *async;
 
    EINA_SAFETY_ON_NULL_RETURN_VAL(dir, NULL);
-   EINA_SAFETY_ON_NULL_RETURN_VAL(main_cb, NULL);
    EINA_SAFETY_ON_NULL_RETURN_VAL(done_cb, NULL);
    EINA_SAFETY_ON_NULL_RETURN_VAL(error_cb, NULL);
 
    async = eio_common_alloc(sizeof(Eio_File_Direct_Ls));
    EINA_SAFETY_ON_NULL_RETURN_VAL(async, NULL);
 
-   async->filter_cb = filter_cb;
-   async->main_cb = main_cb;
    async->ls.directory = eina_stringshare_add(dir);
+   async->filter_cb = filter_cb;
+   if (main_internal_cb)
+     {
+        async->main_internal_cb = main_internal_cb;
+        async->ls.gather = EINA_TRUE;
+     }
+   else
+     {
+        async->main_cb = main_cb;
+     }
 
    if (!eio_long_file_set(&async->ls.common,
                          done_cb,
                          error_cb,
                          data,
                          _eio_file_stat_heavy,
-                         _eio_file_direct_notify,
+                         _eio_direct_notify,
                          eio_async_end,
                          eio_async_error))
      return NULL;
@@ -597,6 +710,31 @@ eio_file_stat_ls(const char *dir,
    return &async->ls.common;
 }
 
+EAPI Eio_File *
+eio_file_stat_ls(const char *dir,
+                 Eio_Filter_Direct_Cb filter_cb,
+                 Eio_Main_Direct_Cb main_cb,
+                 Eio_Done_Cb done_cb,
+                 Eio_Error_Cb error_cb,
+                 const void *data)
+{
+   EINA_SAFETY_ON_NULL_RETURN_VAL(main_cb, NULL);
+
+   return _eio_file_stat_internal_ls(dir, filter_cb, main_cb, NULL, done_cb, error_cb, data);
+}
+
+Eio_File *
+_eio_file_stat_ls(const char *dir,
+                 Eio_Array_Cb main_internal_cb,
+                 Eio_Done_Cb done_cb,
+                 Eio_Error_Cb error_cb,
+                 const void *data)
+{
+   EINA_SAFETY_ON_NULL_RETURN_VAL(main_internal_cb, NULL);
+
+   return _eio_file_stat_internal_ls(dir, NULL, NULL, main_internal_cb, done_cb, error_cb, data);
+}
+
 EAPI Eina_Bool
 eio_file_cancel(Eio_File *ls)
 {
index 39c37ae..69a73d3 100644 (file)
@@ -104,6 +104,8 @@ extern int _eio_log_dom_global;
 #endif /* ifdef CRI */
 #define CRI(...) EINA_LOG_DOM_CRIT(_eio_log_dom_global, __VA_ARGS__)
 
+typedef void (*Eio_Array_Cb)(void *data, Eio_File *common, Eina_Array *g);
+
 typedef struct _Eio_Eet_Open Eio_Eet_Open;
 typedef struct _Eio_Eet_Simple Eio_Eet_Simple;
 typedef struct _Eio_Eet_Write Eio_Eet_Write;
@@ -142,6 +144,7 @@ struct _Eio_File_Associate
 
 struct _Eio_File_Direct_Info
 {
+   // Do not put anything before info
    Eina_File_Direct_Info info;
 
    Eina_Hash *associated;
@@ -278,6 +281,8 @@ struct _Eio_File_Ls
    Eio_File common;
    const char *directory;
    Eina_Iterator *ls;
+
+   Eina_Bool gather;
 };
 
 struct _Eio_File_Direct_Ls
@@ -285,7 +290,10 @@ struct _Eio_File_Direct_Ls
    Eio_File_Ls ls;
 
    Eio_Filter_Direct_Cb filter_cb;
-   Eio_Main_Direct_Cb main_cb;
+   union {
+      Eio_Main_Direct_Cb main_cb;
+      Eio_Array_Cb main_internal_cb;
+   };
 
    Eina_List *pack;
    double start;
@@ -296,7 +304,10 @@ struct _Eio_File_Dir_Ls
    Eio_File_Ls ls;
 
    Eio_Filter_Dir_Cb filter_cb;
-   Eio_Main_Direct_Cb main_cb;
+   union {
+      Eio_Main_Direct_Cb main_cb;
+      Eio_Array_Cb main_internal_cb;
+   };
 
    Eina_List *pack;
    double start;
@@ -307,7 +318,10 @@ struct _Eio_File_Char_Ls
    Eio_File_Ls ls;
 
    Eio_Filter_Cb filter_cb;
-   Eio_Main_Cb main_cb;
+   union {
+      Eio_Main_Cb main_cb;
+      Eio_Array_Cb main_internal_cb;
+   };
 };
 
 struct _Eio_File_Mkdir
@@ -506,4 +520,35 @@ void eio_common_free(Eio_File *common);
 void eio_file_register(Eio_File *common);
 void eio_file_unregister(Eio_File *common);
 
+Eio_File * _eio_file_ls(const char *dir,
+                        Eio_Array_Cb main_internal_cb,
+                        Eio_Done_Cb done_cb,
+                        Eio_Error_Cb error_cb,
+                        const void *data);
+Eio_File * _eio_file_direct_ls(const char *dir,
+                               Eio_Array_Cb main_internal_cb,
+                               Eio_Done_Cb done_cb,
+                               Eio_Error_Cb error_cb,
+                               const void *data);
+Eio_File * _eio_dir_direct_ls(const char *dir,
+                              Eio_Array_Cb main_internal_cb,
+                              Eio_Done_Cb done_cb,
+                              Eio_Error_Cb error_cb,
+                              const void *data);
+Eio_File * _eio_file_stat_ls(const char *dir,
+                             Eio_Array_Cb main_internal_cb,
+                             Eio_Done_Cb done_cb,
+                             Eio_Error_Cb error_cb,
+                             const void *data);
+Eio_File * _eio_dir_stat_ls(const char *dir,
+                            Eio_Array_Cb main_internal_cb,
+                            Eio_Done_Cb done_cb,
+                            Eio_Error_Cb error_cb,
+                            const void *data);
+
+// Sharing notifier between recursive and non recursive code.
+void _eio_string_notify(void *data, Ecore_Thread *thread EINA_UNUSED, void *msg_data);
+void _eio_direct_notify(void *data, Ecore_Thread *thread EINA_UNUSED, void *msg_data);
+
+
 #endif