forked from enlightenment/efl
eio: associate data to a file behing listed assynchronously.
SVN revision: 60043
This commit is contained in:
parent
260718c700
commit
19d5fb205a
|
@ -142,8 +142,30 @@ _eio_file_heavy(void *data, Ecore_Thread *thread)
|
|||
filter = async->filter_cb((void*) async->ls.common.data, &async->ls.common, file);
|
||||
}
|
||||
|
||||
if (filter) ecore_thread_feedback(thread, file);
|
||||
else eina_stringshare_del(file);
|
||||
if (filter)
|
||||
{
|
||||
Eio_File_Char *send;
|
||||
|
||||
send = eio_char_malloc();
|
||||
if (!send) goto on_error;
|
||||
|
||||
send->filename = file;
|
||||
send->associated = async->ls.common.worker.associated;
|
||||
async->ls.common.worker.associated = NULL;
|
||||
|
||||
ecore_thread_feedback(thread, send);
|
||||
}
|
||||
else
|
||||
{
|
||||
on_error:
|
||||
eina_stringshare_del(file);
|
||||
|
||||
if (async->ls.common.worker.associated)
|
||||
{
|
||||
eina_hash_free(async->ls.common.worker.associated);
|
||||
async->ls.common.worker.associated = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if (ecore_thread_check(thread))
|
||||
break;
|
||||
|
@ -158,11 +180,22 @@ static void
|
|||
_eio_file_notify(void *data, Ecore_Thread *thread __UNUSED__, void *msg_data)
|
||||
{
|
||||
Eio_File_Char_Ls *async = data;
|
||||
const char *file = msg_data;
|
||||
Eio_File_Char *info = msg_data;
|
||||
|
||||
async->main_cb((void*) async->ls.common.data, &async->ls.common, file);
|
||||
async->ls.common.main.associated = info->associated;
|
||||
|
||||
eina_stringshare_del(file);
|
||||
async->main_cb((void*) async->ls.common.data,
|
||||
&async->ls.common,
|
||||
info->filename);
|
||||
|
||||
if (async->ls.common.main.associated)
|
||||
{
|
||||
eina_hash_free(async->ls.common.main.associated);
|
||||
async->ls.common.main.associated = NULL;
|
||||
}
|
||||
|
||||
eina_stringshare_del(info->filename);
|
||||
eio_char_free(info);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -189,15 +222,22 @@ _eio_file_eina_ls_heavy(Ecore_Thread *thread, Eio_File_Direct_Ls *async, Eina_It
|
|||
|
||||
if (filter)
|
||||
{
|
||||
Eina_File_Direct_Info *send;
|
||||
Eio_File_Direct_Info *send;
|
||||
|
||||
send = eio_direct_info_malloc();
|
||||
if (!send) continue;
|
||||
|
||||
memcpy(send, info, sizeof (Eina_File_Direct_Info));
|
||||
memcpy(&send->info, info, sizeof (Eina_File_Direct_Info));
|
||||
send->associated = async->ls.common.worker.associated;
|
||||
async->ls.common.worker.associated = NULL;
|
||||
|
||||
ecore_thread_feedback(thread, send);
|
||||
}
|
||||
else if (async->ls.common.worker.associated)
|
||||
{
|
||||
eina_hash_free(async->ls.common.worker.associated);
|
||||
async->ls.common.worker.associated = NULL;
|
||||
}
|
||||
|
||||
if (ecore_thread_check(thread))
|
||||
break;
|
||||
|
@ -234,16 +274,28 @@ static void
|
|||
_eio_file_direct_notify(void *data, Ecore_Thread *thread __UNUSED__, void *msg_data)
|
||||
{
|
||||
Eio_File_Direct_Ls *async = data;
|
||||
Eina_File_Direct_Info *info = msg_data;
|
||||
Eio_File_Direct_Info *info = msg_data;
|
||||
|
||||
async->main_cb((void*) async->ls.common.data, &async->ls.common, 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);
|
||||
}
|
||||
|
||||
#ifdef HAVE_XATTR
|
||||
static void
|
||||
_eio_file_copy_xattr(Ecore_Thread *thread, Eio_File_Progress *op, int in, int out)
|
||||
_eio_file_copy_xattr(Ecore_Thread *thread __UNUSED__,
|
||||
Eio_File_Progress *op __UNUSED__,
|
||||
int in, int out)
|
||||
{
|
||||
char *tmp;
|
||||
ssize_t length;
|
||||
|
@ -849,6 +901,75 @@ eio_file_container_get(Eio_File *ls)
|
|||
return ls->container;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Associate data with the current filtered file.
|
||||
* @param ls The Eio_File ls request currently calling the filter callback.
|
||||
* @param key The key to associate data to.
|
||||
* @param data The data to associate the data to.
|
||||
* @param free_cb The function to call to free the associated data, @p free will be called if not specified.
|
||||
* @return EINA_TRUE if insertion was fine.
|
||||
*
|
||||
* This function could only be safely called from within the filter callback.
|
||||
* If you don't need to copy the key around you can use @ref eio_file_associate_direct_add
|
||||
*/
|
||||
EAPI Eina_Bool
|
||||
eio_file_associate_add(Eio_File *ls,
|
||||
const char *key,
|
||||
void *data, Eina_Free_Cb free_cb)
|
||||
{
|
||||
/* FIXME: Check if we are in the right worker thred */
|
||||
if (!ls->worker.associated)
|
||||
ls->worker.associated = eina_hash_string_small_new(eio_associate_free);
|
||||
|
||||
return eina_hash_add(ls->worker.associated,
|
||||
key,
|
||||
eio_associate_malloc(data, free_cb));
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Associate data with the current filtered file.
|
||||
* @param ls The Eio_File ls request currently calling the filter callback.
|
||||
* @param key The key to associate data to (will not be copied, and the pointer will be used as long as the file is not notified).
|
||||
* @param data The data to associate the data to.
|
||||
* @param free_cb The function to call to free the associated data, @p free will be called if not specified.
|
||||
* @return EINA_TRUE if insertion was fine.
|
||||
*
|
||||
* This function could only be safely called from within the filter callback.
|
||||
* If you need eio to make a proper copy of the @p key to be safe use
|
||||
* @ref eio_file_associate_add instead.
|
||||
*/
|
||||
EAPI Eina_Bool
|
||||
eio_file_associate_direct_add(Eio_File *ls,
|
||||
const char *key,
|
||||
void *data, Eina_Free_Cb free_cb)
|
||||
{
|
||||
/* FIXME: Check if we are in the right worker thred */
|
||||
if (!ls->worker.associated)
|
||||
ls->worker.associated = eina_hash_string_small_new(eio_associate_free);
|
||||
|
||||
return eina_hash_direct_add(ls->worker.associated,
|
||||
key,
|
||||
eio_associate_malloc(data, free_cb));
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get the data associated during the filter callback inside the main loop
|
||||
* @param ls The Eio_File ls request currently calling the notify callback.
|
||||
* @param key The key pointing to the data to retrieve.
|
||||
* @return the data associated with the key or @p NULL if not found.
|
||||
*/
|
||||
EAPI void *
|
||||
eio_file_associate_find(Eio_File *ls, const char *key)
|
||||
{
|
||||
Eio_File_Associate *search;
|
||||
|
||||
if (!ls->main.associated)
|
||||
return NULL;
|
||||
|
||||
search = eina_hash_find(ls->main.associated, key);
|
||||
if (!search) return NULL;
|
||||
return search->data;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Copy a file asynchronously
|
||||
|
|
|
@ -59,7 +59,9 @@ struct _Eio_Alloc_Pool
|
|||
static int _eio_count = 0;
|
||||
|
||||
static Eio_Alloc_Pool progress_pool = { 0, NULL, EIO_MUTEX_INITIALIZER };
|
||||
static Eio_Alloc_Pool direct_info = { 0, NULL, EIO_MUTEX_INITIALIZER };
|
||||
static Eio_Alloc_Pool direct_info_pool = { 0, NULL, EIO_MUTEX_INITIALIZER };
|
||||
static Eio_Alloc_Pool char_pool = { 0, NULL, EIO_MUTEX_INITIALIZER };
|
||||
static Eio_Alloc_Pool associate_pool = { 0, NULL, EIO_MUTEX_INITIALIZER };
|
||||
|
||||
static void *
|
||||
_eio_pool_malloc(Eio_Alloc_Pool *pool, size_t sz)
|
||||
|
@ -142,18 +144,57 @@ eio_progress_send(Ecore_Thread *thread, Eio_File_Progress *op, long long current
|
|||
ecore_thread_feedback(thread, progress);
|
||||
}
|
||||
|
||||
Eina_File_Direct_Info *
|
||||
Eio_File_Direct_Info *
|
||||
eio_direct_info_malloc(void)
|
||||
{
|
||||
return _eio_pool_malloc(&direct_info, sizeof (Eina_File_Direct_Info));
|
||||
return _eio_pool_malloc(&direct_info_pool, sizeof (Eio_File_Direct_Info));
|
||||
}
|
||||
|
||||
void
|
||||
eio_direct_info_free(Eina_File_Direct_Info *data)
|
||||
eio_direct_info_free(Eio_File_Direct_Info *data)
|
||||
{
|
||||
_eio_pool_free(&direct_info, data);
|
||||
_eio_pool_free(&direct_info_pool, data);
|
||||
}
|
||||
|
||||
Eio_File_Char *
|
||||
eio_char_malloc(void)
|
||||
{
|
||||
return _eio_pool_malloc(&char_pool, sizeof (Eio_File_Char));
|
||||
}
|
||||
|
||||
void
|
||||
eio_char_free(Eio_File_Char *data)
|
||||
{
|
||||
_eio_pool_free(&char_pool, data);
|
||||
}
|
||||
|
||||
Eio_File_Associate *
|
||||
eio_associate_malloc(void *data, Eina_Free_Cb free_cb)
|
||||
{
|
||||
Eio_File_Associate *tmp;
|
||||
|
||||
tmp = _eio_pool_malloc(&associate_pool, sizeof (Eio_File_Associate));
|
||||
if (!tmp) return tmp;
|
||||
|
||||
tmp->data = data;
|
||||
tmp->free_cb = free_cb ? free_cb : free;
|
||||
|
||||
return tmp;
|
||||
}
|
||||
|
||||
void
|
||||
eio_associate_free(void *data)
|
||||
{
|
||||
Eio_File_Associate *tmp;
|
||||
|
||||
if (!data) return ;
|
||||
|
||||
tmp = data;
|
||||
tmp->free_cb(tmp->data);
|
||||
_eio_pool_free(&associate_pool, tmp);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @endcond
|
||||
*/
|
||||
|
@ -184,7 +225,9 @@ eio_init(void)
|
|||
ecore_init();
|
||||
|
||||
EIO_MUTEX_INIT(progress_pool);
|
||||
EIO_MUTEX_INIT(direct_info);
|
||||
EIO_MUTEX_INIT(direct_info_pool);
|
||||
EIO_MUTEX_INIT(char_pool);
|
||||
EIO_MUTEX_INIT(associate_pool);
|
||||
|
||||
eio_monitor_init();
|
||||
|
||||
|
@ -198,8 +241,10 @@ eio_init(void)
|
|||
EAPI int
|
||||
eio_shutdown(void)
|
||||
{
|
||||
Eina_File_Direct_Info *info;
|
||||
Eio_File_Direct_Info *info;
|
||||
Eio_File_Char *cin;
|
||||
Eio_Progress *pg;
|
||||
Eio_File_Associate *asso;
|
||||
|
||||
_eio_count--;
|
||||
|
||||
|
@ -207,15 +252,25 @@ eio_shutdown(void)
|
|||
|
||||
EIO_MUTEX_DESTROY(direct_info);
|
||||
EIO_MUTEX_DESTROY(progress_pool);
|
||||
EIO_MUTEX_DESTROY(char_pool);
|
||||
EIO_MUTEX_DESTROY(associate_pool);
|
||||
|
||||
/* Cleanup pool */
|
||||
EINA_TRASH_CLEAN(&progress_pool.trash, pg)
|
||||
free(pg);
|
||||
progress_pool.count = 0;
|
||||
|
||||
EINA_TRASH_CLEAN(&direct_info.trash, info)
|
||||
EINA_TRASH_CLEAN(&direct_info_pool.trash, info)
|
||||
free(info);
|
||||
direct_info.count = 0;
|
||||
direct_info_pool.count = 0;
|
||||
|
||||
EINA_TRASH_CLEAN(&char_pool.trash, cin)
|
||||
free(cin);
|
||||
char_pool.count = 0;
|
||||
|
||||
EINA_TRASH_CLEAN(&associate_pool.trash, asso)
|
||||
free(asso);
|
||||
associate_pool.count = 0;
|
||||
|
||||
ecore_shutdown();
|
||||
eina_shutdown();
|
||||
|
|
|
@ -63,6 +63,32 @@ typedef struct _Eio_Monitor_Backend Eio_Monitor_Backend;
|
|||
|
||||
typedef struct _Eio_Dir_Copy Eio_Dir_Copy;
|
||||
|
||||
typedef struct _Eio_File_Direct_Info Eio_File_Direct_Info;
|
||||
typedef struct _Eio_File_Char Eio_File_Char;
|
||||
|
||||
typedef struct _Eio_File_Associate Eio_File_Associate;
|
||||
|
||||
struct _Eio_File_Associate
|
||||
{
|
||||
void *data;
|
||||
|
||||
Eina_Free_Cb free_cb;
|
||||
};
|
||||
|
||||
struct _Eio_File_Direct_Info
|
||||
{
|
||||
Eina_File_Direct_Info info;
|
||||
|
||||
Eina_Hash *associated;
|
||||
};
|
||||
|
||||
struct _Eio_File_Char
|
||||
{
|
||||
const char *filename;
|
||||
|
||||
Eina_Hash *associated;
|
||||
};
|
||||
|
||||
struct _Eio_File
|
||||
{
|
||||
Ecore_Thread *thread;
|
||||
|
@ -73,6 +99,10 @@ struct _Eio_File
|
|||
|
||||
Eio_Error_Cb error_cb;
|
||||
Eio_Done_Cb done_cb;
|
||||
|
||||
struct {
|
||||
Eina_Hash *associated;
|
||||
} worker, main;
|
||||
};
|
||||
|
||||
struct _Eio_File_Ls
|
||||
|
@ -198,8 +228,14 @@ void eio_file_container_set(Eio_File *common, void *container);
|
|||
void eio_file_error(Eio_File *common);
|
||||
void eio_file_thread_error(Eio_File *common, Ecore_Thread *thread);
|
||||
|
||||
Eina_File_Direct_Info *eio_direct_info_malloc(void);
|
||||
void eio_direct_info_free(Eina_File_Direct_Info *data);
|
||||
Eio_File_Direct_Info *eio_direct_info_malloc(void);
|
||||
void eio_direct_info_free(Eio_File_Direct_Info *data);
|
||||
|
||||
Eio_File_Char *eio_char_malloc(void);
|
||||
void eio_char_free(Eio_File_Char *data);
|
||||
|
||||
Eio_File_Associate *eio_associate_malloc(void *data, Eina_Free_Cb free_cb);
|
||||
void eio_associate_free(void *data);
|
||||
|
||||
Eio_Progress *eio_progress_malloc(void);
|
||||
void eio_progress_free(Eio_Progress *progress);
|
||||
|
|
|
@ -276,6 +276,8 @@ eio_long_file_set(Eio_File *common,
|
|||
common->error = 0;
|
||||
common->thread = NULL;
|
||||
common->container = NULL;
|
||||
common->worker.associated = NULL;
|
||||
common->main.associated = NULL;
|
||||
|
||||
/* Be aware that ecore_thread_feedback_run could call cancel_cb if something goes wrong.
|
||||
This means that common would be destroyed if thread == NULL.
|
||||
|
|
Loading…
Reference in New Issue