forked from enlightenment/efl
* eio: Add an error callback, some docs and a small README.
SVN revision: 50446
This commit is contained in:
parent
2ac69e62f0
commit
4df9bbead1
|
@ -0,0 +1,10 @@
|
|||
Enlightenment Input Output Library
|
||||
==================================
|
||||
|
||||
This library is intended to provide non blocking IO by using thread for all
|
||||
operation that may block. It depends only on eina and ecore right now. It
|
||||
should integrate all the features/functions of Ecore_File that could block.
|
||||
|
||||
This should become one day part of what we call the EFL and be a dependence
|
||||
of E17. Feel free to contribute, help is always appreciated !
|
||||
|
|
@ -32,7 +32,7 @@
|
|||
#endif
|
||||
|
||||
#ifdef _WIN32
|
||||
# ifdef EFL_ECORE_BUILD
|
||||
# ifdef EFL_EIO_BUILD
|
||||
# ifdef DLL_EXPORT
|
||||
# define EAPI __declspec(dllexport)
|
||||
# else
|
||||
|
@ -40,7 +40,7 @@
|
|||
# endif /* ! DLL_EXPORT */
|
||||
# else
|
||||
# define EAPI __declspec(dllimport)
|
||||
# endif /* ! EFL_ECORE_BUILD */
|
||||
# endif /* ! EFL_EIO_BUILD */
|
||||
#else
|
||||
# ifdef __GNUC__
|
||||
# if __GNUC__ >= 4
|
||||
|
@ -53,7 +53,7 @@
|
|||
# endif
|
||||
#endif /* ! _WIN32 */
|
||||
|
||||
typedef struct _Eio_List Eio_List;
|
||||
typedef struct _Eio_File Eio_File;
|
||||
|
||||
typedef Eina_Bool (*Eio_Filter_Cb)(const char *file, void *data);
|
||||
typedef void (*Eio_Main_Cb)(const char *file, void *data);
|
||||
|
@ -66,18 +66,20 @@ typedef void (*Eio_Done_Cb)(void *data);
|
|||
EAPI int eio_init(void);
|
||||
EAPI int eio_shutdown(void);
|
||||
|
||||
EAPI Eio_List *eio_file_ls(const char *dir,
|
||||
Eio_Filter_Cb filter,
|
||||
Eio_Main_Cb main,
|
||||
Eio_Done_Cb done,
|
||||
const void *data);
|
||||
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_Done_Cb error_cb,
|
||||
const void *data);
|
||||
|
||||
EAPI Eio_List *eio_file_direct_ls(const char *dir,
|
||||
Eio_Filter_Direct_Cb filter,
|
||||
Eio_Main_Direct_Cb main,
|
||||
Eio_Done_Cb done,
|
||||
const void *data);
|
||||
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_Done_Cb error_cb,
|
||||
const void *data);
|
||||
|
||||
EAPI Eina_Bool eio_file_cancel(Eio_List *list);
|
||||
EAPI Eina_Bool eio_file_cancel(Eio_File *ls);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -26,27 +26,39 @@
|
|||
|
||||
#include "Eio.h"
|
||||
|
||||
struct _Eio_List
|
||||
typedef struct _Eio_File_Ls Eio_File_Ls;
|
||||
typedef struct _Eio_File_Direct_Ls Eio_File_Direct_Ls;
|
||||
typedef struct _Eio_File_Char_Ls Eio_File_Char_Ls;
|
||||
|
||||
struct _Eio_File
|
||||
{
|
||||
Eina_Iterator *it;
|
||||
Ecore_Thread *thread;
|
||||
const void *data;
|
||||
|
||||
Eio_Done_Cb done;
|
||||
Eio_Done_Cb done_cb;
|
||||
Eio_Done_Cb error_cb;
|
||||
};
|
||||
|
||||
union
|
||||
{
|
||||
struct
|
||||
{
|
||||
Eio_Filter_Direct_Cb filter;
|
||||
Eio_Main_Direct_Cb main;
|
||||
} direct;
|
||||
struct
|
||||
{
|
||||
Eio_Filter_Cb filter;
|
||||
Eio_Main_Cb main;
|
||||
} str;
|
||||
} u;
|
||||
struct _Eio_File_Ls
|
||||
{
|
||||
Eio_File common;
|
||||
const char *directory;
|
||||
};
|
||||
|
||||
struct _Eio_File_Direct_Ls
|
||||
{
|
||||
Eio_File_Ls ls;
|
||||
|
||||
Eio_Filter_Direct_Cb filter_cb;
|
||||
Eio_Main_Direct_Cb main_cb;
|
||||
};
|
||||
|
||||
struct _Eio_File_Char_Ls
|
||||
{
|
||||
Eio_File_Ls ls;
|
||||
|
||||
Eio_Filter_Cb filter_cb;
|
||||
Eio_Main_Cb main_cb;
|
||||
};
|
||||
|
||||
static int _eio_count = 0;
|
||||
|
@ -54,36 +66,49 @@ static int _eio_count = 0;
|
|||
static void
|
||||
_eio_file_heavy(Ecore_Thread *thread, void *data)
|
||||
{
|
||||
Eio_List *async;
|
||||
Eio_File_Char_Ls *async;
|
||||
Eina_Iterator *ls;
|
||||
const char *file;
|
||||
|
||||
async = data;
|
||||
|
||||
EINA_ITERATOR_FOREACH(async->it, file)
|
||||
ls = eina_file_ls(async->ls.directory);
|
||||
if (!ls)
|
||||
{
|
||||
ecore_thread_cancel(thread);
|
||||
return ;
|
||||
}
|
||||
|
||||
EINA_ITERATOR_FOREACH(ls, file)
|
||||
{
|
||||
Eina_Bool filter = EINA_TRUE;
|
||||
|
||||
if (async->u.str.filter)
|
||||
if (async->filter_cb)
|
||||
{
|
||||
filter = async->u.str.filter(file, (void*) async->data);
|
||||
filter = async->filter_cb(file, (void*) async->ls.common.data);
|
||||
}
|
||||
|
||||
if (filter) ecore_thread_notify(thread, file);
|
||||
else eina_stringshare_del(file);
|
||||
|
||||
if (ecore_thread_check(thread))
|
||||
break;
|
||||
}
|
||||
|
||||
eina_iterator_free(ls);
|
||||
}
|
||||
|
||||
static void
|
||||
_eio_file_notify(__UNUSED__ Ecore_Thread *thread, void *msg_data, void *data)
|
||||
_eio_file_notify(Ecore_Thread *thread __UNUSED__, void *msg_data, void *data)
|
||||
{
|
||||
Eio_List *async;
|
||||
Eio_File_Char_Ls *async;
|
||||
const char *file;
|
||||
|
||||
async = data;
|
||||
file = msg_data;
|
||||
|
||||
if (async->u.str.main)
|
||||
async->u.str.main(file, (void*) async->data);
|
||||
if (async->main_cb)
|
||||
async->main_cb(file, (void*) async->ls.common.data);
|
||||
|
||||
eina_stringshare_del(file);
|
||||
}
|
||||
|
@ -91,18 +116,26 @@ _eio_file_notify(__UNUSED__ Ecore_Thread *thread, void *msg_data, void *data)
|
|||
static void
|
||||
_eio_file_direct_heavy(Ecore_Thread *thread, void *data)
|
||||
{
|
||||
Eio_List *async;
|
||||
Eio_File_Direct_Ls *async;
|
||||
Eina_Iterator *ls;
|
||||
const Eina_File_Direct_Info *info;
|
||||
|
||||
async = data;
|
||||
|
||||
EINA_ITERATOR_FOREACH(async->it, info)
|
||||
ls = eina_file_direct_ls(async->ls.directory);
|
||||
if (!ls)
|
||||
{
|
||||
ecore_thread_cancel(thread);
|
||||
return ;
|
||||
}
|
||||
|
||||
EINA_ITERATOR_FOREACH(ls, info)
|
||||
{
|
||||
Eina_Bool filter = EINA_TRUE;
|
||||
|
||||
if (async->u.direct.filter)
|
||||
if (async->filter_cb)
|
||||
{
|
||||
filter = async->u.direct.filter(info, (void*) async->data);
|
||||
filter = async->filter_cb(info, (void*) async->ls.common.data);
|
||||
}
|
||||
|
||||
if (filter)
|
||||
|
@ -115,20 +148,25 @@ _eio_file_direct_heavy(Ecore_Thread *thread, void *data)
|
|||
memcpy(send, info, sizeof (Eina_File_Direct_Info));
|
||||
ecore_thread_notify(thread, send);
|
||||
}
|
||||
|
||||
if (ecore_thread_check(thread))
|
||||
break;
|
||||
}
|
||||
|
||||
eina_iterator_free(ls);
|
||||
}
|
||||
|
||||
static void
|
||||
_eio_file_direct_notify(__UNUSED__ Ecore_Thread *thread, void *msg_data, void *data)
|
||||
_eio_file_direct_notify(Ecore_Thread *thread __UNUSED__, void *msg_data, void *data)
|
||||
{
|
||||
Eio_List *async;
|
||||
Eio_File_Direct_Ls *async;
|
||||
Eina_File_Direct_Info *info;
|
||||
|
||||
async = data;
|
||||
info = msg_data;
|
||||
|
||||
if (async->u.direct.main)
|
||||
async->u.direct.main(info, (void*) async->data);
|
||||
if (async->main_cb)
|
||||
async->main_cb(info, (void*) async->ls.common.data);
|
||||
|
||||
free(info);
|
||||
}
|
||||
|
@ -136,14 +174,28 @@ _eio_file_direct_notify(__UNUSED__ Ecore_Thread *thread, void *msg_data, void *d
|
|||
static void
|
||||
_eio_file_end(void *data)
|
||||
{
|
||||
Eio_List *async;
|
||||
Eio_File_Ls *async;
|
||||
|
||||
async = data;
|
||||
|
||||
if (async->done)
|
||||
async->done((void*) async->data);
|
||||
if (async->common.done_cb)
|
||||
async->common.done_cb((void*) async->common.data);
|
||||
|
||||
eina_iterator_free(async->it);
|
||||
eina_stringshare_del(async->directory);
|
||||
free(async);
|
||||
}
|
||||
|
||||
static void
|
||||
_eio_file_error(void *data)
|
||||
{
|
||||
Eio_File_Ls *async;
|
||||
|
||||
async = data;
|
||||
|
||||
if (async->common.error_cb)
|
||||
async->common.error_cb((void*) async->common.data);
|
||||
|
||||
eina_stringshare_del(async->directory);
|
||||
free(async);
|
||||
}
|
||||
|
||||
|
@ -172,86 +224,103 @@ eio_shutdown(void)
|
|||
return _eio_count;
|
||||
}
|
||||
|
||||
EAPI Eio_List *
|
||||
/**
|
||||
* @brief List content of a directory without locking your app.
|
||||
* @param dir The directory to list.
|
||||
* @param filter_cb Callback called from another thread.
|
||||
* @param main_cb Callback called from the main loop for each accepted file.
|
||||
* @param done_cb Callback called from the main loop when the content of the directory has been listed.
|
||||
* @param error_cb Callback called from the main loop when the directory could not be opened or listing content has been canceled.
|
||||
* @return A reference to the IO operation.
|
||||
*
|
||||
* eio_file_ls run eina_file_ls in a separated thread using ecore_long_run. This prevent
|
||||
* any lock in your apps.
|
||||
*/
|
||||
EAPI Eio_File *
|
||||
eio_file_ls(const char *dir,
|
||||
Eio_Filter_Cb filter,
|
||||
Eio_Main_Cb main,
|
||||
Eio_Done_Cb done,
|
||||
const void *data)
|
||||
Eio_Filter_Cb filter_cb,
|
||||
Eio_Main_Cb main_cb,
|
||||
Eio_Done_Cb done_cb,
|
||||
Eio_Done_Cb error_cb,
|
||||
const void *data)
|
||||
{
|
||||
Eina_Iterator *ls;
|
||||
Eio_List *async = NULL;
|
||||
Eio_File_Char_Ls *async = NULL;
|
||||
|
||||
ls = eina_file_ls(dir);
|
||||
if (!ls) return NULL;
|
||||
|
||||
async = malloc(sizeof (Eio_List));
|
||||
async = malloc(sizeof (Eio_File_Char_Ls));
|
||||
if (!async) goto on_error;
|
||||
|
||||
async->u.str.filter = filter;
|
||||
async->u.str.main = main;
|
||||
async->done = done;
|
||||
async->data = data;
|
||||
async->it = ls;
|
||||
async->thread = ecore_long_run(_eio_file_heavy,
|
||||
_eio_file_notify,
|
||||
_eio_file_end,
|
||||
_eio_file_end,
|
||||
async,
|
||||
EINA_FALSE);
|
||||
if (!async->thread) goto on_error;
|
||||
|
||||
return async;
|
||||
async->filter_cb = filter_cb;
|
||||
async->main_cb = main_cb;
|
||||
async->ls.directory = eina_stringshare_add(dir);
|
||||
async->ls.common.done_cb = done_cb;
|
||||
async->ls.common.error_cb = error_cb;
|
||||
async->ls.common.data = data;
|
||||
async->ls.common.thread = ecore_long_run(_eio_file_heavy,
|
||||
_eio_file_notify,
|
||||
_eio_file_end,
|
||||
_eio_file_error,
|
||||
async,
|
||||
EINA_FALSE);
|
||||
if (!async->ls.common.thread) goto on_error;
|
||||
|
||||
return &async->ls.common;
|
||||
|
||||
on_error:
|
||||
free(async);
|
||||
eina_iterator_free(ls);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
EAPI Eio_List *
|
||||
/**
|
||||
* @brief List content of a directory without locking your app.
|
||||
* @param dir The directory to list.
|
||||
* @param filter_cb Callback called from another thread.
|
||||
* @param main_cb Callback called from the main loop for each accepted file.
|
||||
* @param done_cb Callback called from the main loop when the content of the directory has been listed.
|
||||
* @param error_cb Callback called from the main loop when the directory could not be opened or listing content has been canceled.
|
||||
* @return A reference to the IO operation.
|
||||
*
|
||||
* eio_file_direct_ls run eina_file_direct_ls in a separated thread using
|
||||
* ecore_long_run. This prevent any lock in your apps.
|
||||
*/
|
||||
EAPI Eio_File *
|
||||
eio_file_direct_ls(const char *dir,
|
||||
Eio_Filter_Direct_Cb filter,
|
||||
Eio_Main_Direct_Cb main,
|
||||
Eio_Done_Cb done,
|
||||
const void *data)
|
||||
Eio_Filter_Direct_Cb filter_cb,
|
||||
Eio_Main_Direct_Cb main_cb,
|
||||
Eio_Done_Cb done_cb,
|
||||
Eio_Done_Cb error_cb,
|
||||
const void *data)
|
||||
{
|
||||
Eina_Iterator *ls;
|
||||
Eio_List *async = NULL;
|
||||
Eio_File_Direct_Ls *async = NULL;
|
||||
|
||||
ls = eina_file_direct_ls(dir);
|
||||
if (!ls) return NULL;
|
||||
|
||||
async = malloc(sizeof (Eio_List));
|
||||
async = malloc(sizeof (Eio_File_Direct_Ls));
|
||||
if (!async) goto on_error;
|
||||
|
||||
async->u.direct.filter = filter;
|
||||
async->u.direct.main = main;
|
||||
async->done = done;
|
||||
async->data = data;
|
||||
async->it = ls;
|
||||
async->thread = ecore_long_run(_eio_file_direct_heavy,
|
||||
_eio_file_direct_notify,
|
||||
_eio_file_end,
|
||||
_eio_file_end,
|
||||
async,
|
||||
EINA_FALSE);
|
||||
if (!async->thread) goto on_error;
|
||||
async->filter_cb = filter_cb;
|
||||
async->main_cb = main_cb;
|
||||
async->ls.directory = eina_stringshare_add(dir);
|
||||
async->ls.common.done_cb = done_cb;
|
||||
async->ls.common.error_cb = error_cb;
|
||||
async->ls.common.data = data;
|
||||
async->ls.common.thread = ecore_long_run(_eio_file_direct_heavy,
|
||||
_eio_file_direct_notify,
|
||||
_eio_file_end,
|
||||
_eio_file_error,
|
||||
async,
|
||||
EINA_FALSE);
|
||||
if (!async->ls.common.thread) goto on_error;
|
||||
|
||||
return async;
|
||||
return &async->ls.common;
|
||||
|
||||
|
||||
on_error:
|
||||
free(async);
|
||||
eina_iterator_free(ls);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
EAPI Eina_Bool
|
||||
eio_file_cancel(Eio_List *list)
|
||||
eio_file_cancel(Eio_File *ls)
|
||||
{
|
||||
return ecore_thread_cancel(list->thread);
|
||||
return ecore_thread_cancel(ls->thread);
|
||||
}
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue