[eio] reorganize code like eina, clean up doc

SVN revision: 53688
This commit is contained in:
Vincent Torri 2010-10-20 19:17:30 +00:00
parent 6b588fbef6
commit 3a5d43ea9c
5 changed files with 347 additions and 222 deletions

View File

@ -73,7 +73,17 @@ extern "C" {
* @{
*/
typedef enum _Eio_File_Op
/**
* @typedef Eio_File_Op
* Input/Output operations on files.
*/
typedef enum _Eio_File_Op Eio_File_Op;
/**
* @enum _Eio_File_Op
* Input/Output operations on files.
*/
enum _Eio_File_Op
{
EIO_FILE_COPY, /**< IO operation is about a specific file copy */
EIO_FILE_MOVE, /**< IO operation is about a specific file move */
@ -82,10 +92,19 @@ typedef enum _Eio_File_Op
EIO_UNLINK, /**< IO operation is about a destroying a path (source will point to base path to be destroyed and dest to path destroyed by this IO */
EIO_FILE_GETPWNAM, /**< IO operation is trying to get uid from user name */
EIO_FILE_GETGRNAM /**< IO operation is trying to get gid from user name */
} Eio_File_Op;
};
typedef struct _Eio_File Eio_File; /**< Generic asynchronous IO reference */
typedef struct _Eio_Progress Eio_Progress; /**< Progress information on a specific operation */
/**
* @typedef Eio_File
*Generic asynchronous IO reference.
*/
typedef struct _Eio_File Eio_File;
/**
* @typedef Eio_Progress
* Progress information on a specific operation.
*/
typedef struct _Eio_Progress Eio_Progress;
typedef Eina_Bool (*Eio_Filter_Cb)(void *data, const char *file);
typedef void (*Eio_Main_Cb)(void *data, const char *file);

View File

@ -19,6 +19,14 @@
#include "eio_private.h"
#include "Eio.h"
/*============================================================================*
* Local *
*============================================================================*/
/**
* @cond LOCAL
*/
static int
eio_strcmp(const void *a, const void *b)
{
@ -537,6 +545,20 @@ _eio_dir_rmrf_heavy(Ecore_Thread *thread, void *data)
return;
}
/**
* @endcond
*/
/*============================================================================*
* Global *
*============================================================================*/
/*============================================================================*
* API *
*============================================================================*/
/**
* @addtogroup Eio_Group Asynchronous Inout/Output library
*

View File

@ -21,6 +21,14 @@
#include "eio_private.h"
#include "Eio.h"
/*============================================================================*
* Local *
*============================================================================*/
/**
* @cond LOCAL
*/
static void
_eio_file_heavy(Ecore_Thread *thread, void *data)
{
@ -154,14 +162,6 @@ _eio_file_write(int fd, void *mem, ssize_t length)
return EINA_TRUE;
}
void
eio_progress_cb(Eio_Progress *progress, Eio_File_Progress *op)
{
op->progress_cb((void *) op->common.data, progress);
eio_progress_free(progress);
}
#ifndef MAP_HUGETLB
# define MAP_HUGETLB 0
#endif
@ -254,63 +254,6 @@ _eio_file_copy_splice(Ecore_Thread *thread, Eio_File_Progress *op, int in, int o
}
#endif
Eina_Bool
eio_file_copy_do(Ecore_Thread *thread, Eio_File_Progress *copy)
{
struct stat buf;
int result = -1;
int in = -1;
int out = -1;
in = open(copy->source, O_RDONLY);
if (in < 0)
{
eio_file_thread_error(&copy->common, thread);
return EINA_FALSE;
}
/*
As we need file size for progression information and both copy method
call fstat (better than stat as it avoid race condition).
*/
if (fstat(in, &buf) < 0)
goto on_error;
/* open write */
out = open(copy->dest, O_WRONLY | O_CREAT | O_TRUNC, buf.st_mode);
if (out < 0)
goto on_error;
#ifdef EFL_HAVE_SPLICE
/* fast file copy code using Linux splice API */
result = _eio_file_copy_splice(thread, copy, in, out, buf.st_size);
if (result == 0)
goto on_error;
#endif
/* classic copy method using mmap and write */
if (result == -1 && !_eio_file_copy_mmap(thread, copy, in, out, buf.st_size))
goto on_error;
/* change access right to match source */
if (fchmod(out, buf.st_mode) != 0)
goto on_error;
close(out);
close(in);
return EINA_TRUE;
on_error:
eio_file_thread_error(&copy->common, thread);
if (in >= 0) close(in);
if (out >= 0) close(out);
if (out >= 0)
unlink(copy->dest);
return EINA_FALSE;
}
static void
_eio_file_copy_heavy(Ecore_Thread *thread, void *data)
{
@ -482,6 +425,92 @@ _eio_file_move_error(void *data)
_eio_file_move_free(move);
}
/**
* @endcond
*/
/*============================================================================*
* Global *
*============================================================================*/
/**
* @cond LOCAL
*/
void
eio_progress_cb(Eio_Progress *progress, Eio_File_Progress *op)
{
op->progress_cb((void *) op->common.data, progress);
eio_progress_free(progress);
}
Eina_Bool
eio_file_copy_do(Ecore_Thread *thread, Eio_File_Progress *copy)
{
struct stat buf;
int result = -1;
int in = -1;
int out = -1;
in = open(copy->source, O_RDONLY);
if (in < 0)
{
eio_file_thread_error(&copy->common, thread);
return EINA_FALSE;
}
/*
As we need file size for progression information and both copy method
call fstat (better than stat as it avoid race condition).
*/
if (fstat(in, &buf) < 0)
goto on_error;
/* open write */
out = open(copy->dest, O_WRONLY | O_CREAT | O_TRUNC, buf.st_mode);
if (out < 0)
goto on_error;
#ifdef EFL_HAVE_SPLICE
/* fast file copy code using Linux splice API */
result = _eio_file_copy_splice(thread, copy, in, out, buf.st_size);
if (result == 0)
goto on_error;
#endif
/* classic copy method using mmap and write */
if (result == -1 && !_eio_file_copy_mmap(thread, copy, in, out, buf.st_size))
goto on_error;
/* change access right to match source */
if (fchmod(out, buf.st_mode) != 0)
goto on_error;
close(out);
close(in);
return EINA_TRUE;
on_error:
eio_file_thread_error(&copy->common, thread);
if (in >= 0) close(in);
if (out >= 0) close(out);
if (out >= 0)
unlink(copy->dest);
return EINA_FALSE;
}
/**
* @endcond
*/
/*============================================================================*
* API *
*============================================================================*/
/**
* @addtogroup Eio_Group Asynchronous Inout/Output library

View File

@ -19,7 +19,13 @@
#include "eio_private.h"
#include "Eio.h"
static int _eio_count = 0;
/*============================================================================*
* Local *
*============================================================================*/
/**
* @cond LOCAL
*/
/* Progress pool */
typedef struct _Eio_Alloc_Pool Eio_Alloc_Pool;
@ -32,9 +38,112 @@ struct _Eio_Alloc_Pool
pthread_mutex_t lock;
};
static int _eio_count = 0;
static Eio_Alloc_Pool progress = { 0, NULL, PTHREAD_MUTEX_INITIALIZER };
static Eio_Alloc_Pool direct_info = { 0, NULL, PTHREAD_MUTEX_INITIALIZER };
static void *
_eio_pool_malloc(Eio_Alloc_Pool *pool, size_t sz)
{
void *result = NULL;
if (pool->count)
{
pthread_mutex_lock(&pool->lock);
result = eina_trash_pop(&pool->trash);
if (result) pool->count--;
pthread_mutex_unlock(&pool->lock);
}
if (!result) result = malloc(sz);
return result;
}
static void
_eio_pool_free(Eio_Alloc_Pool *pool, void *data)
{
if (pool->count >= EIO_PROGRESS_LIMIT)
{
free(data);
}
else
{
pthread_mutex_lock(&pool->lock);
eina_trash_push(&pool->trash, data);
pool->count++;
pthread_mutex_unlock(&pool->lock);
}
}
/**
* @endcond
*/
/*============================================================================*
* Global *
*============================================================================*/
/**
* @cond LOCAL
*/
Eio_Progress *
eio_progress_malloc(void)
{
return _eio_pool_malloc(&progress, sizeof (Eio_Progress));
}
void
eio_progress_free(Eio_Progress *data)
{
eina_stringshare_del(data->source);
eina_stringshare_del(data->dest);
_eio_pool_free(&progress, data);
}
void
eio_progress_send(Ecore_Thread *thread, Eio_File_Progress *op, off_t current, off_t max)
{
Eio_Progress *progress;
if (op->progress_cb == NULL)
return ;
progress = eio_progress_malloc();
if (!progress) return ;
progress->op = op->op;
progress->current = current;
progress->max = max;
progress->percent = (float) current * 100.0 / (float) max;
progress->source = eina_stringshare_ref(op->source);
progress->dest = eina_stringshare_ref(op->dest);
ecore_thread_feedback(thread, progress);
}
Eina_File_Direct_Info *
eio_direct_info_malloc(void)
{
return _eio_pool_malloc(&direct_info, sizeof (Eina_File_Direct_Info) + sizeof (struct dirent));
}
void
eio_direct_info_free(Eina_File_Direct_Info *data)
{
_eio_pool_free(&direct_info, data);
}
/**
* @endcond
*/
/*============================================================================*
* API *
*============================================================================*/
/**
* @addtogroup Eio_Group Asynchronous Inout/Output library
@ -87,87 +196,6 @@ eio_shutdown(void)
return _eio_count;
}
static void *
_eio_pool_malloc(Eio_Alloc_Pool *pool, size_t sz)
{
void *result = NULL;
if (pool->count)
{
pthread_mutex_lock(&pool->lock);
result = eina_trash_pop(&pool->trash);
if (result) pool->count--;
pthread_mutex_unlock(&pool->lock);
}
if (!result) result = malloc(sz);
return result;
}
static void
_eio_pool_free(Eio_Alloc_Pool *pool, void *data)
{
if (pool->count >= EIO_PROGRESS_LIMIT)
{
free(data);
}
else
{
pthread_mutex_lock(&pool->lock);
eina_trash_push(&pool->trash, data);
pool->count++;
pthread_mutex_unlock(&pool->lock);
}
}
Eio_Progress *
eio_progress_malloc(void)
{
return _eio_pool_malloc(&progress, sizeof (Eio_Progress));
}
void
eio_progress_free(Eio_Progress *data)
{
eina_stringshare_del(data->source);
eina_stringshare_del(data->dest);
_eio_pool_free(&progress, data);
}
void
eio_progress_send(Ecore_Thread *thread, Eio_File_Progress *op, off_t current, off_t max)
{
Eio_Progress *progress;
if (op->progress_cb == NULL)
return ;
progress = eio_progress_malloc();
if (!progress) return ;
progress->op = op->op;
progress->current = current;
progress->max = max;
progress->percent = (float) current * 100.0 / (float) max;
progress->source = eina_stringshare_ref(op->source);
progress->dest = eina_stringshare_ref(op->dest);
ecore_thread_feedback(thread, progress);
}
Eina_File_Direct_Info *
eio_direct_info_malloc(void)
{
return _eio_pool_malloc(&direct_info, sizeof (Eina_File_Direct_Info) + sizeof (struct dirent));
}
void
eio_direct_info_free(Eina_File_Direct_Info *data)
{
_eio_pool_free(&direct_info, data);
}
/**
* @}
*/

