diff --git a/src/lib/eio/eio_dir.c b/src/lib/eio/eio_dir.c index 9d0c72e7bf..e275ae9f70 100644 --- a/src/lib/eio/eio_dir.c +++ b/src/lib/eio/eio_dir.c @@ -741,29 +741,6 @@ _eio_dir_direct_find_heavy(void *data, Ecore_Thread *thread) async->pack = NULL; } -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) { @@ -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,92 @@ 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; + + return &async->ls.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) +{ + 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(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->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_direct_notify, _eio_dir_stat_done, _eio_dir_stat_error)) return NULL; @@ -967,29 +1020,19 @@ eio_dir_direct_ls(const char *dir, 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); - - if (!eio_long_file_set(&async->ls.common, - done_cb, - error_cb, - data, - _eio_dir_direct_find_heavy, - _eio_dir_stat_find_notify, - _eio_dir_stat_done, - _eio_dir_stat_error)) - return NULL; - - return &async->ls.common; + 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); } diff --git a/src/lib/eio/eio_file.c b/src/lib/eio/eio_file.c index a7c02b9a40..1afa4ab165 100644 --- a/src/lib/eio/eio_file.c +++ b/src/lib/eio/eio_file.c @@ -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,6 +531,48 @@ eio_async_error(void *data, Ecore_Thread *thread EINA_UNUSED) /*============================================================================* * API * *============================================================================*/ +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(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->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_string_notify, + eio_async_end, + eio_async_error)) + return NULL; + + return &async->ls.common; +} EAPI Eio_File * eio_file_ls(const char *dir, @@ -500,26 +582,59 @@ eio_file_ls(const char *dir, Eio_Error_Cb error_cb, const void *data) { - Eio_File_Char_Ls *async; + 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_Char_Ls)); + 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_heavy, - _eio_file_notify, + _eio_file_direct_heavy, + _eio_direct_notify, eio_async_end, eio_async_error)) return NULL; @@ -534,27 +649,60 @@ eio_file_direct_ls(const char *dir, 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_direct_heavy, - _eio_file_direct_notify, + _eio_file_stat_heavy, + _eio_direct_notify, eio_async_end, eio_async_error)) return NULL; @@ -570,31 +718,21 @@ eio_file_stat_ls(const char *dir, 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); + return _eio_file_stat_internal_ls(dir, filter_cb, main_cb, NULL, done_cb, error_cb, data); +} - async->filter_cb = filter_cb; - async->main_cb = main_cb; - async->ls.directory = eina_stringshare_add(dir); +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); - if (!eio_long_file_set(&async->ls.common, - done_cb, - error_cb, - data, - _eio_file_stat_heavy, - _eio_file_direct_notify, - eio_async_end, - eio_async_error)) - return NULL; - - return &async->ls.common; + return _eio_file_stat_internal_ls(dir, NULL, NULL, main_internal_cb, done_cb, error_cb, data); } EAPI Eina_Bool diff --git a/src/lib/eio/eio_private.h b/src/lib/eio/eio_private.h index 39c37ae20b..69a73d3020 100644 --- a/src/lib/eio/eio_private.h +++ b/src/lib/eio/eio_private.h @@ -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