From: Leandro D. <do...@pr...> - 2012-09-24 13:48:56
|
Hi Guillaume, On Mon, Sep 24, 2012 at 01:54:45PM +0200, Guillaume Friloux wrote: > On 24/09/2012 13:40, Guillaume Friloux wrote: > >Added a mutex to not get crappy values when multiple calls to > >filter_cb are done (eio can launch multiple threads it seems) > > > Fuck me i suck. This version is better. > > /* > * Compile : > * gcc -g -o eio_file_stat_ls eio_file_stat_ls.c `pkg-config --cflags --libs eina ecore eio` > * > * Prepare : > * mkdir test > * touch test/456 > * touch test/excluded > * touch test/backuped > * > * Run : > * ./eio_file_stat_ls test > */ > > #include <Eio.h> > #include <regex.h> > > struct _Filter > { > const char *name; > regex_t preg; > }; > > struct _Data > { > unsigned int count_filtered, > count_passed, > count_total, > jobs; > Eina_List *l_filters; > Eina_Lock mutex; > }; > > void _free_cb(void *data) > { > return; > } You don't need this callback. > > void _filter_add(struct _Data *data, const char *name) > { > struct _Filter *obj; > > obj = calloc(1, sizeof(struct _Filter)); > if (!obj) > return; > > if (regcomp(&(obj->preg), name, REG_EXTENDED)) > { > fprintf(stderr, "Failed to compile regex for \"%s\"\n", name); > free(obj); > return; > } > obj->name = eina_stringshare_add(name); > data->l_filters = eina_list_append(data->l_filters, obj); > } > > /* > * This function is called inside eio's thread, so dont use anything not > * thread-safe inside! > */ > Eina_Bool > _list_cb_filter(void *data, Eio_File *handler, const Eina_File_Direct_Info *file) > { > char *last_slash; > struct _Data *obj = data; > struct _Filter *filter; > Eina_List *l; > > last_slash = strrchr(file->path, '/'); > > eina_lock_take(&obj->mutex); > obj->count_total++; > > if (file->type==EINA_FILE_DIR) > { > eina_lock_release(&obj->mutex); > return EINA_TRUE; > } > > EINA_LIST_FOREACH(obj->l_filters, l, filter) > { > if (!regexec(&(filter->preg), last_slash + 1, 0, 0, 0)) > { > eio_file_associate_add(handler, file->path, filter, _free_cb); Like I said, you don't need _free_cb, pass NULL here. > eina_lock_release(&obj->mutex); > return EINA_TRUE; > } > } > > obj->count_filtered++; > eina_lock_release(&obj->mutex); > return EINA_FALSE; > } > > void > _list_cb_done(void *data, Eio_File *handler) > { > struct _Data *obj = data; > > eina_lock_take(&obj->mutex); > if (!--obj->jobs) > ecore_main_loop_quit(); > eina_lock_release(&obj->mutex); > } > > void > _list_cb_error(void *data, Eio_File *handler, int error) > { > fprintf(stderr, "An error occured : %s\n", strerror(error)); > } > > void > _list_cb(void *data, Eio_File *handler, const Eina_File_Direct_Info *file) > { > struct _Data *obj = data; > struct _Filter *filter; > > eina_lock_take(&obj->mutex); > > if (file->type==EINA_FILE_DIR) > { > obj->jobs++; > eio_file_stat_ls(file->path, > _list_cb_filter, > _list_cb, > _list_cb_done, > _list_cb_error, > data); > eina_lock_release(&obj->mutex); > return; > } > obj->count_passed++; > > filter = eio_file_associate_find(handler, file->path); > printf("File %s matched %s\n", file->path, filter->name); > eina_lock_release(&obj->mutex); > } > > int main(int argc, char **argv) > { > struct _Data *data; > struct _Filter *filter; > > if (argc != 2) > { > fprintf(stderr, "Usage ./eio_file_stat_ls testdir\n"); > return 1; > } > > if (!eina_init()) > return 1; > if (!ecore_init()) > return 1; > if (!eio_init()) > return 1; > I'm not sure if the sequence here matter too much but I would register ecore first. And, just returning is not enough, you should shutdown what succeed before. In the sequence we have here, if eina_init has succeed and ecore_init has failed eina still needs to be finished. Labels down in the end of your main to handle this scenarios would fit very well. :-) > data = calloc(1, sizeof(struct _Data)); > data->jobs = 1; > eina_lock_new(&data->mutex); > eina_lock_debug(&data->mutex); > > > _filter_add(data, "^[0-9]+$"); > _filter_add(data, "^back.*"); > > > eio_file_stat_ls(argv[1], > _list_cb_filter, > _list_cb, > _list_cb_done, > _list_cb_error, > data); > > ecore_main_loop_begin(); > > printf("Stats :\tTotal = %d\tFiltered = %d\tPassed = %d\n", > data->count_total, data->count_filtered, data->count_passed); > > EINA_LIST_FREE(data->l_filters, filter) > { > eina_stringshare_del(filter->name); > regfree(&filter->preg); > free(filter); > } > > eina_lock_free(&data->mutex); > free(data); > eio_shutdown(); > ecore_shutdown(); > eina_shutdown(); > return 0; > } Thank you.... -- Leandro Dorileo ProFUSION embedded systems http://profusion.mobi |