View File

@ -21,78 +21,13 @@
#include "eio_private.h"
#include "Eio.h"
void
eio_file_error(Eio_File *common)
{
if (common->error_cb)
common->error_cb(common->error, (void*) common->data);
}
/*============================================================================*
* Local *
*============================================================================*/
void
eio_file_thread_error(Eio_File *common, Ecore_Thread *thread)
{
common->error = errno;
ecore_thread_cancel(thread);
}
Eina_Bool
eio_long_file_set(Eio_File *common,
Eio_Done_Cb done_cb,
Eio_Error_Cb error_cb,
const void *data,
Ecore_Thread_Heavy_Cb heavy_cb,
Ecore_Thread_Notify_Cb notify_cb,
Ecore_Cb end_cb,
Ecore_Cb cancel_cb)
{
Ecore_Thread *thread;
common->done_cb = done_cb;
common->error_cb = error_cb;
common->data = data;
common->error = 0;
common->thread = NULL;
/* Be aware that ecore_thread_run could call cancel_cb if something goes wrong.
This means that common would be destroyed if thread == NULL.
*/
thread = ecore_thread_feedback_run(heavy_cb,
notify_cb,
end_cb,
cancel_cb,
common,
EINA_TRUE);
if (thread) common->thread = thread;
return !!thread;
}
Eina_Bool
eio_file_set(Eio_File *common,
Eio_Done_Cb done_cb,
Eio_Error_Cb error_cb,
const void *data,
Ecore_Thread_Heavy_Cb job_cb,
Ecore_Cb end_cb,
Ecore_Cb cancel_cb)
{
Ecore_Thread *thread;
common->done_cb = done_cb;
common->error_cb = error_cb;
common->data = data;
common->error = 0;
common->thread = NULL;
/* Be aware that ecore_thread_run could call cancel_cb if something goes wrong.
This means that common would be destroyed if thread == NULL.
*/
thread = ecore_thread_run(job_cb, end_cb, cancel_cb, common);
if (thread) common->thread = thread;
return !!thread;
}
/* --- */
/**
* @cond LOCAL
*/
static void
_eio_file_mkdir(Ecore_Thread *thread, void *data)
@ -297,6 +232,98 @@ _eio_file_chown_error(void *data)
_eio_chown_free(ch);
}
/**
* @endcond
*/
/*============================================================================*
* Global *
*============================================================================*/
/**
* @cond LOCAL
*/
void
eio_file_error(Eio_File *common)
{
if (common->error_cb)
common->error_cb(common->error, (void*) common->data);
}
void
eio_file_thread_error(Eio_File *common, Ecore_Thread *thread)
{
common->error = errno;
ecore_thread_cancel(thread);
}
Eina_Bool
eio_long_file_set(Eio_File *common,
Eio_Done_Cb done_cb,
Eio_Error_Cb error_cb,
const void *data,
Ecore_Thread_Heavy_Cb heavy_cb,
Ecore_Thread_Notify_Cb notify_cb,
Ecore_Cb end_cb,
Ecore_Cb cancel_cb)
{
Ecore_Thread *thread;
common->done_cb = done_cb;
common->error_cb = error_cb;
common->data = data;
common->error = 0;
common->thread = NULL;
/* Be aware that ecore_thread_run could call cancel_cb if something goes wrong.
This means that common would be destroyed if thread == NULL.
*/
thread = ecore_thread_feedback_run(heavy_cb,
notify_cb,
end_cb,
cancel_cb,
common,
EINA_TRUE);
if (thread) common->thread = thread;
return !!thread;
}
Eina_Bool
eio_file_set(Eio_File *common,
Eio_Done_Cb done_cb,
Eio_Error_Cb error_cb,
const void *data,
Ecore_Thread_Heavy_Cb job_cb,
Ecore_Cb end_cb,
Ecore_Cb cancel_cb)
{
Ecore_Thread *thread;
common->done_cb = done_cb;
common->error_cb = error_cb;
common->data = data;
common->error = 0;
common->thread = NULL;
/* Be aware that ecore_thread_run could call cancel_cb if something goes wrong.
This means that common would be destroyed if thread == NULL.
*/
thread = ecore_thread_run(job_cb, end_cb, cancel_cb, common);
if (thread) common->thread = thread;
return !!thread;
}
/**
* @endcond
*/
/*============================================================================*
* API *
*============================================================================*/
/**
* @addtogroup Eio_Group Asynchronous Inout/Output library
*