From: Enlightenment S. <no-...@en...> - 2010-08-31 16:25:05
|
Log: * eio: start to implement new cleaner API. Author: cedric Date: 2010-08-31 09:24:58 -0700 (Tue, 31 Aug 2010) New Revision: 51784 Modified: trunk/eio/src/lib/Eio.h trunk/eio/src/lib/Makefile.am trunk/eio/src/lib/eio_file.c Modified: trunk/eio/src/lib/Eio.h =================================================================== --- trunk/eio/src/lib/Eio.h 2010-08-31 13:49:17 UTC (rev 51783) +++ trunk/eio/src/lib/Eio.h 2010-08-31 16:24:58 UTC (rev 51784) @@ -26,6 +26,10 @@ # include <Evil.h> #endif +#include <sys/types.h> +#include <sys/stat.h> +#include <unistd.h> + #include <Eina.h> #ifdef EAPI @@ -66,16 +70,27 @@ } Eio_File_Op_Flags; typedef struct _Eio_File Eio_File; +typedef struct _Eio_Progress Eio_Progress; +typedef struct _Eio_Stat Eio_Stat; typedef Eina_Bool (*Eio_Filter_Cb)(const void *data, const char *file); typedef void (*Eio_Main_Cb)(const void *data, const char *file); -typedef void (*Eio_File_Op_Main_Cb)(const void *data, Eio_File_Op_Flags flag, void *value); typedef Eina_Bool (*Eio_Filter_Direct_Cb)(const void *data, const Eina_File_Direct_Info *info); typedef void (*Eio_Main_Direct_Cb)(const void *data, const Eina_File_Direct_Info *info); +typedef void (*Eio_Stat_Cb)(const void *data, const struct stat *stat); +typedef void (*Eio_Progress_Cb)(const void *data, const Eio_Progress *info); + typedef void (*Eio_Done_Cb)(const void *data); +struct _Eio_Progress +{ + size_t current; + size_t max; + float percent; +}; + EAPI int eio_init(void); EAPI int eio_shutdown(void); @@ -93,12 +108,56 @@ Eio_Done_Cb error_cb, const void *data); +EAPI Eio_File *eio_file_direct_stat(const char *path, + Eio_Stat_Cb done_cb, + Eio_Done_Cb error_cb, + const void *data); + +EAPI Eio_File *eio_file_unlink(const char *path, + Eio_Done_Cb done_cb, + Eio_Done_Cb error_cb, + const void *data); + +EAPI Eio_File *eio_file_mkdir(const char *path, + mode_t mode, + Eio_Done_Cb done_cb, + Eio_Done_Cb error_cb, + const void *data); + +EAPI Eio_File *eio_file_move(const char *source, + const char *dest, + Eio_Progress_Cb progress_cb, + Eio_Done_Cb done_cb, + Eio_Done_Cb error_cb, + const void *data); + +EAPI Eio_File *eio_file_copy(const char *source, + const char *dest, + Eio_Progress_Cb progress_cb, + Eio_Done_Cb done_cb, + Eio_Done_Cb error_cb, + const void *data); + +EAPI Eio_File *eio_dir_move(const char *source, + const char *dest, + Eio_Progress_Cb progress_cb, + Eio_Done_Cb done_cb, + Eio_Done_Cb error_cb, + const void *data); + +EAPI Eio_File *eio_dir_copy(const char *source, + const char *dest, + Eio_Progress_Cb progress_cb, + Eio_Done_Cb done_cb, + Eio_Done_Cb error_cb, + const void *data); + +EAPI Eio_File *eio_dir_unlink(const char *path, + Eio_Progress_Cb progress_cb, + Eio_Done_Cb done_cb, + Eio_Done_Cb error_cb, + const void *data); + EAPI Eina_Bool eio_file_cancel(Eio_File *ls); -EAPI Eio_File *eio_file_operation(const char *file, - Eio_File_Op_Flags eio_file_flags, - Eio_File_Op_Main_Cb main_cb, - Eio_Done_Cb done_cb, - Eio_Done_Cb error_cb, - const void *data); #endif Modified: trunk/eio/src/lib/Makefile.am =================================================================== --- trunk/eio/src/lib/Makefile.am 2010-08-31 13:49:17 UTC (rev 51783) +++ trunk/eio/src/lib/Makefile.am 2010-08-31 16:24:58 UTC (rev 51784) @@ -9,8 +9,11 @@ includesdir = $(includedir)/eio-@VMAJ@ libeio_la_SOURCES = \ -eio_file.c +eio_file.c \ +eio_main.c \ +eio_single.c libeio_la_LIBADD = @EIO_LIBS@ libeio_la_LDFLAGS = -no-undefined @lt_enable_auto_import@ -version-info @version_info@ @release_info@ +EXTRA_DIST = eio_private.h Modified: trunk/eio/src/lib/eio_file.c =================================================================== --- trunk/eio/src/lib/eio_file.c 2010-08-31 13:49:17 UTC (rev 51783) +++ trunk/eio/src/lib/eio_file.c 2010-08-31 16:24:58 UTC (rev 51784) @@ -23,8 +23,6 @@ # include "config.h" #endif -#include <Ecore.h> - #include <stdio.h> #include <string.h> @@ -43,59 +41,10 @@ #include <sys/stat.h> #include <dirent.h> +#include "eio_private.h" + #include "Eio.h" -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; -typedef struct _Eio_File_Op Eio_File_Op; - -struct _Eio_File -{ - Ecore_Thread *thread; - const void *data; - - Eio_Done_Cb done_cb; - Eio_Done_Cb error_cb; -}; - -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; -}; - -struct _Eio_File_Op -{ - Eio_File common; - const char *file; - struct stat st; - Eio_File_Op_Flags flags; - Eina_Bool exists; - Eina_Bool can_read; - Eina_Bool can_write; - Eina_Bool can_execute; - Eio_File_Op_Main_Cb main_cb; -}; - -static int _eio_count = 0; - static void _eio_file_heavy(Ecore_Thread *thread, void *data) { @@ -220,112 +169,6 @@ free(async); } -static void -_eio_file_op_cb(void *data) -{ - Eio_File_Op *async = data; - - async->exists = (stat(async->file, &async->st) == 0); - if (async->exists) - { - if ((async->flags & EIO_FILE_CAN_READ) == EIO_FILE_CAN_READ) - { - if (!access(async->file, R_OK)) - async->can_read = EINA_TRUE; - else - async->can_read = EINA_FALSE; - } - if ((async->flags & EIO_FILE_CAN_WRITE) == EIO_FILE_CAN_WRITE) - { - if (!access(async->file, W_OK)) - async->can_write = EINA_TRUE; - else - async->can_write = EINA_FALSE; - } - if ((async->flags & EIO_FILE_CAN_EXECUTE) == EIO_FILE_CAN_EXECUTE) - { - if (!access(async->file, X_OK)) - async->can_execute = EINA_TRUE; - else - async->can_execute = EINA_FALSE; - } - } -} - -static void -_eio_file_op_end(void *data) -{ - Eio_File_Op *async = data; - - if (!async->exists) - { - if ((async->flags & EIO_FILE_EXISTS) == EIO_FILE_EXISTS) - { - async->main_cb(async->common.data, EIO_FILE_EXISTS, (void *)(long)async->exists); - if (async->common.done_cb) - async->common.done_cb(async->common.data); - } - else - ecore_thread_cancel(async->common.thread); - return; - } - - if ((async->flags & EIO_FILE_MOD_TIME) == EIO_FILE_MOD_TIME) - async->main_cb(async->common.data, EIO_FILE_MOD_TIME, (void *)(long)async->st.st_mtime); - if ((async->flags & EIO_FILE_SIZE) == EIO_FILE_SIZE) - async->main_cb(async->common.data, EIO_FILE_SIZE, (void *)(long)async->st.st_size); - if ((async->flags & EIO_FILE_EXISTS) == EIO_FILE_EXISTS) - async->main_cb(async->common.data, EIO_FILE_EXISTS, (void *)(long)async->exists); - if ((async->flags & EIO_FILE_IS_DIR) == EIO_FILE_IS_DIR) - async->main_cb(async->common.data, EIO_FILE_IS_DIR, (void *)(long)S_ISDIR(async->st.st_mode)); - if ((async->flags & EIO_FILE_CAN_READ) == EIO_FILE_CAN_READ) - async->main_cb(async->common.data, EIO_FILE_CAN_READ, (void *)(long)async->can_read); - if ((async->flags & EIO_FILE_CAN_WRITE) == EIO_FILE_CAN_WRITE) - async->main_cb(async->common.data, EIO_FILE_CAN_WRITE, (void *)(long)async->can_write); - if ((async->flags & EIO_FILE_CAN_EXECUTE) == EIO_FILE_CAN_EXECUTE) - async->main_cb(async->common.data, EIO_FILE_CAN_EXECUTE, (void *)(long)async->can_execute); - if (async->common.done_cb) - async->common.done_cb(async->common.data); - - free(async); -} - -static void -_eio_file_op_error(void *data) -{ - Eio_File_Op *async = data; - - if (async->common.error_cb) - async->common.error_cb(async->common.data); - - free(async); -} - -EAPI int -eio_init(void) -{ - _eio_count++; - - if (_eio_count > 1) return _eio_count; - - eina_init(); - ecore_init(); - - return _eio_count; -} - -EAPI int -eio_shutdown(void) -{ - _eio_count--; - - if (_eio_count > 0) return _eio_count; - - ecore_shutdown(); - eina_shutdown(); - return _eio_count; -} - /** * @brief List content of a directory without locking your app. * @param dir The directory to list. @@ -348,8 +191,11 @@ { Eio_File_Char_Ls *async = NULL; + if (!dir) + return NULL; + async = malloc(sizeof (Eio_File_Char_Ls)); - if (!async) goto on_error; + if (!async) return NULL; async->filter_cb = filter_cb; async->main_cb = main_cb; @@ -368,6 +214,7 @@ return &async->ls.common; on_error: + eina_stringshare_del(async->ls.directory); free(async); return NULL; } @@ -394,8 +241,11 @@ { Eio_File_Direct_Ls *async = NULL; + if (!dir) + return NULL; + async = malloc(sizeof (Eio_File_Direct_Ls)); - if (!async) goto on_error; + if (!async) return NULL; async->filter_cb = filter_cb; async->main_cb = main_cb; @@ -413,8 +263,8 @@ return &async->ls.common; - on_error: + eina_stringshare_del(async->ls.directory); free(async); return NULL; } @@ -425,48 +275,3 @@ return ecore_thread_cancel(ls->thread); } -/** - * @brief Perform standard File IO operations. - * @param file The file to operate on. - * @param flags Eio_File_Op_Flags to specify which operations to do. - * @param main_cb Callback called from the main loop with the results of the file operations. - * @param done_cb Callback called from the main loop when the operations are through. - * @param error_cb Callback called from the main loop when the file operations could not be completed. - * @return A reference to the IO operation. - * - * eio_file_operation runs selected operations in a separated thread using - * ecore_thread_run. This prevents any locking in your apps. - */ -EAPI Eio_File * -eio_file_operation(const char *file, - Eio_File_Op_Flags eio_file_flags, - Eio_File_Op_Main_Cb main_cb, - Eio_Done_Cb done_cb, - Eio_Done_Cb error_cb, - const void *data) -{ - Eio_File_Op *async = NULL; - - async = malloc(sizeof (Eio_File_Op)); - if (!async) goto on_error; - - async->main_cb = main_cb; - async->file = file; - async->flags = eio_file_flags; - async->common.done_cb = done_cb; - async->common.error_cb = error_cb; - async->common.data = data; - - async->common.thread = ecore_thread_run(_eio_file_op_cb, - _eio_file_op_end, - _eio_file_op_error, - async); - if (!async->common.thread) goto on_error; - - return &async->common; - - on_error: - free(async); - return NULL; -} - |
From: Enlightenment S. <no-...@en...> - 2010-09-01 08:23:24
|
Log: * eio: oops, forgot to add those files. Author: cedric Date: 2010-09-01 01:23:15 -0700 (Wed, 01 Sep 2010) New Revision: 51800 Added: trunk/eio/src/lib/eio_main.c trunk/eio/src/lib/eio_private.h trunk/eio/src/lib/eio_single.c |
From: Enlightenment S. <no-...@en...> - 2010-09-02 13:40:08
|
Log: * eio: add eio_file_unlink. Author: cedric Date: 2010-09-02 06:39:59 -0700 (Thu, 02 Sep 2010) New Revision: 51840 Modified: trunk/eio/src/lib/eio_private.h trunk/eio/src/lib/eio_single.c Modified: trunk/eio/src/lib/eio_private.h =================================================================== --- trunk/eio/src/lib/eio_private.h 2010-09-02 12:11:47 UTC (rev 51839) +++ trunk/eio/src/lib/eio_private.h 2010-09-02 13:39:59 UTC (rev 51840) @@ -9,6 +9,7 @@ typedef struct _Eio_File_Direct_Ls Eio_File_Direct_Ls; typedef struct _Eio_File_Char_Ls Eio_File_Char_Ls; typedef struct _Eio_File_Mkdir Eio_File_Mkdir; +typedef struct _Eio_File_Unlink Eio_File_Unlink; struct _Eio_File { @@ -49,4 +50,11 @@ mode_t mode; }; +struct _Eio_File_Unlink +{ + Eio_File common; + + const char *path; +}; + #endif Modified: trunk/eio/src/lib/eio_single.c =================================================================== --- trunk/eio/src/lib/eio_single.c 2010-09-02 12:11:47 UTC (rev 51839) +++ trunk/eio/src/lib/eio_single.c 2010-09-02 13:39:59 UTC (rev 51840) @@ -60,6 +60,39 @@ ecore_thread_cancel(r->common.thread); } +static void +_eio_file_unlink(void *data) +{ + Eio_File_Unlink *l = data; + + if (unlink(l->path) != 0) + ecore_thread_cancel(l->common.thread); +} + +static void +_eio_file_unlink_done(void *data) +{ + Eio_File_Unlink *l = data; + + if (l->common.done_cb) + l->common.done_cb(l->common.data); + + eina_stringshare_del(l->path); + free(l); +} + +static void +_eio_file_unlink_error(void *data) +{ + Eio_File_Unlink *l = data; + + if (l->common.error_cb) + l->common.error_cb(l->common.data); + + eina_stringshare_del(l->path); + free(l); +} + /* ---- */ EAPI Eio_File * @@ -71,12 +104,44 @@ return NULL; } +/** + * @brief Unlink a file/directory. + * @param mode The permission to set, follow (mode & ~umask & 0777). + * @param done_cb Callback called from the main loop when the directory has been created. + * @param error_cb Callback called from the main loop when the directory failed to be created or has been canceled. + * @return A reference to the IO operation. + * + * eio_file_unlink basically call unlink in another thread. This prevent any lock in your apps. + */ EAPI Eio_File * eio_file_unlink(const char *path, Eio_Done_Cb done_cb, Eio_Done_Cb error_cb, const void *data) { + Eio_File_Unlink *l = NULL; + + if (!path || !done_cb || !error_cb) + return NULL; + + l = malloc(sizeof (Eio_File_Unlink)); + if (!l) return NULL; + + l->path = eina_stringshare_add(path); + l->common.done_cb = done_cb; + l->common.error_cb = error_cb; + l->common.data = data; + l->common.thread = ecore_thread_run(_eio_file_unlink, + _eio_file_unlink_done, + _eio_file_unlink_error, + l); + if (!l->common.thread) goto on_error; + + return &l->common; + + on_error: + eina_stringshare_del(l->path); + free(l); return NULL; } |
From: Enlightenment S. <no-...@en...> - 2010-09-03 13:39:00
|
Log: * eio: limit number of threads used by eio_file_ls. Author: cedric Date: 2010-09-03 06:38:49 -0700 (Fri, 03 Sep 2010) New Revision: 51861 Modified: trunk/eio/src/lib/eio_file.c Modified: trunk/eio/src/lib/eio_file.c =================================================================== --- trunk/eio/src/lib/eio_file.c 2010-09-03 13:25:22 UTC (rev 51860) +++ trunk/eio/src/lib/eio_file.c 2010-09-03 13:38:49 UTC (rev 51861) @@ -208,7 +208,7 @@ _eio_file_end, _eio_file_error, async, - EINA_FALSE); + EINA_TRUE); if (!async->ls.common.thread) goto on_error; return &async->ls.common; @@ -258,7 +258,7 @@ _eio_file_end, _eio_file_error, async, - EINA_FALSE); + EINA_TRUE); if (!async->ls.common.thread) goto on_error; return &async->ls.common; |
From: Enlightenment S. <no-...@en...> - 2010-09-06 15:27:17
|
Log: * eio: minor cleanup and add stat support. Author: cedric Date: 2010-09-06 08:27:10 -0700 (Mon, 06 Sep 2010) New Revision: 51925 Modified: trunk/eio/src/lib/eio_file.c trunk/eio/src/lib/eio_private.h trunk/eio/src/lib/eio_single.c Modified: trunk/eio/src/lib/eio_file.c =================================================================== --- trunk/eio/src/lib/eio_file.c 2010-09-06 15:17:21 UTC (rev 51924) +++ trunk/eio/src/lib/eio_file.c 2010-09-06 15:27:10 UTC (rev 51925) @@ -162,8 +162,7 @@ async = data; - if (async->common.error_cb) - async->common.error_cb(async->common.data); + eio_file_error(&async->common); eina_stringshare_del(async->directory); free(async); Modified: trunk/eio/src/lib/eio_private.h =================================================================== --- trunk/eio/src/lib/eio_private.h 2010-09-06 15:17:21 UTC (rev 51924) +++ trunk/eio/src/lib/eio_private.h 2010-09-06 15:27:10 UTC (rev 51925) @@ -3,6 +3,10 @@ #include <Ecore.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <unistd.h> + #include "Eio.h" typedef struct _Eio_File_Ls Eio_File_Ls; @@ -10,6 +14,7 @@ typedef struct _Eio_File_Char_Ls Eio_File_Char_Ls; typedef struct _Eio_File_Mkdir Eio_File_Mkdir; typedef struct _Eio_File_Unlink Eio_File_Unlink; +typedef struct _Eio_File_Stat Eio_File_Stat; struct _Eio_File { @@ -57,4 +62,17 @@ const char *path; }; +struct _Eio_File_Stat +{ + Eio_File common; + + Eio_Stat_Cb done_cb; + + struct stat buffer; + const char *path; +}; + +void eio_file_error(Eio_File *common); +void eio_file_thread_error(Eio_File *common); + #endif Modified: trunk/eio/src/lib/eio_single.c =================================================================== --- trunk/eio/src/lib/eio_single.c 2010-09-06 15:17:21 UTC (rev 51924) +++ trunk/eio/src/lib/eio_single.c 2010-09-06 15:27:10 UTC (rev 51925) @@ -27,37 +27,55 @@ #include "Eio.h" +void +eio_file_error(Eio_File *common) +{ + if (common->error_cb) + common->error_cb(common->data); +} + +void +eio_file_thread_error(Eio_File *common) +{ + ecore_thread_cancel(common->thread); +} + +/* --- */ + static void -_eio_file_mkdir_done(void *data) +_eio_file_mkdir(void *data) { - Eio_File_Mkdir *r = data; + Eio_File_Mkdir *m = data; - if (r->common.done_cb) - r->common.done_cb(r->common.data); + if (mkdir(m->path, m->mode) != 0) + eio_file_thread_error(&m->common); +} - eina_stringshare_del(r->path); - free(r); +static void +_eio_mkdir_free(Eio_File_Mkdir *m) +{ + eina_stringshare_del(m->path); + free(m); } static void -_eio_file_mkdir_error(void *data) +_eio_file_mkdir_done(void *data) { - Eio_File_Mkdir *r = data; + Eio_File_Mkdir *m = data; - if (r->common.error_cb) - r->common.error_cb(r->common.data); + if (m->common.done_cb) + m->common.done_cb(m->common.data); - eina_stringshare_del(r->path); - free(r); + _eio_mkdir_free(m); } static void -_eio_file_mkdir(void *data) +_eio_file_mkdir_error(void *data) { - Eio_File_Mkdir *r = data; + Eio_File_Mkdir *m = data; - if (mkdir(r->path, r->mode) != 0) - ecore_thread_cancel(r->common.thread); + eio_file_error(&m->common); + _eio_mkdir_free(m); } static void @@ -66,10 +84,17 @@ Eio_File_Unlink *l = data; if (unlink(l->path) != 0) - ecore_thread_cancel(l->common.thread); + eio_file_thread_error(&l->common); } static void +_eio_unlink_free(Eio_File_Unlink *l) +{ + eina_stringshare_del(l->path); + free(l); +} + +static void _eio_file_unlink_done(void *data) { Eio_File_Unlink *l = data; @@ -77,8 +102,7 @@ if (l->common.done_cb) l->common.done_cb(l->common.data); - eina_stringshare_del(l->path); - free(l); + _eio_unlink_free(l); } static void @@ -86,21 +110,86 @@ { Eio_File_Unlink *l = data; - if (l->common.error_cb) - l->common.error_cb(l->common.data); + eio_file_error(&l->common); + _eio_unlink_free(l); +} - eina_stringshare_del(l->path); - free(l); +static void +_eio_file_stat(void *data) +{ + Eio_File_Stat *s = data; + + if (stat(s->path, &s->buffer) != 0) + eio_file_thread_error(&s->common); } +static void +_eio_stat_free(Eio_File_Stat *s) +{ + eina_stringshare_del(s->path); + free(s); +} + +static void +_eio_file_stat_done(void *data) +{ + Eio_File_Stat *s = data; + + if (s->done_cb) + s->done_cb(s->common.data, &s->buffer); + + _eio_stat_free(s); +} + +static void +_eio_file_stat_error(void *data) +{ + Eio_File_Stat *s = data; + + eio_file_error(&s->common); + _eio_stat_free(s); +} + /* ---- */ +/** + * @brief Stat a file/directory. + * @param done_cb Callback called from the main loop when stat was successfully called.. + * @param error_cb Callback called from the main loop when stat failed or has been canceled. + * @return A reference to the IO operation. + * + * eio_file_direct_stat basically call stat in another thread. This prevent any lock in your apps. + */ EAPI Eio_File * eio_file_direct_stat(const char *path, Eio_Stat_Cb done_cb, Eio_Done_Cb error_cb, const void *data) { + Eio_File_Stat *s = NULL; + + if (!path || !done_cb || !error_cb) + return NULL; + + s = malloc(sizeof (Eio_File_Stat)); + if (!s) return NULL; + + s->path = eina_stringshare_add(path); + s->done_cb = done_cb; + s->common.done_cb = NULL; + s->common.error_cb = error_cb; + s->common.data = data; + s->common.thread = ecore_thread_run(_eio_file_stat, + _eio_file_stat_done, + _eio_file_stat_error, + s); + if (!s->common.thread) goto on_error; + + return &s->common; + + on_error: + eina_stringshare_del(s->path); + free(s); return NULL; } |
From: Enlightenment S. <no-...@en...> - 2010-09-06 16:37:54
|
Log: * eio: major cleanup. Author: cedric Date: 2010-09-06 09:37:43 -0700 (Mon, 06 Sep 2010) New Revision: 51927 Modified: trunk/eio/src/lib/Eio.h trunk/eio/src/lib/eio_file.c trunk/eio/src/lib/eio_private.h trunk/eio/src/lib/eio_single.c Modified: trunk/eio/src/lib/Eio.h =================================================================== --- trunk/eio/src/lib/Eio.h 2010-09-06 16:36:44 UTC (rev 51926) +++ trunk/eio/src/lib/Eio.h 2010-09-06 16:37:43 UTC (rev 51927) @@ -83,6 +83,7 @@ typedef void (*Eio_Progress_Cb)(const void *data, const Eio_Progress *info); typedef void (*Eio_Done_Cb)(const void *data); +typedef void (*Eio_Error_Cb)(int errno, const void *data); struct _Eio_Progress { Modified: trunk/eio/src/lib/eio_file.c =================================================================== --- trunk/eio/src/lib/eio_file.c 2010-09-06 16:36:44 UTC (rev 51926) +++ trunk/eio/src/lib/eio_file.c 2010-09-06 16:37:43 UTC (rev 51927) @@ -199,23 +199,18 @@ 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_TRUE); - if (!async->ls.common.thread) goto on_error; - return &async->ls.common; + if (!eio_long_file_set(&async->ls.common, + done_cb, + error_cb, + data, + _eio_file_heavy, + _eio_file_notify, + _eio_file_end, + _eio_file_error)) + return NULL; - on_error: - eina_stringshare_del(async->ls.directory); - free(async); - return NULL; + return &async->ls.common; } /** @@ -249,23 +244,18 @@ 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_TRUE); - if (!async->ls.common.thread) goto on_error; - return &async->ls.common; + if (!eio_long_file_set(&async->ls.common, + done_cb, + error_cb, + data, + _eio_file_direct_heavy, + _eio_file_direct_notify, + _eio_file_end, + _eio_file_error)) + return NULL; - on_error: - eina_stringshare_del(async->ls.directory); - free(async); - return NULL; + return &async->ls.common; } EAPI Eina_Bool Modified: trunk/eio/src/lib/eio_private.h =================================================================== --- trunk/eio/src/lib/eio_private.h 2010-09-06 16:36:44 UTC (rev 51926) +++ trunk/eio/src/lib/eio_private.h 2010-09-06 16:37:43 UTC (rev 51927) @@ -72,6 +72,23 @@ const char *path; }; +Eina_Bool eio_file_set(Eio_File *common, + Eio_Done_Cb done_cb, + Eio_Done_Cb error_cb, + const void *data, + Ecore_Cb job_cb, + Ecore_Cb end_cb, + Ecore_Cb cancel_cb); + +Eina_Bool eio_long_file_set(Eio_File *common, + Eio_Done_Cb done_cb, + Eio_Done_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); + void eio_file_error(Eio_File *common); void eio_file_thread_error(Eio_File *common); Modified: trunk/eio/src/lib/eio_single.c =================================================================== --- trunk/eio/src/lib/eio_single.c 2010-09-06 16:36:44 UTC (rev 51926) +++ trunk/eio/src/lib/eio_single.c 2010-09-06 16:37:43 UTC (rev 51927) @@ -40,6 +40,58 @@ ecore_thread_cancel(common->thread); } +Eina_Bool +eio_long_file_set(Eio_File *common, + Eio_Done_Cb done_cb, + Eio_Done_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; + + thread = ecore_long_run(heavy_cb, + notify_cb, + end_cb, + cancel_cb, + common, + EINA_TRUE); + + if (!thread) return EINA_FALSE; + common->thread = thread; + return EINA_TRUE; +} + +Eina_Bool +eio_file_set(Eio_File *common, + Eio_Done_Cb done_cb, + Eio_Done_Cb error_cb, + const void *data, + Ecore_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; + thread = ecore_thread_run(job_cb, + end_cb, + cancel_cb, + common); + + if (!thread) return EINA_FALSE; + common->thread = thread; + return EINA_TRUE; +} + /* --- */ static void @@ -176,21 +228,17 @@ s->path = eina_stringshare_add(path); s->done_cb = done_cb; - s->common.done_cb = NULL; - s->common.error_cb = error_cb; - s->common.data = data; - s->common.thread = ecore_thread_run(_eio_file_stat, - _eio_file_stat_done, - _eio_file_stat_error, - s); - if (!s->common.thread) goto on_error; + if (!eio_file_set(&s->common, + NULL, + error_cb, + data, + _eio_file_stat, + _eio_file_stat_done, + _eio_file_stat_error)) + return NULL; + return &s->common; - - on_error: - eina_stringshare_del(s->path); - free(s); - return NULL; } /** @@ -217,21 +265,17 @@ if (!l) return NULL; l->path = eina_stringshare_add(path); - l->common.done_cb = done_cb; - l->common.error_cb = error_cb; - l->common.data = data; - l->common.thread = ecore_thread_run(_eio_file_unlink, - _eio_file_unlink_done, - _eio_file_unlink_error, - l); - if (!l->common.thread) goto on_error; + if (!eio_file_set(&l->common, + done_cb, + error_cb, + data, + _eio_file_unlink, + _eio_file_unlink_done, + _eio_file_unlink_error)) + return NULL; + return &l->common; - - on_error: - eina_stringshare_del(l->path); - free(l); - return NULL; } /** @@ -261,21 +305,17 @@ r->path = eina_stringshare_add(path); r->mode = mode; - r->common.done_cb = done_cb; - r->common.error_cb = error_cb; - r->common.data = data; - r->common.thread = ecore_thread_run(_eio_file_mkdir, - _eio_file_mkdir_done, - _eio_file_mkdir_error, - r); - if (!r->common.thread) goto on_error; + if (!eio_file_set(&r->common, + done_cb, + error_cb, + data, + _eio_file_mkdir, + _eio_file_mkdir_done, + _eio_file_mkdir_error)) + return NULL; + return &r->common; - - on_error: - eina_stringshare_del(r->path); - free(r); - return NULL; } |
From: Enlightenment S. <no-...@en...> - 2010-09-07 14:43:58
|
Log: * eio: return errno on error. Author: cedric Date: 2010-09-07 07:43:51 -0700 (Tue, 07 Sep 2010) New Revision: 51946 Modified: trunk/eio/src/lib/Eio.h trunk/eio/src/lib/eio_file.c trunk/eio/src/lib/eio_private.h trunk/eio/src/lib/eio_single.c Modified: trunk/eio/src/lib/Eio.h =================================================================== --- trunk/eio/src/lib/Eio.h 2010-09-07 14:34:36 UTC (rev 51945) +++ trunk/eio/src/lib/Eio.h 2010-09-07 14:43:51 UTC (rev 51946) @@ -83,7 +83,7 @@ typedef void (*Eio_Progress_Cb)(const void *data, const Eio_Progress *info); typedef void (*Eio_Done_Cb)(const void *data); -typedef void (*Eio_Error_Cb)(int errno, const void *data); +typedef void (*Eio_Error_Cb)(int error, const void *data); struct _Eio_Progress { @@ -99,64 +99,64 @@ Eio_Filter_Cb filter_cb, Eio_Main_Cb main_cb, Eio_Done_Cb done_cb, - Eio_Done_Cb error_cb, + Eio_Error_Cb error_cb, 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, + Eio_Error_Cb error_cb, const void *data); EAPI Eio_File *eio_file_direct_stat(const char *path, Eio_Stat_Cb done_cb, - Eio_Done_Cb error_cb, + Eio_Error_Cb error_cb, const void *data); EAPI Eio_File *eio_file_unlink(const char *path, Eio_Done_Cb done_cb, - Eio_Done_Cb error_cb, + Eio_Error_Cb error_cb, const void *data); EAPI Eio_File *eio_file_mkdir(const char *path, mode_t mode, Eio_Done_Cb done_cb, - Eio_Done_Cb error_cb, + Eio_Error_Cb error_cb, const void *data); EAPI Eio_File *eio_file_move(const char *source, const char *dest, Eio_Progress_Cb progress_cb, Eio_Done_Cb done_cb, - Eio_Done_Cb error_cb, + Eio_Error_Cb error_cb, const void *data); EAPI Eio_File *eio_file_copy(const char *source, const char *dest, Eio_Progress_Cb progress_cb, Eio_Done_Cb done_cb, - Eio_Done_Cb error_cb, + Eio_Error_Cb error_cb, const void *data); EAPI Eio_File *eio_dir_move(const char *source, const char *dest, Eio_Progress_Cb progress_cb, Eio_Done_Cb done_cb, - Eio_Done_Cb error_cb, + Eio_Error_Cb error_cb, const void *data); EAPI Eio_File *eio_dir_copy(const char *source, const char *dest, Eio_Progress_Cb progress_cb, Eio_Done_Cb done_cb, - Eio_Done_Cb error_cb, + Eio_Error_Cb error_cb, const void *data); EAPI Eio_File *eio_dir_unlink(const char *path, Eio_Progress_Cb progress_cb, Eio_Done_Cb done_cb, - Eio_Done_Cb error_cb, + Eio_Error_Cb error_cb, const void *data); EAPI Eina_Bool eio_file_cancel(Eio_File *ls); Modified: trunk/eio/src/lib/eio_file.c =================================================================== --- trunk/eio/src/lib/eio_file.c 2010-09-07 14:34:36 UTC (rev 51945) +++ trunk/eio/src/lib/eio_file.c 2010-09-07 14:43:51 UTC (rev 51946) @@ -185,7 +185,7 @@ Eio_Filter_Cb filter_cb, Eio_Main_Cb main_cb, Eio_Done_Cb done_cb, - Eio_Done_Cb error_cb, + Eio_Error_Cb error_cb, const void *data) { Eio_File_Char_Ls *async = NULL; @@ -230,7 +230,7 @@ Eio_Filter_Direct_Cb filter_cb, Eio_Main_Direct_Cb main_cb, Eio_Done_Cb done_cb, - Eio_Done_Cb error_cb, + Eio_Error_Cb error_cb, const void *data) { Eio_File_Direct_Ls *async = NULL; Modified: trunk/eio/src/lib/eio_private.h =================================================================== --- trunk/eio/src/lib/eio_private.h 2010-09-07 14:34:36 UTC (rev 51945) +++ trunk/eio/src/lib/eio_private.h 2010-09-07 14:43:51 UTC (rev 51946) @@ -21,8 +21,10 @@ Ecore_Thread *thread; const void *data; + int error; + + Eio_Error_Cb error_cb; Eio_Done_Cb done_cb; - Eio_Done_Cb error_cb; }; struct _Eio_File_Ls @@ -72,17 +74,19 @@ const char *path; }; +/* Be aware that ecore_thread_run could call cancel_cb if something goes wrong. */ Eina_Bool eio_file_set(Eio_File *common, Eio_Done_Cb done_cb, - Eio_Done_Cb error_cb, + Eio_Error_Cb error_cb, const void *data, Ecore_Cb job_cb, Ecore_Cb end_cb, Ecore_Cb cancel_cb); +/* Be aware that ecore_thread_run could call cancel_cb if something goes wrong. */ Eina_Bool eio_long_file_set(Eio_File *common, Eio_Done_Cb done_cb, - Eio_Done_Cb error_cb, + Eio_Error_Cb error_cb, const void *data, Ecore_Thread_Heavy_Cb heavy_cb, Ecore_Thread_Notify_Cb notify_cb, Modified: trunk/eio/src/lib/eio_single.c =================================================================== --- trunk/eio/src/lib/eio_single.c 2010-09-07 14:34:36 UTC (rev 51945) +++ trunk/eio/src/lib/eio_single.c 2010-09-07 14:43:51 UTC (rev 51946) @@ -23,6 +23,8 @@ # include "config.h" #endif +#include <errno.h> + #include "eio_private.h" #include "Eio.h" @@ -31,19 +33,20 @@ eio_file_error(Eio_File *common) { if (common->error_cb) - common->error_cb(common->data); + common->error_cb(common->error, common->data); } void eio_file_thread_error(Eio_File *common) { + common->error = errno; ecore_thread_cancel(common->thread); } Eina_Bool eio_long_file_set(Eio_File *common, Eio_Done_Cb done_cb, - Eio_Done_Cb error_cb, + Eio_Error_Cb error_cb, const void *data, Ecore_Thread_Heavy_Cb heavy_cb, Ecore_Thread_Notify_Cb notify_cb, @@ -55,7 +58,9 @@ common->done_cb = done_cb; common->error_cb = error_cb; common->data = data; + common->error = 0; + /* Be aware that ecore_thread_run could call cancel_cb if something goes wrong. */ thread = ecore_long_run(heavy_cb, notify_cb, end_cb, @@ -71,7 +76,7 @@ Eina_Bool eio_file_set(Eio_File *common, Eio_Done_Cb done_cb, - Eio_Done_Cb error_cb, + Eio_Error_Cb error_cb, const void *data, Ecore_Cb job_cb, Ecore_Cb end_cb, @@ -82,6 +87,9 @@ common->done_cb = done_cb; common->error_cb = error_cb; common->data = data; + common->error = 0; + + /* Be aware that ecore_thread_run could call cancel_cb if something goes wrong. */ thread = ecore_thread_run(job_cb, end_cb, cancel_cb, @@ -215,7 +223,7 @@ EAPI Eio_File * eio_file_direct_stat(const char *path, Eio_Stat_Cb done_cb, - Eio_Done_Cb error_cb, + Eio_Error_Cb error_cb, const void *data) { Eio_File_Stat *s = NULL; @@ -253,7 +261,7 @@ EAPI Eio_File * eio_file_unlink(const char *path, Eio_Done_Cb done_cb, - Eio_Done_Cb error_cb, + Eio_Error_Cb error_cb, const void *data) { Eio_File_Unlink *l = NULL; @@ -292,7 +300,7 @@ eio_file_mkdir(const char *path, mode_t mode, Eio_Done_Cb done_cb, - Eio_Done_Cb error_cb, + Eio_Error_Cb error_cb, const void *data) { Eio_File_Mkdir *r = NULL; |
From: Enlightenment S. <no-...@en...> - 2010-09-13 13:44:31
|
Log: * eio: callback are allowed to modify their own data. Don't know how I wrote this non sense. Author: cedric Date: 2010-09-13 06:44:24 -0700 (Mon, 13 Sep 2010) New Revision: 52189 Modified: trunk/eio/src/lib/Eio.h trunk/eio/src/lib/eio_file.c trunk/eio/src/lib/eio_single.c Modified: trunk/eio/src/lib/Eio.h =================================================================== --- trunk/eio/src/lib/Eio.h 2010-09-13 12:35:52 UTC (rev 52188) +++ trunk/eio/src/lib/Eio.h 2010-09-13 13:44:24 UTC (rev 52189) @@ -73,17 +73,17 @@ typedef struct _Eio_Progress Eio_Progress; typedef struct _Eio_Stat Eio_Stat; -typedef Eina_Bool (*Eio_Filter_Cb)(const void *data, const char *file); -typedef void (*Eio_Main_Cb)(const void *data, const char *file); +typedef Eina_Bool (*Eio_Filter_Cb)(void *data, const char *file); +typedef void (*Eio_Main_Cb)(void *data, const char *file); -typedef Eina_Bool (*Eio_Filter_Direct_Cb)(const void *data, const Eina_File_Direct_Info *info); -typedef void (*Eio_Main_Direct_Cb)(const void *data, const Eina_File_Direct_Info *info); +typedef Eina_Bool (*Eio_Filter_Direct_Cb)(void *data, const Eina_File_Direct_Info *info); +typedef void (*Eio_Main_Direct_Cb)(void *data, const Eina_File_Direct_Info *info); -typedef void (*Eio_Stat_Cb)(const void *data, const struct stat *stat); -typedef void (*Eio_Progress_Cb)(const void *data, const Eio_Progress *info); +typedef void (*Eio_Stat_Cb)(void *data, const struct stat *stat); +typedef void (*Eio_Progress_Cb)(void *data, const Eio_Progress *info); -typedef void (*Eio_Done_Cb)(const void *data); -typedef void (*Eio_Error_Cb)(int error, const void *data); +typedef void (*Eio_Done_Cb)(void *data); +typedef void (*Eio_Error_Cb)(int error, void *data); struct _Eio_Progress { Modified: trunk/eio/src/lib/eio_file.c =================================================================== --- trunk/eio/src/lib/eio_file.c 2010-09-13 12:35:52 UTC (rev 52188) +++ trunk/eio/src/lib/eio_file.c 2010-09-13 13:44:24 UTC (rev 52189) @@ -65,7 +65,7 @@ if (async->filter_cb) { - filter = async->filter_cb(async->ls.common.data, file); + filter = async->filter_cb((void*) async->ls.common.data, file); } if (filter) ecore_thread_notify(thread, file); @@ -85,7 +85,7 @@ const char *file = msg_data; if (async->main_cb) - async->main_cb(async->ls.common.data, file); + async->main_cb((void*) async->ls.common.data, file); eina_stringshare_del(file); } @@ -110,7 +110,7 @@ if (async->filter_cb) { - filter = async->filter_cb(async->ls.common.data, info); + filter = async->filter_cb((void*) async->ls.common.data, info); } if (filter) @@ -138,7 +138,7 @@ Eina_File_Direct_Info *info = msg_data; if (async->main_cb) - async->main_cb(async->ls.common.data, info); + async->main_cb((void*) async->ls.common.data, info); free(info); } @@ -149,7 +149,7 @@ Eio_File_Ls *async = data; if (async->common.done_cb) - async->common.done_cb(async->common.data); + async->common.done_cb((void*) async->common.data); eina_stringshare_del(async->directory); free(async); Modified: trunk/eio/src/lib/eio_single.c =================================================================== --- trunk/eio/src/lib/eio_single.c 2010-09-13 12:35:52 UTC (rev 52188) +++ trunk/eio/src/lib/eio_single.c 2010-09-13 13:44:24 UTC (rev 52189) @@ -33,7 +33,7 @@ eio_file_error(Eio_File *common) { if (common->error_cb) - common->error_cb(common->error, common->data); + common->error_cb(common->error, (void*) common->data); } void @@ -124,7 +124,7 @@ Eio_File_Mkdir *m = data; if (m->common.done_cb) - m->common.done_cb(m->common.data); + m->common.done_cb((void*) m->common.data); _eio_mkdir_free(m); } @@ -160,7 +160,7 @@ Eio_File_Unlink *l = data; if (l->common.done_cb) - l->common.done_cb(l->common.data); + l->common.done_cb((void*) l->common.data); _eio_unlink_free(l); } @@ -196,7 +196,7 @@ Eio_File_Stat *s = data; if (s->done_cb) - s->done_cb(s->common.data, &s->buffer); + s->done_cb((void*) s->common.data, &s->buffer); _eio_stat_free(s); } |
From: Enlightenment S. <no-...@en...> - 2010-09-28 09:05:59
|
Log: * eio: add eio_file_move (completly asynchronous and non blocking move). It first try a rename, then fallback to an eio_file_copy + eio_file_unlink. Small example on how to use it : #include <Ecore.h> #include <Eio.h> static void _test_done_cb(void *data) { printf("move done\n"); ecore_main_loop_quit(); } static void _test_error_cb(int error, void *data) { fprintf(stderr, "error: [%s]\n", strerror(error)); ecore_main_loop_quit(); } int main(int argc, char **argv) { Eio_File *cp; if (argc != 3) { fprintf(stderr, "eio_cp source_file destination_file\n"); return -1; } ecore_init(); eio_init(); cp = eio_file_move(argv[1], argv[2], NULL, _test_done_cb, _test_error_cb, NULL); ecore_main_loop_begin(); eio_shutdown(); ecore_shutdown(); return 0; } Author: cedric Date: 2010-09-28 02:05:51 -0700 (Tue, 28 Sep 2010) New Revision: 52845 Modified: trunk/eio/src/lib/eio_file.c trunk/eio/src/lib/eio_private.h Modified: trunk/eio/src/lib/eio_file.c =================================================================== --- trunk/eio/src/lib/eio_file.c 2010-09-28 08:46:08 UTC (rev 52844) +++ trunk/eio/src/lib/eio_file.c 2010-09-28 09:05:51 UTC (rev 52845) @@ -187,11 +187,11 @@ } static void -_eio_file_copy_send(Ecore_Thread *thread, Eio_File_Copy *copy, off_t current, off_t max) +_eio_file_send(Ecore_Thread *thread, Eio_File_Progress *op, off_t current, off_t max) { Eio_Progress *progress; - if (copy->progress_cb == NULL) + if (op->progress_cb == NULL) return ; pthread_mutex_lock(&lock); @@ -205,16 +205,31 @@ 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); } +static void +_eio_file_progress(Eio_Progress *progress, Eio_File_Progress *op) +{ + op->progress_cb((void *) op->common.data, progress); + eina_stringshare_del(progress->source); + eina_stringshare_del(progress->dest); + + pthread_mutex_lock(&lock); + eina_trash_push(&trash, progress); + trash_count++; + pthread_mutex_unlock(&lock); +} + #ifndef MAP_HUGETLB # define MAP_HUGETLB 0 #endif static Eina_Bool -_eio_file_copy_mmap(Ecore_Thread *thread, Eio_File_Copy *copy, int in, int out, off_t size) +_eio_file_copy_mmap(Ecore_Thread *thread, Eio_File_Progress *op, int in, int out, off_t size) { char *m = MAP_FAILED; off_t i; @@ -242,13 +257,13 @@ if (!_eio_file_write(out, m + k, EIO_PACKET_SIZE)) goto on_error; - _eio_file_copy_send(thread, copy, i + j, size); + _eio_file_send(thread, op, i + j, size); } if (!_eio_file_write(out, m + k, c - k)) goto on_error; - _eio_file_copy_send(thread, copy, i + c, size); + _eio_file_send(thread, op, i + c, size); munmap(m, EIO_PACKET_SIZE * EIO_PACKET_COUNT); m = MAP_FAILED; @@ -263,7 +278,7 @@ #ifdef EFL_HAVE_SPLICE static int -_eio_file_copy_splice(Ecore_Thread *thread, Eio_File_Copy *copy, int in, int out, off_t size) +_eio_file_copy_splice(Ecore_Thread *thread, Eio_File_Progress *op, int in, int out, off_t size) { int result = 0; off_t count; @@ -281,7 +296,7 @@ count = splice(pipefd[0], NULL, out, 0, count, SPLICE_F_MORE | SPLICE_F_MOVE); if (count < 0) goto on_error; - _eio_file_copy_send(thread, copy, i, size); + _eio_file_send(thread, op, i, size); } result = 1; @@ -298,7 +313,7 @@ static void _eio_file_copy_heavy(Ecore_Thread *thread, void *data) { - Eio_File_Copy *copy; + Eio_File_Progress *copy; struct stat buf; int result = -1; int in = -1; @@ -348,21 +363,15 @@ static void _eio_file_copy_notify(Ecore_Thread *thread __UNUSED__, void *msg_data, void *data) { - Eio_File_Copy *copy = data; - Eio_Progress *progress = msg_data; + Eio_File_Progress *copy = data; - copy->progress_cb((void *) copy->common.data, progress); - - pthread_mutex_lock(&lock); - eina_trash_push(&trash, progress); - trash_count++; - pthread_mutex_unlock(&lock); + _eio_file_progress(msg_data, copy); } static void _eio_file_copy_end(void *data) { - Eio_File_Copy *copy = data; + Eio_File_Progress *copy = data; copy->common.done_cb((void*) copy->common.data); @@ -374,7 +383,7 @@ static void _eio_file_copy_error(void *data) { - Eio_File_Copy *copy = data; + Eio_File_Progress *copy = data; eio_file_error(©->common); @@ -383,6 +392,130 @@ free(copy); } +static void +_eio_file_move_copy_progress(void *data, const Eio_Progress *info) +{ + Eio_File_Move *move = data; + + move->progress.progress_cb((void*) move->progress.common.data, info); +} + +static void +_eio_file_move_unlink_done(void *data) +{ + Eio_File_Move *move = data; + + move->progress.common.done_cb((void*) move->progress.common.data); + + eina_stringshare_del(move->progress.source); + eina_stringshare_del(move->progress.dest); + free(move); +} + +static void +_eio_file_move_unlink_error(int error, void *data) +{ + Eio_File_Move *move = data; + + move->copy = NULL; + + move->progress.common.error = error; + eio_file_error(&move->progress.common); + + eina_stringshare_del(move->progress.source); + eina_stringshare_del(move->progress.dest); + free(move); +} + +static void +_eio_file_move_copy_done(void *data) +{ + Eio_File_Move *move = data; + Eio_File *rm; + + rm = eio_file_unlink(move->progress.source, + _eio_file_move_unlink_done, + _eio_file_move_unlink_error, + move); + if (rm) move->copy = rm; +} + +static void +_eio_file_move_copy_error(int error, void *data) +{ + Eio_File_Move *move = data; + + move->progress.common.error = error; + eio_file_error(&move->progress.common); + + eina_stringshare_del(move->progress.source); + eina_stringshare_del(move->progress.dest); + free(move); +} + +static void +_eio_file_move_heavy(Ecore_Thread *thread, void *data) +{ + Eio_File_Move *move = data; + + if (rename(move->progress.source, move->progress.dest) < 0) + eio_file_thread_error(&move->progress.common); + else + _eio_file_send(thread, &move->progress, 1, 1); +} + +static void +_eio_file_move_notify(Ecore_Thread *thread __UNUSED__, void *msg_data, void *data) +{ + Eio_File_Move *move = data; + + _eio_file_progress(msg_data, &move->progress); +} + +static void +_eio_file_move_end(void *data) +{ + Eio_File_Move *move = data; + + move->progress.common.done_cb((void*) move->progress.common.data); + + eina_stringshare_del(move->progress.source); + eina_stringshare_del(move->progress.dest); + free(move); +} + +static void +_eio_file_move_error(void *data) +{ + Eio_File_Move *move = data; + + if (move->copy) + { + eio_file_cancel(move->copy); + return ; + } + + if (move->progress.common.error == EXDEV) + { + Eio_File *eio_cp; + + eio_cp = eio_file_copy(move->progress.source, move->progress.dest, + move->progress.progress_cb ? _eio_file_move_copy_progress : NULL, + _eio_file_move_copy_done, + _eio_file_move_copy_error, + move); + + if (eio_cp) move->copy = eio_cp; + return ; + } + + eio_file_error(&move->progress.common); + + eina_stringshare_del(move->progress.source); + eina_stringshare_del(move->progress.dest); + free(move); +} + /** * @brief List content of a directory without locking your app. * @param dir The directory to list. @@ -508,12 +641,12 @@ Eio_Error_Cb error_cb, const void *data) { - Eio_File_Copy *copy = NULL; + Eio_File_Progress *copy = NULL; if (!source || !dest || !done_cb || !error_cb) return NULL; - copy = malloc(sizeof (Eio_File_Copy)); + copy = malloc(sizeof (Eio_File_Progress)); if (!copy) return NULL; copy->progress_cb = progress_cb; @@ -533,3 +666,36 @@ return ©->common; } +EAPI Eio_File * +eio_file_move(const char *source, + const char *dest, + Eio_Progress_Cb progress_cb, + Eio_Done_Cb done_cb, + Eio_Error_Cb error_cb, + const void *data) +{ + Eio_File_Move *move = NULL; + + if (!source || !dest || !done_cb || !error_cb) + return NULL; + + move = malloc(sizeof (Eio_File_Move)); + if (!move) return NULL; + + move->progress.progress_cb = progress_cb; + move->progress.source = eina_stringshare_add(source); + move->progress.dest = eina_stringshare_add(dest); + move->copy = NULL; + + if (!eio_long_file_set(&move->progress.common, + done_cb, + error_cb, + data, + _eio_file_move_heavy, + _eio_file_move_notify, + _eio_file_move_end, + _eio_file_move_error)) + return NULL; + + return &move->progress.common; +} Modified: trunk/eio/src/lib/eio_private.h =================================================================== --- trunk/eio/src/lib/eio_private.h 2010-09-28 08:46:08 UTC (rev 52844) +++ trunk/eio/src/lib/eio_private.h 2010-09-28 09:05:51 UTC (rev 52845) @@ -19,7 +19,8 @@ typedef struct _Eio_File_Mkdir Eio_File_Mkdir; typedef struct _Eio_File_Unlink Eio_File_Unlink; typedef struct _Eio_File_Stat Eio_File_Stat; -typedef struct _Eio_File_Copy Eio_File_Copy; +typedef struct _Eio_File_Progress Eio_File_Progress; +typedef struct _Eio_File_Move Eio_File_Move; struct _Eio_File { @@ -79,7 +80,7 @@ const char *path; }; -struct _Eio_File_Copy +struct _Eio_File_Progress { Eio_File common; @@ -89,6 +90,13 @@ const char *dest; }; +struct _Eio_File_Move +{ + Eio_File_Progress progress; + + Eio_File *copy; +}; + /* Be aware that ecore_thread_run could call cancel_cb if something goes wrong. */ Eina_Bool eio_file_set(Eio_File *common, Eio_Done_Cb done_cb, |
From: Enlightenment S. <no-...@en...> - 2010-10-05 11:44:10
|
Log: * eio: share some code. Author: cedric Date: 2010-10-05 04:44:03 -0700 (Tue, 05 Oct 2010) New Revision: 53056 Modified: trunk/eio/src/lib/eio_file.c trunk/eio/src/lib/eio_main.c trunk/eio/src/lib/eio_private.h Modified: trunk/eio/src/lib/eio_file.c =================================================================== --- trunk/eio/src/lib/eio_file.c 2010-10-05 11:32:12 UTC (rev 53055) +++ trunk/eio/src/lib/eio_file.c 2010-10-05 11:44:03 UTC (rev 53056) @@ -46,16 +46,10 @@ #include <sys/mman.h> #include <fcntl.h> -#include <pthread.h> - #include "eio_private.h" #include "Eio.h" -static pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER; -static Eina_Trash *trash = NULL; -static int trash_count = 0; - static void _eio_file_heavy(Ecore_Thread *thread, void *data) { @@ -127,10 +121,13 @@ { Eina_File_Direct_Info *send; - send = malloc(sizeof (Eina_File_Direct_Info)); + send = malloc(sizeof (Eina_File_Direct_Info) + sizeof (struct dirent)); if (!send) continue; memcpy(send, info, sizeof (Eina_File_Direct_Info)); + send->dirent = (struct dirent*)(send + 1); + memcpy((void*) send->dirent, info->dirent, sizeof (struct dirent)); + ecore_thread_feedback(thread, send); } @@ -194,12 +191,7 @@ if (op->progress_cb == NULL) return ; - pthread_mutex_lock(&lock); - progress = eina_trash_pop(&trash); - if (progress) trash_count--; - pthread_mutex_unlock(&lock); - - if (!progress) progress = malloc(sizeof (Eio_Progress)); + progress = eio_progress_malloc(); if (!progress) return ; progress->current = current; @@ -215,13 +207,8 @@ _eio_file_progress(Eio_Progress *progress, Eio_File_Progress *op) { op->progress_cb((void *) op->common.data, progress); - eina_stringshare_del(progress->source); - eina_stringshare_del(progress->dest); - pthread_mutex_lock(&lock); - eina_trash_push(&trash, progress); - trash_count++; - pthread_mutex_unlock(&lock); + eio_progress_free(progress); } #ifndef MAP_HUGETLB @@ -505,8 +492,13 @@ _eio_file_move_copy_error, move); - if (eio_cp) move->copy = eio_cp; - return ; + if (eio_cp) + { + move->copy = eio_cp; + + move->progress.common.thread = ((Eio_File_Progress*)move->copy)->common.thread; + return ; + } } eio_file_error(&move->progress.common); Modified: trunk/eio/src/lib/eio_main.c =================================================================== --- trunk/eio/src/lib/eio_main.c 2010-10-05 11:32:12 UTC (rev 53055) +++ trunk/eio/src/lib/eio_main.c 2010-10-05 11:44:03 UTC (rev 53056) @@ -1,3 +1,22 @@ +/* EIO - EFL data type library + * Copyright (C) 2010 Enlightenment Developers: + * Cedric Bail <ced...@fr...> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; + * if not, see <http://www.gnu.org/licenses/>. + */ + #ifdef HAVE_CONFIG_H # include "config.h" #endif @@ -2,2 +21,4 @@ +#include <pthread.h> + #include "eio_private.h" @@ -8,6 +29,11 @@ static int _eio_count = 0; +/* Progress pool */ +static pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER; +static Eina_Trash *trash = NULL; +static int trash_count = 0; + EAPI int eio_init(void) { @@ -24,11 +50,51 @@ EAPI int eio_shutdown(void) { + Eio_Progress *progress; + _eio_count--; if (_eio_count > 0) return _eio_count; + /* Cleanup progress pool */ + EINA_TRASH_CLEAN(&trash, progress) + free(progress); + trash_count = 0; + ecore_shutdown(); eina_shutdown(); return _eio_count; } + +Eio_Progress * +eio_progress_malloc(void) +{ + Eio_Progress *progress; + + pthread_mutex_lock(&lock); + progress = eina_trash_pop(&trash); + if (progress) trash_count--; + pthread_mutex_unlock(&lock); + + if (!progress) progress = malloc(sizeof (Eio_Progress)); + return progress; +} + +void +eio_progress_free(Eio_Progress *progress) +{ + eina_stringshare_del(progress->source); + eina_stringshare_del(progress->dest); + + if (trash_count >= EIO_PROGRESS_LIMIT) + { + free(progress); + } + else + { + pthread_mutex_lock(&lock); + eina_trash_push(&trash, progress); + trash_count++; + pthread_mutex_unlock(&lock); + } +} Modified: trunk/eio/src/lib/eio_private.h =================================================================== --- trunk/eio/src/lib/eio_private.h 2010-10-05 11:32:12 UTC (rev 53055) +++ trunk/eio/src/lib/eio_private.h 2010-10-05 11:44:03 UTC (rev 53056) @@ -9,6 +9,9 @@ #include "Eio.h" +/* Keeping 32 Eio_File_Progress alive should be enought */ +#define EIO_PROGRESS_LIMIT 32 + /* Huge TLB == 16M on most system */ #define EIO_PACKET_SIZE 65536 #define EIO_PACKET_COUNT 256 @@ -22,6 +25,8 @@ typedef struct _Eio_File_Progress Eio_File_Progress; typedef struct _Eio_File_Move Eio_File_Move; +typedef struct _Eio_Dir_Copy Eio_Dir_Copy; + struct _Eio_File { Ecore_Thread *thread; @@ -97,6 +102,14 @@ Eio_File *copy; }; +struct _Eio_Dir_Copy +{ + Eio_File_Progress progress; + + Eina_List *files; + Eina_List *dirs; +}; + /* Be aware that ecore_thread_run could call cancel_cb if something goes wrong. */ Eina_Bool eio_file_set(Eio_File *common, Eio_Done_Cb done_cb, @@ -119,4 +132,7 @@ void eio_file_error(Eio_File *common); void eio_file_thread_error(Eio_File *common); +Eio_Progress *eio_progress_malloc(void); +void eio_progress_free(Eio_Progress *progress); + #endif |
From: Enlightenment S. <no-...@en...> - 2010-10-05 12:56:15
|
Log: * eio: share more code and make copy cancellable. Author: cedric Date: 2010-10-05 05:56:07 -0700 (Tue, 05 Oct 2010) New Revision: 53057 Modified: trunk/eio/src/lib/eio_file.c trunk/eio/src/lib/eio_main.c trunk/eio/src/lib/eio_private.h Modified: trunk/eio/src/lib/eio_file.c =================================================================== --- trunk/eio/src/lib/eio_file.c 2010-10-05 11:44:03 UTC (rev 53056) +++ trunk/eio/src/lib/eio_file.c 2010-10-05 12:56:07 UTC (rev 53057) @@ -244,16 +244,19 @@ if (!_eio_file_write(out, m + k, EIO_PACKET_SIZE)) goto on_error; - _eio_file_send(thread, op, i + j, size); + eio_progress_send(thread, op, i + j, size); } if (!_eio_file_write(out, m + k, c - k)) goto on_error; - _eio_file_send(thread, op, i + c, size); + eio_progress_send(thread, op, i + c, size); munmap(m, EIO_PACKET_SIZE * EIO_PACKET_COUNT); m = MAP_FAILED; + + if (ecore_thread_check(thread)) + goto on_error; } return EINA_TRUE; @@ -283,7 +286,10 @@ count = splice(pipefd[0], NULL, out, 0, count, SPLICE_F_MORE | SPLICE_F_MOVE); if (count < 0) goto on_error; - _eio_file_send(thread, op, i, size); + eio_progress_send(thread, op, i, size); + + if (ecore_thread_check(thread)) + goto on_error; } result = 1; @@ -448,7 +454,7 @@ if (rename(move->progress.source, move->progress.dest) < 0) eio_file_thread_error(&move->progress.common); else - _eio_file_send(thread, &move->progress, 1, 1); + eio_progress_send(thread, &move->progress, 1, 1); } static void @@ -482,7 +488,7 @@ return ; } - if (move->progress.common.error == EXDEV) + if (move->progress.common.error == EXDEV && !ecore_thread_check(thread)) { Eio_File *eio_cp; Modified: trunk/eio/src/lib/eio_main.c =================================================================== --- trunk/eio/src/lib/eio_main.c 2010-10-05 11:44:03 UTC (rev 53056) +++ trunk/eio/src/lib/eio_main.c 2010-10-05 12:56:07 UTC (rev 53057) @@ -98,3 +98,24 @@ pthread_mutex_unlock(&lock); } } + +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->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); +} + Modified: trunk/eio/src/lib/eio_private.h =================================================================== --- trunk/eio/src/lib/eio_private.h 2010-10-05 11:44:03 UTC (rev 53056) +++ trunk/eio/src/lib/eio_private.h 2010-10-05 12:56:07 UTC (rev 53057) @@ -134,5 +134,7 @@ Eio_Progress *eio_progress_malloc(void); void eio_progress_free(Eio_Progress *progress); +void eio_progress_send(Ecore_Thread *thread, Eio_File_Progress *op, + off_t current, off_t max); #endif |
From: Enlightenment S. <no-...@en...> - 2010-10-05 14:30:06
|
Log: * eio: fix docs and typos. Author: cedric Date: 2010-10-05 07:29:58 -0700 (Tue, 05 Oct 2010) New Revision: 53062 Modified: trunk/eio/src/lib/eio_file.c Modified: trunk/eio/src/lib/eio_file.c =================================================================== --- trunk/eio/src/lib/eio_file.c 2010-10-05 14:05:23 UTC (rev 53061) +++ trunk/eio/src/lib/eio_file.c 2010-10-05 14:29:58 UTC (rev 53062) @@ -184,26 +184,6 @@ } static void -_eio_file_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->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); -} - -static void _eio_file_progress(Eio_Progress *progress, Eio_File_Progress *op) { op->progress_cb((void *) op->common.data, progress); @@ -321,6 +301,10 @@ return ; } + /* + 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; @@ -330,14 +314,20 @@ 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); @@ -488,7 +478,7 @@ return ; } - if (move->progress.common.error == EXDEV && !ecore_thread_check(thread)) + if (move->progress.common.error == EXDEV) { Eio_File *eio_cp; @@ -628,9 +618,9 @@ * @param data Private data given to callback. * * This function will copy a file from source to dest. It will try to use splice - * if possible, if not it will fallback to mmap/write. + * if possible, if not it will fallback to mmap/write. It will try to preserve + * access right, but not user/group identification. */ - EAPI Eio_File * eio_file_copy(const char *source, const char *dest, @@ -664,6 +654,20 @@ return ©->common; } +/** + * @brief Move a file asynchronously + * @param source Should be the name of the file to move the data from. + * @param dest Should be the name of the file to move the data to. + * @param progress_cb Callback called to know the progress of the move. + * @param done_cb Callback called when the move is done. + * @param error_cb Callback called when something goes wrong. + * @param data Private data given to callback. + * + * This function will copy a file from source to dest. It will try to use splice + * if possible, if not it will fallback to mmap/write. It will try to preserve + * access right, but not user/group identification. + + */ EAPI Eio_File * eio_file_move(const char *source, const char *dest, |
From: Enlightenment S. <no-...@en...> - 2010-10-05 14:55:53
|
Log: * eio: report current operation during progress. Author: cedric Date: 2010-10-05 07:55:47 -0700 (Tue, 05 Oct 2010) New Revision: 53063 Modified: trunk/eio/src/lib/Eio.h trunk/eio/src/lib/eio_file.c trunk/eio/src/lib/eio_main.c trunk/eio/src/lib/eio_private.h Modified: trunk/eio/src/lib/Eio.h =================================================================== --- trunk/eio/src/lib/Eio.h 2010-10-05 14:29:58 UTC (rev 53062) +++ trunk/eio/src/lib/Eio.h 2010-10-05 14:55:47 UTC (rev 53063) @@ -58,16 +58,13 @@ # endif #endif /* ! _WIN32 */ -typedef enum _Eio_File_Op_Flags +typedef enum _Eio_File_Op { - EIO_FILE_MOD_TIME = 1, - EIO_FILE_SIZE = 2, - EIO_FILE_EXISTS = 4, - EIO_FILE_IS_DIR = 8, - EIO_FILE_CAN_READ = 16, - EIO_FILE_CAN_WRITE = 32, - EIO_FILE_CAN_EXECUTE = 64 -} Eio_File_Op_Flags; + EIO_FILE_COPY, + EIO_FILE_MOVE, + EIO_DIR_COPY, + EIO_DIR_MOVE +} Eio_File_Op; typedef struct _Eio_File Eio_File; typedef struct _Eio_Progress Eio_Progress; @@ -87,6 +84,8 @@ struct _Eio_Progress { + Eio_File_Op op; + off_t current; off_t max; float percent; Modified: trunk/eio/src/lib/eio_file.c =================================================================== --- trunk/eio/src/lib/eio_file.c 2010-10-05 14:29:58 UTC (rev 53062) +++ trunk/eio/src/lib/eio_file.c 2010-10-05 14:55:47 UTC (rev 53063) @@ -283,17 +283,14 @@ } #endif -static void -_eio_file_copy_heavy(Ecore_Thread *thread, void *data) +Eina_Bool +eio_file_copy_do(Ecore_Thread *thread, Eio_File_Progress *copy) { - Eio_File_Progress *copy; struct stat buf; int result = -1; int in = -1; int out = -1; - copy = data; - in = open(copy->source, O_RDONLY); if (in < 0) { @@ -331,7 +328,7 @@ close(out); close(in); - return ; + return EINA_TRUE; on_error: eio_file_thread_error(©->common); @@ -340,10 +337,18 @@ if (out >= 0) close(out); if (out >= 0) unlink(copy->dest); - return ; + return EINA_FALSE; } static void +_eio_file_copy_heavy(Ecore_Thread *thread, void *data) +{ + Eio_File_Progress *copy = data; + + eio_file_copy_do(thread, copy); +} + +static void _eio_file_copy_notify(Ecore_Thread *thread __UNUSED__, void *msg_data, void *data) { Eio_File_Progress *copy = data; @@ -637,6 +642,7 @@ copy = malloc(sizeof (Eio_File_Progress)); if (!copy) return NULL; + move->op = EIO_FILE_COPY; copy->progress_cb = progress_cb; copy->source = eina_stringshare_add(source); copy->dest = eina_stringshare_add(dest); @@ -684,6 +690,7 @@ move = malloc(sizeof (Eio_File_Move)); if (!move) return NULL; + move->progress.op = EIO_FILE_MOVE; move->progress.progress_cb = progress_cb; move->progress.source = eina_stringshare_add(source); move->progress.dest = eina_stringshare_add(dest); Modified: trunk/eio/src/lib/eio_main.c =================================================================== --- trunk/eio/src/lib/eio_main.c 2010-10-05 14:29:58 UTC (rev 53062) +++ trunk/eio/src/lib/eio_main.c 2010-10-05 14:55:47 UTC (rev 53063) @@ -110,6 +110,7 @@ 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; Modified: trunk/eio/src/lib/eio_private.h =================================================================== --- trunk/eio/src/lib/eio_private.h 2010-10-05 14:29:58 UTC (rev 53062) +++ trunk/eio/src/lib/eio_private.h 2010-10-05 14:55:47 UTC (rev 53063) @@ -93,6 +93,8 @@ const char *source; const char *dest; + + Eio_File_Op op; }; struct _Eio_File_Move @@ -136,5 +138,6 @@ void eio_progress_free(Eio_Progress *progress); void eio_progress_send(Ecore_Thread *thread, Eio_File_Progress *op, off_t current, off_t max); +Eina_Bool eio_file_copy_do(Ecore_Thread *thread, Eio_File_Progress *copy); #endif |
From: Enlightenment S. <no-...@en...> - 2010-10-05 15:32:30
|
Log: * eio: more code to share. Author: cedric Date: 2010-10-05 08:32:24 -0700 (Tue, 05 Oct 2010) New Revision: 53065 Modified: trunk/eio/src/lib/eio_file.c trunk/eio/src/lib/eio_private.h Modified: trunk/eio/src/lib/eio_file.c =================================================================== --- trunk/eio/src/lib/eio_file.c 2010-10-05 15:19:11 UTC (rev 53064) +++ trunk/eio/src/lib/eio_file.c 2010-10-05 15:32:24 UTC (rev 53065) @@ -183,8 +183,8 @@ return EINA_TRUE; } -static void -_eio_file_progress(Eio_Progress *progress, Eio_File_Progress *op) +void +eio_progress_cb(Eio_Progress *progress, Eio_File_Progress *op) { op->progress_cb((void *) op->common.data, progress); @@ -295,7 +295,7 @@ if (in < 0) { eio_file_thread_error(©->common); - return ; + return EINA_FALSE; } /* @@ -353,7 +353,7 @@ { Eio_File_Progress *copy = data; - _eio_file_progress(msg_data, copy); + eio_progress_cb(msg_data, copy); } static void @@ -457,7 +457,7 @@ { Eio_File_Move *move = data; - _eio_file_progress(msg_data, &move->progress); + eio_progress_cb(msg_data, &move->progress); } static void @@ -642,7 +642,7 @@ copy = malloc(sizeof (Eio_File_Progress)); if (!copy) return NULL; - move->op = EIO_FILE_COPY; + copy->op = EIO_FILE_COPY; copy->progress_cb = progress_cb; copy->source = eina_stringshare_add(source); copy->dest = eina_stringshare_add(dest); Modified: trunk/eio/src/lib/eio_private.h =================================================================== --- trunk/eio/src/lib/eio_private.h 2010-10-05 15:19:11 UTC (rev 53064) +++ trunk/eio/src/lib/eio_private.h 2010-10-05 15:32:24 UTC (rev 53065) @@ -138,6 +138,8 @@ void eio_progress_free(Eio_Progress *progress); void eio_progress_send(Ecore_Thread *thread, Eio_File_Progress *op, off_t current, off_t max); +void eio_progress_cb(Eio_Progress *progress, Eio_File_Progress *op); + Eina_Bool eio_file_copy_do(Ecore_Thread *thread, Eio_File_Progress *copy); #endif |
From: Enlightenment S. <no-...@en...> - 2010-10-05 15:58:25
|
Log: * eio: follow efl coding style. Author: cedric Date: 2010-10-05 08:58:19 -0700 (Tue, 05 Oct 2010) New Revision: 53066 Modified: trunk/eio/src/lib/eio_file.c Modified: trunk/eio/src/lib/eio_file.c =================================================================== --- trunk/eio/src/lib/eio_file.c 2010-10-05 15:32:24 UTC (rev 53065) +++ trunk/eio/src/lib/eio_file.c 2010-10-05 15:58:19 UTC (rev 53066) @@ -84,7 +84,7 @@ } static void -_eio_file_notify(Ecore_Thread *thread __UNUSED__, void *msg_data, void *data) +_eio_file_notify(__UNUSED__ Ecore_Thread *thread, void *msg_data, void *data) { Eio_File_Char_Ls *async = data; const char *file = msg_data; @@ -139,7 +139,7 @@ } static void -_eio_file_direct_notify(Ecore_Thread *thread __UNUSED__, void *msg_data, void *data) +_eio_file_direct_notify(__UNUSED__ Ecore_Thread *thread, void *msg_data, void *data) { Eio_File_Direct_Ls *async = data; Eina_File_Direct_Info *info = msg_data; @@ -349,7 +349,7 @@ } static void -_eio_file_copy_notify(Ecore_Thread *thread __UNUSED__, void *msg_data, void *data) +_eio_file_copy_notify(__UNUSED__ Ecore_Thread *thread, void *msg_data, void *data) { Eio_File_Progress *copy = data; @@ -453,7 +453,7 @@ } static void -_eio_file_move_notify(Ecore_Thread *thread __UNUSED__, void *msg_data, void *data) +_eio_file_move_notify(__UNUSED__ Ecore_Thread *thread, void *msg_data, void *data) { Eio_File_Move *move = data; |
From: Enlightenment S. <no-...@en...> - 2010-10-05 16:46:47
|
Log: * eio: add eio_dir_copy. Little example on how to use it : #include <Ecore.h> #include <Eio.h> static void _test_notify_cb(void *data, const Eio_Progress *info) { switch (info->op) { case EIO_FILE_COPY: printf("[%s] %f%%\n", info->dest, info->percent); break; case EIO_DIR_COPY: printf("global [%li/%li] %f%%\n", info->current, info->max, info->percent); break; } } static void _test_done_cb(void *data) { printf("copy done\n"); ecore_main_loop_quit(); } static void _test_error_cb(int error, void *data) { fprintf(stderr, "error: [%s]\n", strerror(error)); ecore_main_loop_quit(); } int main(int argc, char **argv) { Eio_File *cp; if (argc != 3) { fprintf(stderr, "eio_cp source_file destination_file\n"); return -1; } ecore_init(); eio_init(); cp = eio_dir_copy(argv[1], argv[2], _test_notify_cb, _test_done_cb, _test_error_cb, NULL); ecore_main_loop_begin(); eio_shutdown(); ecore_shutdown(); return 0; } NOTE: be aware that it's your duty to provide the "right target". Meaning that copying to '.' will copy the content directly inside '.' and not in a subdirectory. Author: cedric Date: 2010-10-05 09:46:41 -0700 (Tue, 05 Oct 2010) New Revision: 53069 Added: trunk/eio/src/lib/eio_dir.c Modified: trunk/eio/src/lib/Makefile.am Modified: trunk/eio/src/lib/Makefile.am =================================================================== --- trunk/eio/src/lib/Makefile.am 2010-10-05 16:17:04 UTC (rev 53068) +++ trunk/eio/src/lib/Makefile.am 2010-10-05 16:46:41 UTC (rev 53069) @@ -12,7 +12,8 @@ libeio_la_SOURCES = \ eio_file.c \ eio_main.c \ -eio_single.c +eio_single.c \ +eio_dir.c libeio_la_LIBADD = @EIO_LIBS@ libeio_la_LDFLAGS = -no-undefined @lt_enable_auto_import@ -version-info @version_info@ @release_info@ |
From: Enlightenment S. <no-...@en...> - 2010-10-05 16:57:57
|
Log: * eio: fix coding style, the other way. Author: cedric Date: 2010-10-05 09:57:51 -0700 (Tue, 05 Oct 2010) New Revision: 53071 Modified: trunk/eio/src/lib/eio_dir.c trunk/eio/src/lib/eio_file.c Modified: trunk/eio/src/lib/eio_dir.c =================================================================== --- trunk/eio/src/lib/eio_dir.c 2010-10-05 16:54:24 UTC (rev 53070) +++ trunk/eio/src/lib/eio_dir.c 2010-10-05 16:57:51 UTC (rev 53071) @@ -246,7 +246,7 @@ } static void -_eio_dir_copy_notify( __UNUSED__ Ecore_Thread *thread, void *msg_data, void *data) +_eio_dir_copy_notify(Ecore_Thread *thread __UNUSED__, void *msg_data, void *data) { Eio_Dir_Copy *copy = data; Eio_Progress *progress = msg_data; Modified: trunk/eio/src/lib/eio_file.c =================================================================== --- trunk/eio/src/lib/eio_file.c 2010-10-05 16:54:24 UTC (rev 53070) +++ trunk/eio/src/lib/eio_file.c 2010-10-05 16:57:51 UTC (rev 53071) @@ -84,7 +84,7 @@ } 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_File_Char_Ls *async = data; const char *file = msg_data; @@ -139,7 +139,7 @@ } 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_File_Direct_Ls *async = data; Eina_File_Direct_Info *info = msg_data; @@ -349,7 +349,7 @@ } static void -_eio_file_copy_notify(__UNUSED__ Ecore_Thread *thread, void *msg_data, void *data) +_eio_file_copy_notify(Ecore_Thread *thread __UNUSED__, void *msg_data, void *data) { Eio_File_Progress *copy = data; @@ -453,7 +453,7 @@ } static void -_eio_file_move_notify(__UNUSED__ Ecore_Thread *thread, void *msg_data, void *data) +_eio_file_move_notify(Ecore_Thread *thread __UNUSED__, void *msg_data, void *data) { Eio_File_Move *move = data; |
From: Enlightenment S. <no-...@en...> - 2010-10-06 09:54:07
|
Log: * eio: reduce code duplication. Author: cedric Date: 2010-10-06 02:54:00 -0700 (Wed, 06 Oct 2010) New Revision: 53094 Modified: trunk/eio/src/lib/eio_dir.c trunk/eio/src/lib/eio_file.c Modified: trunk/eio/src/lib/eio_dir.c =================================================================== --- trunk/eio/src/lib/eio_dir.c 2010-10-06 08:53:06 UTC (rev 53093) +++ trunk/eio/src/lib/eio_dir.c 2010-10-06 09:54:00 UTC (rev 53094) @@ -255,15 +255,21 @@ } static void +_eio_dir_copy_free(Eio_Dir_Copy *copy) +{ + eina_stringshare_del(copy->progress.source); + eina_stringshare_del(copy->progress.dest); + free(copy); +} + +static void _eio_dir_copy_end(void *data) { Eio_Dir_Copy *copy = data; copy->progress.common.done_cb((void*) copy->progress.common.data); - eina_stringshare_del(copy->progress.source); - eina_stringshare_del(copy->progress.dest); - free(copy); + _eio_dir_copy_free(copy); } static void @@ -273,9 +279,7 @@ eio_file_error(©->progress.common); - eina_stringshare_del(copy->progress.source); - eina_stringshare_del(copy->progress.dest); - free(copy); + _eio_dir_copy_free(copy); } /** Modified: trunk/eio/src/lib/eio_file.c =================================================================== --- trunk/eio/src/lib/eio_file.c 2010-10-06 08:53:06 UTC (rev 53093) +++ trunk/eio/src/lib/eio_file.c 2010-10-06 09:54:00 UTC (rev 53094) @@ -357,15 +357,21 @@ } static void +_eio_file_copy_free(Eio_File_Progress *copy) +{ + eina_stringshare_del(copy->source); + eina_stringshare_del(copy->dest); + free(copy); +} + +static void _eio_file_copy_end(void *data) { Eio_File_Progress *copy = data; copy->common.done_cb((void*) copy->common.data); - eina_stringshare_del(copy->source); - eina_stringshare_del(copy->dest); - free(copy); + _eio_file_copy_free(copy); } static void @@ -375,12 +381,18 @@ eio_file_error(©->common); - eina_stringshare_del(copy->source); - eina_stringshare_del(copy->dest); - free(copy); + _eio_file_copy_free(copy); } static void +_eio_file_move_free(Eio_File_Move *move) +{ + eina_stringshare_del(move->progress.source); + eina_stringshare_del(move->progress.dest); + free(move); +} + +static void _eio_file_move_copy_progress(void *data, const Eio_Progress *info) { Eio_File_Move *move = data; @@ -395,9 +407,7 @@ move->progress.common.done_cb((void*) move->progress.common.data); - eina_stringshare_del(move->progress.source); - eina_stringshare_del(move->progress.dest); - free(move); + _eio_file_move_free(move); } static void @@ -410,9 +420,7 @@ move->progress.common.error = error; eio_file_error(&move->progress.common); - eina_stringshare_del(move->progress.source); - eina_stringshare_del(move->progress.dest); - free(move); + _eio_file_move_free(move); } static void @@ -436,9 +444,7 @@ move->progress.common.error = error; eio_file_error(&move->progress.common); - eina_stringshare_del(move->progress.source); - eina_stringshare_del(move->progress.dest); - free(move); + _eio_file_move_free(move); } static void @@ -467,9 +473,7 @@ move->progress.common.done_cb((void*) move->progress.common.data); - eina_stringshare_del(move->progress.source); - eina_stringshare_del(move->progress.dest); - free(move); + _eio_file_move_free(move); } static void @@ -504,9 +508,7 @@ eio_file_error(&move->progress.common); - eina_stringshare_del(move->progress.source); - eina_stringshare_del(move->progress.dest); - free(move); + _eio_file_move_free(move); } /** |
From: Enlightenment S. <no-...@en...> - 2010-10-11 12:40:27
|
Log: * eio: improve allocation code for eio_file_direct_ls. Author: cedric Date: 2010-10-11 05:40:20 -0700 (Mon, 11 Oct 2010) New Revision: 53262 Modified: trunk/eio/src/lib/eio_file.c trunk/eio/src/lib/eio_main.c trunk/eio/src/lib/eio_private.h Modified: trunk/eio/src/lib/eio_file.c =================================================================== --- trunk/eio/src/lib/eio_file.c 2010-10-11 09:53:52 UTC (rev 53261) +++ trunk/eio/src/lib/eio_file.c 2010-10-11 12:40:20 UTC (rev 53262) @@ -120,7 +120,7 @@ { Eina_File_Direct_Info *send; - send = malloc(sizeof (Eina_File_Direct_Info) + sizeof (struct dirent)); + send = eio_direct_info_malloc(); if (!send) continue; memcpy(send, info, sizeof (Eina_File_Direct_Info)); @@ -145,7 +145,7 @@ async->main_cb((void*) async->ls.common.data, info); - free(info); + eio_direct_info_free(info); } static void Modified: trunk/eio/src/lib/eio_main.c =================================================================== --- trunk/eio/src/lib/eio_main.c 2010-10-11 09:53:52 UTC (rev 53261) +++ trunk/eio/src/lib/eio_main.c 2010-10-11 12:40:20 UTC (rev 53262) @@ -22,6 +22,7 @@ #endif #include <pthread.h> +#include <dirent.h> #include "eio_private.h" @@ -30,10 +31,19 @@ static int _eio_count = 0; /* Progress pool */ -static pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER; -static Eina_Trash *trash = NULL; -static int trash_count = 0; +typedef struct _Eio_Alloc_Pool Eio_Alloc_Pool; +struct _Eio_Alloc_Pool +{ + int count; + Eina_Trash *trash; + + pthread_mutex_t lock; +}; + +static Eio_Alloc_Pool progress = { 0, NULL, PTHREAD_MUTEX_INITIALIZER }; +static Eio_Alloc_Pool direct_info = { 0, NULL, PTHREAD_MUTEX_INITIALIZER }; + EAPI int eio_init(void) { @@ -50,56 +60,76 @@ EAPI int eio_shutdown(void) { - Eio_Progress *progress; + Eina_File_Direct_Info *info; + Eio_Progress *pg; _eio_count--; if (_eio_count > 0) return _eio_count; - /* Cleanup progress pool */ - EINA_TRASH_CLEAN(&trash, progress) - free(progress); - trash_count = 0; + /* Cleanup pool */ + EINA_TRASH_CLEAN(&progress.trash, pg) + free(pg); + progress.count = 0; + EINA_TRASH_CLEAN(&direct_info.trash, info) + free(info); + direct_info.count = 0; + ecore_shutdown(); eina_shutdown(); return _eio_count; } -Eio_Progress * -eio_progress_malloc(void) +static void * +_eio_pool_malloc(Eio_Alloc_Pool *pool, size_t sz) { - Eio_Progress *progress; + void *result = NULL; - pthread_mutex_lock(&lock); - progress = eina_trash_pop(&trash); - if (progress) trash_count--; - pthread_mutex_unlock(&lock); + if (pool->count) + { + pthread_mutex_lock(&pool->lock); + result = eina_trash_pop(&pool->trash); + if (result) pool->count--; + pthread_mutex_unlock(&pool->lock); + } - if (!progress) progress = malloc(sizeof (Eio_Progress)); - return progress; + if (!result) result = malloc(sz); + return result; } -void -eio_progress_free(Eio_Progress *progress) +static void +_eio_pool_free(Eio_Alloc_Pool *pool, void *data) { - eina_stringshare_del(progress->source); - eina_stringshare_del(progress->dest); - - if (trash_count >= EIO_PROGRESS_LIMIT) + if (pool->count >= EIO_PROGRESS_LIMIT) { - free(progress); + free(data); } else { - pthread_mutex_lock(&lock); - eina_trash_push(&trash, progress); - trash_count++; - pthread_mutex_unlock(&lock); + 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; @@ -120,3 +150,15 @@ 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); +} + Modified: trunk/eio/src/lib/eio_private.h =================================================================== --- trunk/eio/src/lib/eio_private.h 2010-10-11 09:53:52 UTC (rev 53261) +++ trunk/eio/src/lib/eio_private.h 2010-10-11 12:40:20 UTC (rev 53262) @@ -134,8 +134,12 @@ void eio_file_error(Eio_File *common); void eio_file_thread_error(Eio_File *common); +Eina_File_Direct_Info *eio_direct_info_malloc(void); +void eio_direct_info_free(Eina_File_Direct_Info *data); + Eio_Progress *eio_progress_malloc(void); void eio_progress_free(Eio_Progress *progress); + void eio_progress_send(Ecore_Thread *thread, Eio_File_Progress *op, off_t current, off_t max); void eio_progress_cb(Eio_Progress *progress, Eio_File_Progress *op); |
From: Enlightenment S. <no-...@en...> - 2010-10-13 10:59:42
|
Log: * eio: fix use of ecore_thread_*run. Author: cedric Date: 2010-10-13 03:59:33 -0700 (Wed, 13 Oct 2010) New Revision: 53348 Modified: trunk/eio/src/lib/eio_single.c Modified: trunk/eio/src/lib/eio_single.c =================================================================== --- trunk/eio/src/lib/eio_single.c 2010-10-13 10:36:04 UTC (rev 53347) +++ trunk/eio/src/lib/eio_single.c 2010-10-13 10:59:33 UTC (rev 53348) @@ -45,20 +45,25 @@ 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. */ - common->thread = ecore_thread_feedback_run(heavy_cb, - notify_cb, - end_cb, - cancel_cb, - common, - EINA_TRUE); - return !!common->thread; + /* 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 @@ -70,15 +75,21 @@ 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. */ - common->thread = ecore_thread_run(job_cb, end_cb, cancel_cb, common); - return !!common->thread; + /* 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; } /* --- */ |
From: Enlightenment S. <no-...@en...> - 2010-10-13 16:45:52
|
Log: * eio: remove unecessary call. Author: cedric Date: 2010-10-13 09:45:45 -0700 (Wed, 13 Oct 2010) New Revision: 53365 Modified: trunk/eio/src/lib/eio_main.c Modified: trunk/eio/src/lib/eio_main.c =================================================================== --- trunk/eio/src/lib/eio_main.c 2010-10-13 16:44:15 UTC (rev 53364) +++ trunk/eio/src/lib/eio_main.c 2010-10-13 16:45:45 UTC (rev 53365) @@ -50,7 +50,6 @@ if (_eio_count > 1) return _eio_count; eina_init(); - eina_threads_init(); ecore_init(); return _eio_count; @@ -76,7 +75,6 @@ direct_info.count = 0; ecore_shutdown(); - eina_threads_shutdown(); eina_shutdown(); return _eio_count; } |
From: Enlightenment S. <no-...@en...> - 2010-10-20 12:09:02
|
Log: * eio: small doxy fix. Author: cedric Date: 2010-10-20 05:08:56 -0700 (Wed, 20 Oct 2010) New Revision: 53656 Modified: trunk/eio/src/lib/eio_file.c trunk/eio/src/lib/eio_single.c Modified: trunk/eio/src/lib/eio_file.c =================================================================== --- trunk/eio/src/lib/eio_file.c 2010-10-20 12:08:42 UTC (rev 53655) +++ trunk/eio/src/lib/eio_file.c 2010-10-20 12:08:56 UTC (rev 53656) @@ -496,6 +496,7 @@ * @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. + * @param data Data passed to callback and not modified at all by eio_file_ls. * @return A reference to the IO operation. * * eio_file_ls run eina_file_ls in a separated thread using ecore_thread_feedback_run. This prevent @@ -543,6 +544,7 @@ * @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. + * @param data Data passed to callback and not modified at all by eio_file_direct_ls. * @return A reference to the IO operation. * * eio_file_direct_ls run eina_file_direct_ls in a separated thread using Modified: trunk/eio/src/lib/eio_single.c =================================================================== --- trunk/eio/src/lib/eio_single.c 2010-10-20 12:08:42 UTC (rev 53655) +++ trunk/eio/src/lib/eio_single.c 2010-10-20 12:08:56 UTC (rev 53656) @@ -211,8 +211,10 @@ /** * @brief Stat a file/directory. + * @param path The path to stat. * @param done_cb Callback called from the main loop when stat was successfully called.. * @param error_cb Callback called from the main loop when stat failed or has been canceled. + * @param data Private data given to callback. * @return A reference to the IO operation. * * eio_file_direct_stat basically call stat in another thread. This prevent any lock in your apps. @@ -248,9 +250,10 @@ /** * @brief Unlink a file/directory. - * @param mode The permission to set, follow (mode & ~umask & 0777). + * @param path The path to unlink. * @param done_cb Callback called from the main loop when the directory has been created. * @param error_cb Callback called from the main loop when the directory failed to be created or has been canceled. + * @param data Private data given to callback. * @return A reference to the IO operation. * * eio_file_unlink basically call unlink in another thread. This prevent any lock in your apps. @@ -289,6 +292,7 @@ * @param mode The permission to set, follow (mode & ~umask & 0777). * @param done_cb Callback called from the main loop when the directory has been created. * @param error_cb Callback called from the main loop when the directory failed to be created or has been canceled. + * @param data Private data given to callback. * @return A reference to the IO operation. * * eio_file_mkdir basically call mkdir in another thread. This prevent any lock in your apps. |
From: Enlightenment S. <no-...@en...> - 2010-10-20 12:10:05
|
Log: * eio: add eio_dir_move. Author: cedric Date: 2010-10-20 05:09:58 -0700 (Wed, 20 Oct 2010) New Revision: 53657 Modified: trunk/eio/src/lib/eio_dir.c Modified: trunk/eio/src/lib/eio_dir.c =================================================================== --- trunk/eio/src/lib/eio_dir.c 2010-10-20 12:08:56 UTC (rev 53656) +++ trunk/eio/src/lib/eio_dir.c 2010-10-20 12:09:58 UTC (rev 53657) @@ -44,7 +44,6 @@ EINA_ITERATOR_FOREACH(it, info) { - fprintf(stderr, "entry: %s\n", info->path); switch (info->dirent->d_type) { case DT_UNKNOWN: @@ -93,111 +92,199 @@ return EINA_FALSE; } -static void -_eio_dir_copy_heavy(Ecore_Thread *thread, void *data) +static Eina_Bool +_eio_dir_init(Ecore_Thread *thread, + off_t *step, off_t *count, + int *length_source, int *length_dest, + Eio_Dir_Copy *order, + Eio_File_Progress *progress) { - Eio_Dir_Copy *copy = data; - const char *file = NULL; - const char *dir = NULL; - - Eio_File_Progress file_copy; - char target[PATH_MAX]; struct stat buffer; - int length_source; - int length_dest; - off_t count; - off_t step; - - /* list all the content that should be copied */ - if (!_eio_dir_recursiv_ls(thread, copy, copy->progress.source)) - return ; - /* notify main thread of the amount of work todo */ - step = 0; - count = eina_list_count(copy->files) + eina_list_count(copy->dirs); - eio_progress_send(thread, ©->progress, step, count); + *step = 0; + *count = eina_list_count(order->files) + eina_list_count(order->dirs) * 2; + eio_progress_send(thread, &order->progress, *step, *count); /* sort the content, so we create the directory in the right order */ - copy->dirs = eina_list_sort(copy->dirs, -1, eio_strcmp); - copy->files = eina_list_sort(copy->files, -1, eio_strcmp); + order->dirs = eina_list_sort(order->dirs, -1, eio_strcmp); + order->files = eina_list_sort(order->files, -1, eio_strcmp); /* prepare stuff */ - length_source = eina_stringshare_strlen(copy->progress.source); - length_dest = eina_stringshare_strlen(copy->progress.dest); + *length_source = eina_stringshare_strlen(order->progress.source); + *length_dest = eina_stringshare_strlen(order->progress.dest); - memcpy(&file_copy, ©->progress, sizeof (Eio_File_Progress)); - file_copy.op = EIO_FILE_COPY; - file_copy.source = NULL; - file_copy.dest = NULL; + memcpy(progress, &order->progress, sizeof (Eio_File_Progress)); + progress->source = NULL; + progress->dest = NULL; /* create destination dir if not available */ - if (stat(copy->progress.dest, &buffer) != 0) + if (stat(order->progress.dest, &buffer) != 0) { - if (stat(copy->progress.source, &buffer) != 0) + if (stat(order->progress.source, &buffer) != 0) { - eio_file_thread_error(©->progress.common, thread); - goto on_error; + eio_file_thread_error(&order->progress.common, thread); + return EINA_FALSE; } - if (mkdir(copy->progress.dest, buffer.st_mode) != 0) + if (mkdir(order->progress.dest, buffer.st_mode) != 0) { - eio_file_thread_error(©->progress.common, thread); - goto on_error; + eio_file_thread_error(&order->progress.common, thread); + return EINA_FALSE; } } + return EINA_TRUE; +} + +static void +_eio_dir_target(Eio_Dir_Copy *order, char *target, const char *dir, int length_source, int length_dest) +{ + int length; + + length = eina_stringshare_strlen(dir); + + memcpy(target, order->progress.dest, length_dest); + target[length_dest] = '/'; + memcpy(target + length_dest + 1, dir + length_source, length - length_source + 1); +} + +static Eina_Bool +_eio_dir_mkdir(Ecore_Thread *thread, Eio_Dir_Copy *order, + off_t *step, off_t count, + int length_source, int length_dest) +{ + const char *dir; + Eina_List *l; + char target[PATH_MAX]; + /* create all directory */ - EINA_LIST_FREE(copy->dirs, dir) + EINA_LIST_FOREACH(order->dirs, l, dir) { /* build target dir path */ - strcpy(target, copy->progress.dest); - target[length_dest] = '/'; - strcpy(target + length_dest + 1, dir + length_source); + _eio_dir_target(order, target, dir, length_source, length_dest); - /* stat the original file for mode info */ - /* FIXME: in some case we already did a stat call, so would be nice to reuse previous result here */ - /* FIXME: apply mode later so that readonly could be copied and property will be set correctly */ - if (stat(dir, &buffer) != 0) + /* create the directory (we will apply the mode later) */ + if (mkdir(target, 0777) != 0) { - eio_file_thread_error(©->progress.common, thread); - goto on_error; + eio_file_thread_error(&order->progress.common, thread); + return EINA_FALSE; } - /* create the directory */ - if (mkdir(target, buffer.st_mode) != 0) + /* inform main thread */ + (*step)++; + eio_progress_send(thread, &order->progress, *step, count); + + /* check for cancel request */ + if (ecore_thread_check(thread)) + return EINA_FALSE; + } + + return EINA_TRUE; +} + +static Eina_Bool +_eio_dir_chmod(Ecore_Thread *thread, Eio_Dir_Copy *order, + off_t *step, off_t count, + int length_source, int length_dest, + Eina_Bool rmdir_source) +{ + const char *dir; + char target[PATH_MAX]; + struct stat buffer; + + while(order->dirs) + { + /* destroy in reverse order so that we don't prevent change of lower dir */ + dir = eina_list_data_get(eina_list_last(order->dirs)); + order->dirs = eina_list_remove_list(order->dirs, eina_list_last(order->dirs)); + + /* build target dir path */ + _eio_dir_target(order, target, dir, length_source, length_dest); + + /* FIXME: in some case we already did a stat call, so would be nice to reuse previous result here */ + /* stat the original dir for mode info */ + if (stat(dir, &buffer) != 0) + goto on_error; + + /* set the orginal mode to the newly created dir */ + if (chmod(target, buffer.st_mode) != 0) + goto on_error; + + /* if required destroy original directory */ + if (rmdir_source) { - eio_file_thread_error(©->progress.common, thread); - goto on_error; + if (rmdir(dir) != 0) + goto on_error; } - step++; - eio_progress_send(thread, ©->progress, step, count); + /* inform main thread */ + (*step)++; + eio_progress_send(thread, &order->progress, *step, count); + /* check for cancel request */ if (ecore_thread_check(thread)) - goto on_error; + goto on_cancel; eina_stringshare_del(dir); } - dir = NULL; - /* Copy all files */ + return EINA_TRUE; + + on_error: + eio_file_thread_error(&order->progress.common, thread); + on_cancel: + if (dir) eina_stringshare_del(dir); + return EINA_FALSE; +} + +static void +_eio_dir_copy_heavy(Ecore_Thread *thread, void *data) +{ + Eio_Dir_Copy *copy = data; + const char *file = NULL; + const char *dir = NULL; + + Eio_File_Progress file_copy; + char target[PATH_MAX]; + + int length_source = 0; + int length_dest = 0; + off_t count; + off_t step; + + /* list all the content that should be copied */ + if (!_eio_dir_recursiv_ls(thread, copy, copy->progress.source)) + return ; + + /* init all structure needed to copy the file */ + if (!_eio_dir_init(thread, &step, &count, &length_source, &length_dest, copy, &file_copy)) + goto on_error; + + /* suboperation is a file copy */ + file_copy.op = EIO_FILE_COPY; + + /* create all directory */ + if (!_eio_dir_mkdir(thread, copy, &step, count, length_source, length_dest)) + goto on_error; + + /* copy all files */ EINA_LIST_FREE(copy->files, file) { - /* build target dir path */ - strcpy(target, copy->progress.dest); - target[length_dest] = '/'; - strcpy(target + length_dest + 1, file + length_source); + /* build target file path */ + _eio_dir_target(copy, target, file, length_source, length_dest); file_copy.source = file; file_copy.dest = eina_stringshare_add(target); + /* copy the file */ if (!eio_file_copy_do(thread, &file_copy)) { copy->progress.common.error = file_copy.common.error; goto on_error; } + /* notify main thread */ step++; eio_progress_send(thread, ©->progress, step, count); @@ -210,10 +297,13 @@ file_copy.dest = NULL; file = NULL; + /* set directory right back */ + if (!_eio_dir_chmod(thread, copy, &step, count, length_source, length_dest, EINA_FALSE)) + goto on_error; + on_error: /* cleanup the mess */ if (file_copy.dest) eina_stringshare_del(file_copy.dest); - if (dir) eina_stringshare_del(dir); if (file) eina_stringshare_del(file); EINA_LIST_FREE(copy->files, file) @@ -264,7 +354,112 @@ _eio_dir_copy_free(copy); } +static void +_eio_dir_move_heavy(Ecore_Thread *thread, void *data) +{ + Eio_Dir_Copy *move = data; + const char *file = NULL; + const char *dir = NULL; + Eio_File_Progress file_move; + char target[PATH_MAX]; + + int length_source; + int length_dest; + off_t count; + off_t step; + + /* just try a rename, maybe we are lucky... */ + if (rename(move->progress.source, move->progress.dest) == 0) + { + /* we are really lucky */ + eio_progress_send(thread, &move->progress, 1, 1); + return ; + } + + /* list all the content that should be moved */ + if (!_eio_dir_recursiv_ls(thread, move, move->progress.source)) + return ; + + /* init all structure needed to move the file */ + if (!_eio_dir_init(thread, &step, &count, &length_source, &length_dest, move, &file_move)) + goto on_error; + + /* sub operation is a file move */ + file_move.op = EIO_FILE_MOVE; + + /* create all directory */ + if (!_eio_dir_mkdir(thread, move, &step, count, length_source, length_dest)) + goto on_error; + + /* move file around */ + EINA_LIST_FREE(move->files, file) + { + /* build target file path */ + _eio_dir_target(move, target, file, length_source, length_dest); + + file_move.source = file; + file_move.dest = eina_stringshare_add(target); + + /* first try to rename */ + if (rename(file_move.source, file_move.dest) < 0) + { + if (errno != EXDEV) + { + eio_file_thread_error(&move->progress.common, thread); + goto on_error; + } + + /* then try real copy */ + if (!eio_file_copy_do(thread, &file_move)) + { + move->progress.common.error = file_move.common.error; + goto on_error; + } + + /* and unlink the original */ + if (unlink(file) != 0) + { + eio_file_thread_error(&move->progress.common, thread); + goto on_error; + } + } + + step++; + eio_progress_send(thread, &move->progress, step, count); + + if (ecore_thread_check(thread)) + goto on_error; + + eina_stringshare_del(file_move.dest); + eina_stringshare_del(file); + } + file_move.dest = NULL; + file = NULL; + + /* set directory right back */ + if (!_eio_dir_chmod(thread, move, &step, count, length_source, length_dest, EINA_TRUE)) + goto on_error; + + if (rmdir(move->progress.source) != 0) + goto on_error; + + on_error: + /* cleanup the mess */ + if (file_move.dest) eina_stringshare_del(file_move.dest); + if (file) eina_stringshare_del(file); + + EINA_LIST_FREE(move->files, file) + eina_stringshare_del(file); + EINA_LIST_FREE(move->dirs, dir) + eina_stringshare_del(dir); + + if (!ecore_thread_check(thread)) + eio_progress_send(thread, &move->progress, count, count); + + return; +} + /** * @addtogroup Eio_Group Asynchronous Inout/Output library * @@ -282,7 +477,7 @@ * * This function will copy a directory and all it's content from source to dest. * It will try to use splice if possible, if not it will fallback to mmap/write. - * It will try to preserve access right, but not user/group identification. + * It will try to preserve access right, but not user/group identity. */ EAPI Eio_File * eio_dir_copy(const char *source, @@ -322,5 +517,56 @@ } /** + * @brief Move a directory and it's content asynchronously + * @param source Should be the name of the directory to copy the data from. + * @param dest Should be the name of the directory to copy the data to. + * @param progress_cb Callback called to know the progress of the copy. + * @param done_cb Callback called when the copy is done. + * @param error_cb Callback called when something goes wrong. + * @param data Private data given to callback. + * + * This function will move a directory and all it's content from source to dest. + * It will try first to rename the directory, if not it will try to use splice + * if possible, if not it will fallback to mmap/write. + * It will try to preserve access right, but not user/group identity. + */ +EAPI Eio_File * +eio_dir_move(const char *source, + const char *dest, + Eio_Progress_Cb progress_cb, + Eio_Done_Cb done_cb, + Eio_Error_Cb error_cb, + const void *data) +{ + Eio_Dir_Copy *move; + + EINA_SAFETY_ON_NULL_RETURN_VAL(source, NULL); + EINA_SAFETY_ON_NULL_RETURN_VAL(dest, NULL); + EINA_SAFETY_ON_NULL_RETURN_VAL(done_cb, NULL); + EINA_SAFETY_ON_NULL_RETURN_VAL(error_cb, NULL); + + move = malloc(sizeof(Eio_Dir_Copy)); + EINA_SAFETY_ON_NULL_RETURN_VAL(move, NULL); + + move->progress.op = EIO_DIR_MOVE; + move->progress.progress_cb = progress_cb; + move->progress.source = eina_stringshare_add(source); + move->progress.dest = eina_stringshare_add(dest); + move->files = NULL; + + if (!eio_long_file_set(&move->progress.common, + done_cb, + error_cb, + data, + _eio_dir_move_heavy, + _eio_dir_copy_notify, + _eio_dir_copy_end, + _eio_dir_copy_error)) + return NULL; + + return &move->progress.common; +} + +/** * @} */ |
From: Enlightenment S. <no-...@en...> - 2010-10-20 12:20:14
|
Log: * eio: more doxy fix. Author: cedric Date: 2010-10-20 05:20:06 -0700 (Wed, 20 Oct 2010) New Revision: 53658 Modified: trunk/eio/src/lib/Eio.h trunk/eio/src/lib/eio_main.c Modified: trunk/eio/src/lib/Eio.h =================================================================== --- trunk/eio/src/lib/Eio.h 2010-10-20 12:09:58 UTC (rev 53657) +++ trunk/eio/src/lib/Eio.h 2010-10-20 12:20:06 UTC (rev 53658) @@ -75,15 +75,14 @@ typedef enum _Eio_File_Op { - EIO_FILE_COPY, - EIO_FILE_MOVE, - EIO_DIR_COPY, - EIO_DIR_MOVE + EIO_FILE_COPY, /**< IO operation is about a specific file copy */ + EIO_FILE_MOVE, /**< IO operation is about a specific file move */ + EIO_DIR_COPY, /**< IO operation is about a specific directory copy */ + EIO_DIR_MOVE /**< IO operation is about a specific directory move */ } Eio_File_Op; -typedef struct _Eio_File Eio_File; -typedef struct _Eio_Progress Eio_Progress; -typedef struct _Eio_Stat Eio_Stat; +typedef struct _Eio_File Eio_File; /**< Generic asynchronous IO reference */ +typedef struct _Eio_Progress Eio_Progress; /**< Progress information on a specific operation */ typedef Eina_Bool (*Eio_Filter_Cb)(void *data, const char *file); typedef void (*Eio_Main_Cb)(void *data, const char *file); @@ -99,14 +98,14 @@ struct _Eio_Progress { - Eio_File_Op op; + Eio_File_Op op; /**< IO type */ - off_t current; - off_t max; - float percent; + off_t current; /**< Current step in the IO operation */ + off_t max; /**< Number of step to do to complete this IO */ + float percent; /**< Percent done of the IO operation */ - const char *source; - const char *dest; + const char *source; /**< source of the IO operation */ + const char *dest; /**< target of the IO operation */ }; EAPI int eio_init(void); Modified: trunk/eio/src/lib/eio_main.c =================================================================== --- trunk/eio/src/lib/eio_main.c 2010-10-20 12:09:58 UTC (rev 53657) +++ trunk/eio/src/lib/eio_main.c 2010-10-20 12:20:06 UTC (rev 53658) @@ -42,6 +42,10 @@ * @{ */ +/** + * @brief Initialize eio and all it's required submodule. + * @return the current number of eio users. + */ EAPI int eio_init(void) { @@ -55,6 +59,10 @@ return _eio_count; } +/** + * @brief Shutdown eio and all it's submodule if possible. + * @return the number of pending users of eio. + */ EAPI int eio_shutdown(void) { |
From: Enlightenment S. <no-...@en...> - 2010-10-20 13:48:23
|
Log: * eio: add eio_dir_unlink. Author: cedric Date: 2010-10-20 06:48:13 -0700 (Wed, 20 Oct 2010) New Revision: 53664 Modified: trunk/eio/src/lib/Eio.h trunk/eio/src/lib/eio_dir.c Modified: trunk/eio/src/lib/Eio.h =================================================================== --- trunk/eio/src/lib/Eio.h 2010-10-20 12:40:36 UTC (rev 53663) +++ trunk/eio/src/lib/Eio.h 2010-10-20 13:48:13 UTC (rev 53664) @@ -78,7 +78,8 @@ EIO_FILE_COPY, /**< IO operation is about a specific file copy */ EIO_FILE_MOVE, /**< IO operation is about a specific file move */ EIO_DIR_COPY, /**< IO operation is about a specific directory copy */ - EIO_DIR_MOVE /**< IO operation is about a specific directory move */ + EIO_DIR_MOVE, /**< IO operation is about a specific directory move */ + 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_Op; typedef struct _Eio_File Eio_File; /**< Generic asynchronous IO reference */ Modified: trunk/eio/src/lib/eio_dir.c =================================================================== --- trunk/eio/src/lib/eio_dir.c 2010-10-20 12:40:36 UTC (rev 53663) +++ trunk/eio/src/lib/eio_dir.c 2010-10-20 13:48:13 UTC (rev 53664) @@ -460,6 +460,83 @@ return; } +static void +_eio_dir_rmrf_heavy(Ecore_Thread *thread, void *data) +{ + Eio_Dir_Copy *rmrf = data; + const char *file = NULL; + const char *dir = NULL; + + off_t count; + off_t step; + + /* list all the content that should be moved */ + if (!_eio_dir_recursiv_ls(thread, rmrf, rmrf->progress.source)) + return ; + + /* init counter */ + step = 0; + count = eina_list_count(rmrf->files) + eina_list_count(rmrf->dirs) + 1; + + EINA_LIST_FREE(rmrf->files, file) + { + if (unlink(file) != 0) + { + eio_file_thread_error(&rmrf->progress.common, thread); + goto on_error; + } + + eina_stringshare_replace(&rmrf->progress.dest, file); + + step++; + eio_progress_send(thread, &rmrf->progress, step, count); + + if (ecore_thread_check(thread)) + goto on_error; + + eina_stringshare_del(file); + } + file = NULL; + + EINA_LIST_FREE(rmrf->dirs, dir) + { + if (rmdir(dir) != 0) + { + eio_file_thread_error(&rmrf->progress.common, thread); + goto on_error; + } + + eina_stringshare_replace(&rmrf->progress.dest, dir); + + step++; + eio_progress_send(thread, &rmrf->progress, step, count); + + if (ecore_thread_check(thread)) + goto on_error; + + eina_stringshare_del(dir); + } + dir = NULL; + + if (rmdir(rmrf->progress.source) != 0) + goto on_error; + step++; + + on_error: + if (dir) eina_stringshare_del(dir); + if (file) eina_stringshare_del(file); + + EINA_LIST_FREE(rmrf->dirs, dir) + eina_stringshare_del(dir); + EINA_LIST_FREE(rmrf->files, file) + eina_stringshare_del(file); + + if (!ecore_thread_check(thread)) + eio_progress_send(thread, &rmrf->progress, count, count); + + return; +} + /** * @addtogroup Eio_Group Asynchronous Inout/Output library * @@ -502,6 +579,7 @@ copy->progress.source = eina_stringshare_add(source); copy->progress.dest = eina_stringshare_add(dest); copy->files = NULL; + copy->dirs = NULL; if (!eio_long_file_set(©->progress.common, done_cb, @@ -553,6 +631,7 @@ move->progress.source = eina_stringshare_add(source); move->progress.dest = eina_stringshare_add(dest); move->files = NULL; + move->dirs = NULL; if (!eio_long_file_set(&move->progress.common, done_cb, @@ -568,5 +647,54 @@ } /** + * @brief Remove a directory and it's content asynchronously + * @param path Should be the name of the directory to destroy. + * @param progress_cb Callback called to know the progress of the copy. + * @param done_cb Callback called when the copy is done. + * @param error_cb Callback called when something goes wrong. + * @param data Private data given to callback. + * + * This function will move a directory and all it's content from source to dest. + * It will try first to rename the directory, if not it will try to use splice + * if possible, if not it will fallback to mmap/write. + * It will try to preserve access right, but not user/group identity. + */ +EAPI Eio_File * +eio_dir_unlink(const char *path, + Eio_Progress_Cb progress_cb, + Eio_Done_Cb done_cb, + Eio_Error_Cb error_cb, + const void *data) +{ + Eio_Dir_Copy *rmrf; + + EINA_SAFETY_ON_NULL_RETURN_VAL(path, NULL); + EINA_SAFETY_ON_NULL_RETURN_VAL(done_cb, NULL); + EINA_SAFETY_ON_NULL_RETURN_VAL(error_cb, NULL); + + rmrf = malloc(sizeof(Eio_Dir_Copy)); + EINA_SAFETY_ON_NULL_RETURN_VAL(rmrf, NULL); + + rmrf->progress.op = EIO_UNLINK; + rmrf->progress.progress_cb = progress_cb; + rmrf->progress.source = eina_stringshare_add(path); + rmrf->progress.dest = NULL; + rmrf->files = NULL; + rmrf->dirs = NULL; + + if (!eio_long_file_set(&rmrf->progress.common, + done_cb, + error_cb, + data, + _eio_dir_rmrf_heavy, + _eio_dir_copy_notify, + _eio_dir_copy_end, + _eio_dir_copy_error)) + return NULL; + + return &rmrf->progress.common; +} + +/** * @} */ |