From 6d7b331448d5cb9753dd711d2eb94aec6246cc61 Mon Sep 17 00:00:00 2001 From: Lauro Moura Date: Tue, 12 Apr 2016 16:00:23 -0300 Subject: [PATCH] eio: Adds Eo-based Eio API The legacy Eio_File factory functions are replaced by an Eo object called Eo_Job that return promises wrapping the async file operations. With this commit, the legacy Eio callbacks are replaced by the following Eo/Promises counterparts : * Done_Cb -> Promise then success callback * Error_Cb -> Promise then error callback * Main_Cb -> Promise progress callback * Filter_Cb -> Job object event (more below) Events are used to deliver and get the filter data. To differentiate between the named and direct versions, they come in "filter,direct" and "filter,name" versions. Monitors were wrapped inside a new class Eo_Sentry. The user creates a sentry object and adds monitoring targets to it, listening to events on it. The sentry event info is composed of two strings. The source string is the path being monitored, i.e. the one passed to eio_sentry_add, and the trigger string is the path that actually triggered the event, e.g. a new file created in a monitored directory. --- eio/Makefile.am | 54 ++++++++++++++------ eio/eio_job_ls.c | 79 +++++++++++++++++++++++++++++ eio/eio_job_open.c | 80 +++++++++++++++++++++++++++++ eio/eio_job_open_multi.c | 103 ++++++++++++++++++++++++++++++++++++++ unsorted/eio/eio_sentry.c | 55 ++++++++++++++++++++ 5 files changed, 355 insertions(+), 16 deletions(-) create mode 100644 eio/eio_job_ls.c create mode 100644 eio/eio_job_open.c create mode 100644 eio/eio_job_open_multi.c create mode 100644 unsorted/eio/eio_sentry.c diff --git a/eio/Makefile.am b/eio/Makefile.am index 53b95fec..4fccc703 100644 --- a/eio/Makefile.am +++ b/eio/Makefile.am @@ -24,31 +24,53 @@ endif EXTRA_PROGRAMS = \ eio_file_ls \ -eio_file_copy +eio_file_copy \ +eio_job_open \ +eio_job_open_multi \ +eio_job_ls \ +eio_sentry + +EIO_EXAMPLES_LDADD = \ +$(top_builddir)/src/lib/eio/libeio.la \ +$(top_builddir)/src/lib/eo/libeo.la \ +$(top_builddir)/src/lib/ecore/libecore.la \ +$(top_builddir)/src/lib/efl/libefl.la \ +$(top_builddir)/src/lib/eet/libeet.la \ +$(top_builddir)/src/lib/emile/libemile.la \ +$(top_builddir)/src/lib/eina/libeina.la \ +@EIO_LDFLAGS@ eio_file_ls_SOURCES = eio_file_ls.c eio_file_ls_LDADD = \ -$(top_builddir)/src/lib/eio/libeio.la \ -$(top_builddir)/src/lib/eo/libeo.la \ -$(top_builddir)/src/lib/ecore/libecore.la \ -$(top_builddir)/src/lib/eet/libeet.la \ -$(top_builddir)/src/lib/emile/libemile.la \ -$(top_builddir)/src/lib/eina/libeina.la \ -@EIO_LDFLAGS@ +$(EIO_EXAMPLES_LDADD) eio_file_copy_SOURCES = eio_file_copy.c eio_file_copy_LDADD = \ -$(top_builddir)/src/lib/eio/libeio.la \ -$(top_builddir)/src/lib/eo/libeo.la \ -$(top_builddir)/src/lib/ecore/libecore.la \ -$(top_builddir)/src/lib/eet/libeet.la \ -$(top_builddir)/src/lib/emile/libemile.la \ -$(top_builddir)/src/lib/eina/libeina.la \ -@EIO_LDFLAGS@ +$(EIO_EXAMPLES_LDADD) + +eio_job_open_SOURCES = eio_job_open.c +eio_job_open_LDADD = \ +$(EIO_EXAMPLES_LDADD) + +eio_job_open_multi_SOURCES = eio_job_open_multi.c +eio_job_open_multi_LDADD = \ +$(EIO_EXAMPLES_LDADD) + +eio_job_ls_SOURCES = eio_job_ls.c +eio_job_ls_LDADD = \ +$(EIO_EXAMPLES_LDADD) + +eio_sentry_SOURCES = eio_sentry.c +eio_sentry_LDADD = \ +$(EIO_EXAMPLES_LDADD) SRCS = \ eio_file_ls.c \ -eio_file_copy.c +eio_file_copy.c \ +eio_job_open.c \ +eio_job_open_multi.c \ +eio_job_ls.c \ +eio_sentry.c DATA_FILES = Makefile.examples diff --git a/eio/eio_job_ls.c b/eio/eio_job_ls.c new file mode 100644 index 00000000..354325e4 --- /dev/null +++ b/eio/eio_job_ls.c @@ -0,0 +1,79 @@ +#if HAVE_CONFIG_H +#include +#endif + + +#include +#include + +#include +#include +#include + +void done_cb(void *data, void *value EINA_UNUSED) +{ + Eio_Job *job = data; + printf("%s done listing files.\n", __FUNCTION__); + ecore_main_loop_quit(); + eo_unref(job); +} + +void error_cb(void *data, Eina_Error *error) +{ + Eio_Job *job = data; + EINA_SAFETY_ON_NULL_RETURN(error); + const char *msg = eina_error_msg_get(*error); + printf("%s error: %s\n", __FUNCTION__, msg); + ecore_main_loop_quit(); + + eo_unref(job); +} + +void filter_cb(void *data, const Eo_Event *event) +{ + Eio_Filter_Name_Data *event_info = event->info; + static Eina_Bool should_filter = EINA_FALSE; + + printf("Filtering file %s\n", event_info->file); + + should_filter = !should_filter; + event_info->filter = should_filter; +} + +// Progress used to be the "Eio_Main_Cb" family of callbacks in the legacy API. +void progress_cb(void *data, const char *filename) +{ + EINA_SAFETY_ON_NULL_RETURN(filename); + printf("%s listing filename: %s\n", __FUNCTION__, filename); +} + +void list_files(void *data) +{ + Eina_Promise *promise; + const char *path = data; + + Eio_Job *job = eo_add(EIO_JOB_CLASS, NULL); + eo_event_callback_add(job, EIO_JOB_EVENT_FILTER_NAME, (Eo_Event_Cb)&filter_cb, NULL); + eio_job_file_ls(job, path, &promise); + eina_promise_progress_cb_add(promise, (Eina_Promise_Progress_Cb)&progress_cb, NULL, NULL); + eina_promise_then(promise, (Eina_Promise_Cb)&done_cb, (Eina_Promise_Error_Cb)&error_cb, job); +} + +int main(int argc, char const *argv[]) +{ + eio_init(); + ecore_init(); + + const char *path = getenv("HOME"); + + if (argc > 1) + path = argv[1]; + + Ecore_Job *job = ecore_job_add(&list_files, path); + + ecore_main_loop_begin(); + + ecore_shutdown(); + eio_shutdown(); + return 0; +} diff --git a/eio/eio_job_open.c b/eio/eio_job_open.c new file mode 100644 index 00000000..fb235c2e --- /dev/null +++ b/eio/eio_job_open.c @@ -0,0 +1,80 @@ +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include + +#include +#include +#include + +void error_cb(void *data, Eina_Error *error) +{ + EINA_SAFETY_ON_NULL_RETURN(error); + EINA_SAFETY_ON_NULL_RETURN(data); + + const char *msg = eina_error_msg_get(*error); + EINA_LOG_ERR("error: %s", msg); + + ecore_main_loop_quit(); +} + +void done_closing_cb(int *result EINA_UNUSED) +{ + printf("%s closed file.\n", __FUNCTION__); + + ecore_main_loop_quit(); +} + +void closing_job(Eio_Job *job, Eina_File *file) +{ + Eina_Promise *promise = NULL; + printf("%s Will close the file...\n", __FUNCTION__); + eio_job_file_close(job, file, &promise); + eina_promise_then(promise, (Eina_Promise_Cb)&done_closing_cb, (Eina_Promise_Error_Cb)&error_cb, job); +} + +void done_open_cb(void *data, Eina_File **file) +{ + EINA_SAFETY_ON_NULL_RETURN(data); + EINA_SAFETY_ON_NULL_RETURN(file); + EINA_SAFETY_ON_NULL_RETURN(*file); + + Eio_Job *job = data; + + const char *name = eina_file_filename_get(*file); + printf("%s opened file %s\n", __FUNCTION__, name); + + closing_job(job, *file); +} + +void open_file(const char *path) +{ + Eina_Promise *promise; + + Eio_Job *job = eo_add(EIO_JOB_CLASS, NULL); + eio_job_file_open(job, path, EINA_FALSE, &promise); + eina_promise_then(promise, (Eina_Promise_Cb)&done_open_cb, (Eina_Promise_Error_Cb)&error_cb, job); + + eo_unref(job); +} + +int main(int argc, char const *argv[]) +{ + eio_init(); + ecore_init(); + + const char *path = getenv("HOME"); + + if (argc > 1) + path = argv[1]; + + open_file(path); + + ecore_main_loop_begin(); + + ecore_shutdown(); + eio_shutdown(); + return 0; +} diff --git a/eio/eio_job_open_multi.c b/eio/eio_job_open_multi.c new file mode 100644 index 00000000..8082d4bf --- /dev/null +++ b/eio/eio_job_open_multi.c @@ -0,0 +1,103 @@ +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include + +#include +#include +#include + +void error_cb(void *data, Eina_Error *error) +{ + EINA_SAFETY_ON_NULL_RETURN(error); + EINA_SAFETY_ON_NULL_RETURN(data); + + const char *msg = eina_error_msg_get(*error); + EINA_LOG_ERR("error: %s", msg); + + Eio_Job *job = data; + eo_unref(job); + + ecore_main_loop_quit(); +} + +void done_closing_cb(void *data, Eina_Iterator **result EINA_UNUSED) +{ + EINA_SAFETY_ON_NULL_RETURN(data); + + printf("%s closed file.\n", __FUNCTION__); + + Eio_Job *job = data; + eo_unref(job); + + ecore_main_loop_quit(); +} + +void closing_job(Eio_Job *job, Eina_File *file1, Eina_File *file2) +{ + Eina_Promise *promise; + Eina_Promise *tasks[3] = {NULL, NULL, NULL}; + + printf("%s Closing files.\n", __FUNCTION__); + eio_job_file_close(job, file1, &tasks[0]); + eio_job_file_close(job, file2, &tasks[1]); + promise = eina_promise_all(eina_carray_iterator_new((void**)&tasks[0])); + eina_promise_then(promise, (Eina_Promise_Cb)&done_closing_cb, (Eina_Promise_Error_Cb)&error_cb, job); +} + +void done_open_cb(void *data, Eina_Iterator **iterator) +{ + EINA_SAFETY_ON_NULL_RETURN(data); + EINA_SAFETY_ON_NULL_RETURN(iterator); + EINA_SAFETY_ON_NULL_RETURN(*iterator); + Eio_Job *job = data; + + Eina_File **file = NULL; + Eina_File **files = calloc(sizeof(Eina_File*),2); + int i = 0; + while (eina_iterator_next(*iterator, (void**)&file)) + { + files[i] = *file; + const char *name = eina_file_filename_get(*file); + printf("%s opened file %s\n", __FUNCTION__, name); + i++; + } + closing_job(job, files[0], files[1]); + free(files); +} + +void open_file(const char *path, const char *path2) +{ + Eina_Promise *promise; + Eina_Promise *tasks[3] = {NULL, NULL, NULL}; + + Eio_Job *job = eo_add(EIO_JOB_CLASS, NULL); + eio_job_file_open(job, path, EINA_FALSE, &tasks[0]); + eio_job_file_open(job, path2, EINA_FALSE, &tasks[1]); + promise = eina_promise_all(eina_carray_iterator_new((void**)&tasks[0])); + eina_promise_then(promise, (Eina_Promise_Cb)&done_open_cb, (Eina_Promise_Error_Cb)&error_cb, job); +} + +int main(int argc, char const *argv[]) +{ + eio_init(); + ecore_init(); + + const char *path = getenv("HOME"); + const char *path2 = "./"; + + if (argc > 1) + path = argv[1]; + if (argc > 2) + path2 = argv[2]; + + open_file(path, path2); + + ecore_main_loop_begin(); + + ecore_shutdown(); + eio_shutdown(); + return 0; +} diff --git a/unsorted/eio/eio_sentry.c b/unsorted/eio/eio_sentry.c new file mode 100644 index 00000000..a6218a79 --- /dev/null +++ b/unsorted/eio/eio_sentry.c @@ -0,0 +1,55 @@ +#if HAVE_CONFIG_H +#include +#endif + + +#include +#include + +#include +#include +#include + +Eina_Bool +sentry_cb(void *data, const Eo_Event *event) +{ + Eio_Sentry_Event *event_info = event->info; + + printf("Event on monitored path %s", event_info->source); + printf("Created file %s\n", event_info->trigger); + + ecore_main_loop_quit(); + + return EINA_FALSE; +} + +void +monitor_stuff(void *data) +{ + const char *path = data; + Eio_Sentry *sentry = eo_add(EIO_SENTRY_CLASS, NULL); + eo_event_callback_add(sentry, EIO_SENTRY_EVENT_FILE_CREATED, (Eo_Event_Cb)&sentry_cb, NULL); + + printf("Starting monitoring path %s\n", path); + eio_sentry_add(sentry, path); +} + +int +main(int argc, char const *argv[]) +{ + eio_init(); + ecore_init(); + + const char *path = getenv("HOME"); + + if (argc > 1) + path = argv[1]; + + Ecore_Job *job = ecore_job_add(&monitor_stuff, path); + + ecore_main_loop_begin(); + + ecore_shutdown(); + eio_shutdown(); + return 0; +}