From 12285a5f4f124f3ff5fa73dd4460bd6b2c024df1 Mon Sep 17 00:00:00 2001 From: Cedric BAIL Date: Mon, 28 Nov 2011 23:24:32 +0000 Subject: [PATCH] ethumb: cleanup API. SVN revision: 65660 --- legacy/ethumb/src/lib/Ethumb.c | 47 ++++- legacy/ethumb/src/lib/Ethumb.h | 2 + legacy/ethumb/src/lib/client/Ethumb_Client.c | 192 ++++++++++--------- legacy/ethumb/src/lib/client/Ethumb_Client.h | 2 +- legacy/ethumb/src/lib/ethumb_private.h | 1 + 5 files changed, 148 insertions(+), 96 deletions(-) diff --git a/legacy/ethumb/src/lib/Ethumb.c b/legacy/ethumb/src/lib/Ethumb.c index c510fdce83..ecabe9cc02 100644 --- a/legacy/ethumb/src/lib/Ethumb.c +++ b/legacy/ethumb/src/lib/Ethumb.c @@ -787,6 +787,7 @@ ethumb_file_set(Ethumb *e, const char *path, const char *key) } path = _ethumb_build_absolute_path(path, buf); + eina_stringshare_replace(&e->src_hash, NULL); eina_stringshare_replace(&e->src_path, path); eina_stringshare_replace(&e->src_key, key); @@ -949,8 +950,6 @@ static void _ethumb_file_generate_path(Ethumb *e) { char buf[PATH_MAX]; - char *fullname; - const char *hash; const char *thumb_dir, *category; const char *ext; int fdo_format; @@ -987,10 +986,15 @@ _ethumb_file_generate_path(Ethumb *e) else ext = "eet"; - fullname = ecore_file_realpath(e->src_path); - hash = _ethumb_generate_hash(fullname); - snprintf(buf, sizeof(buf), "%s/%s/%s.%s", thumb_dir, category, hash, ext); - free(fullname); + if (!e->src_hash) + { + char *fullname; + + fullname = ecore_file_realpath(e->src_path); + e->src_hash = _ethumb_generate_hash(fullname); + free(fullname); + } + snprintf(buf, sizeof(buf), "%s/%s/%s.%s", thumb_dir, category, e->src_hash, ext); DBG("ethumb=%p, path=%s", e, buf); eina_stringshare_replace(&e->thumb_path, buf); if (e->format == ETHUMB_THUMB_EET) @@ -1003,7 +1007,6 @@ _ethumb_file_generate_path(Ethumb *e) eina_stringshare_del(thumb_dir); eina_stringshare_del(category); - eina_stringshare_del(hash); } EAPI void @@ -1012,6 +1015,7 @@ ethumb_file_free(Ethumb *e) EINA_SAFETY_ON_NULL_RETURN(e); DBG("ethumb=%p", e); + eina_stringshare_replace(&e->src_hash, NULL); eina_stringshare_replace(&e->src_path, NULL); eina_stringshare_replace(&e->src_key, NULL); eina_stringshare_replace(&e->thumb_path, NULL); @@ -1050,6 +1054,32 @@ ethumb_thumb_path_get(Ethumb *e, const char **path, const char **key) if (key) *key = e->thumb_key; } +EAPI void +ethumb_thumb_hash(Ethumb *e) +{ + EINA_SAFETY_ON_NULL_RETURN(e); + if (!e->src_hash) + { + char *fullname; + + fullname = ecore_file_realpath(e->src_path); + e->src_hash = _ethumb_generate_hash(fullname); + free(fullname); + } +} + +EAPI void +ethumb_thumb_hash_copy(Ethumb *dst, const Ethumb *src) +{ + EINA_SAFETY_ON_NULL_RETURN(dst); + EINA_SAFETY_ON_NULL_RETURN(src); + + if (src == dst) return ; + + eina_stringshare_del(dst->src_hash); + dst->src_hash = eina_stringshare_ref(src->src_hash); +} + void ethumb_calculate_aspect_from_ratio(Ethumb *e, float ia, int *w, int *h) { @@ -1602,6 +1632,7 @@ ethumb_dup(const Ethumb *e) r->thumb_dir = eina_stringshare_ref(e->thumb_dir); r->category = eina_stringshare_ref(e->category); + r->src_hash = eina_stringshare_ref(e->src_hash); r->src_path = eina_stringshare_ref(e->src_path); r->src_key = eina_stringshare_ref(e->src_key); r->thumb_path = eina_stringshare_ref(e->thumb_path); @@ -1708,8 +1739,6 @@ ethumb_key_cmp(const void *key1, __UNUSED__ int key1_length, const Ethumb *e1 = key1; const Ethumb *e2 = key2; - CMP_PARAM(thumb_dir); - CMP_PARAM(category); CMP_PARAM(thumb_dir); CMP_PARAM(category); CMP_PARAM(tw); diff --git a/legacy/ethumb/src/lib/Ethumb.h b/legacy/ethumb/src/lib/Ethumb.h index dc7b133545..96e7d0755a 100644 --- a/legacy/ethumb/src/lib/Ethumb.h +++ b/legacy/ethumb/src/lib/Ethumb.h @@ -98,6 +98,8 @@ EAPI const char *ethumb_thumb_category_get(const Ethumb *e) EINA_WARN_UNUSED_RE EAPI void ethumb_thumb_path_set(Ethumb *e, const char *path, const char *key) EINA_ARG_NONNULL(1); EAPI void ethumb_thumb_path_get(Ethumb *e, const char **path, const char **key) EINA_ARG_NONNULL(1); +EAPI void ethumb_thumb_hash(Ethumb *e) EINA_ARG_NONNULL(1); +EAPI void ethumb_thumb_hash_copy(Ethumb *dst, const Ethumb *src) EINA_ARG_NONNULL(1, 2); typedef enum _Ethumb_Thumb_FDO_Size { diff --git a/legacy/ethumb/src/lib/client/Ethumb_Client.c b/legacy/ethumb/src/lib/client/Ethumb_Client.c index a5c01c9397..b9d001cfe3 100644 --- a/legacy/ethumb/src/lib/client/Ethumb_Client.c +++ b/legacy/ethumb/src/lib/client/Ethumb_Client.c @@ -168,24 +168,23 @@ struct _ethumb_pending_gen }; typedef struct _Ethumb_Async_Exists Ethumb_Async_Exists; -typedef struct _Ethumb_Async_Exists_Cb Ethumb_Async_Exists_Cb; struct _Ethumb_Async_Exists { - Ethumb *dup; - Ethumb_Client *source; + const char *path; + + Ethumb *dup; /* We will work on that one to prevent race and lock */ Eina_List *callbacks; - Ecore_Thread *thread; - EINA_REFCOUNT; - - Eina_Bool exists : 1; - Eina_Bool cancel : 1; }; -struct _Ethumb_Async_Exists_Cb +struct _Ethumb_Exists { + Ethumb_Async_Exists *parent; + Ethumb_Client *client; + Ethumb *dup; /* We don't want to loose parameters so keep them around */ + Ethumb_Client_Thumb_Exists_Cb exists_cb; const void *data; }; @@ -347,21 +346,15 @@ _ethumb_async_delete(void *data) { Ethumb_Async_Exists *async = data; - ethumb_free(async->dup); + assert(async->callbacks == NULL); + assert(async->thread == NULL); - EINA_REFCOUNT_UNREF(async->source) - _ethumb_client_free(async->source); + ethumb_free(async->dup); + eina_stringshare_del(async->path); free(async); } -static void -_ethumb_async_cancel(Ethumb_Async_Exists *async) -{ - async->cancel = EINA_TRUE; - ecore_thread_cancel(async->thread); -} - static void _ethumb_client_name_owner_changed(void *data, DBusMessage *msg) { @@ -599,28 +592,37 @@ _ethumb_client_exists_heavy(void *data, Ecore_Thread *thread __UNUSED__) { Ethumb_Async_Exists *async = data; - async->exists = ethumb_exists(async->dup); + ethumb_thumb_hash(async->dup); } static void _ethumb_client_exists_end(void *data, Ecore_Thread *thread __UNUSED__) { Ethumb_Async_Exists *async = data; - Ethumb_Async_Exists_Cb *cb; - Ethumb *tmp = async->source->ethumb; - - async->source->ethumb = async->dup; + Ethumb_Exists *cb; EINA_LIST_FREE(async->callbacks, cb) { - cb->exists_cb(async->source, (Ethumb_Exists*) async, async->exists, (void*) cb->data); - free(cb); + Ethumb *tmp; + + ethumb_thumb_hash_copy(cb->dup, async->dup); + tmp = cb->client->ethumb; + cb->client->ethumb = cb->dup; + + cb->exists_cb(cb->client, cb, + ethumb_exists(cb->client->ethumb), + (void*) cb->data); + + cb->client->ethumb = tmp; + EINA_REFCOUNT_UNREF(cb->client) + _ethumb_client_free(cb->client); + ethumb_free(cb->dup); + free(cb); } - async->source->ethumb = tmp; async->thread = NULL; - eina_hash_del(_exists_request, async->dup, async); + eina_hash_del(_exists_request, async->path, async); } /** @@ -666,11 +668,7 @@ ethumb_client_init(void) ethumb_init(); e_dbus_init(); - _exists_request = eina_hash_new(ethumb_length, - ethumb_key_cmp, - ethumb_hash, - _ethumb_async_delete, - 3); + _exists_request = eina_hash_stringshared_new(_ethumb_async_delete); return ++_initcount; } @@ -699,6 +697,8 @@ ethumb_client_shutdown(void) return _initcount; /* should find a non racy solution to closing all pending exists request */ + eina_hash_free(_exists_request); + _exists_request = NULL; e_dbus_shutdown(); ethumb_shutdown(); @@ -2162,57 +2162,81 @@ ethumb_client_thumb_path_get(Ethumb_Client *client, const char **path, const cha EAPI Ethumb_Exists * ethumb_client_thumb_exists(Ethumb_Client *client, Ethumb_Client_Thumb_Exists_Cb exists_cb, const void *data) { - Ethumb_Async_Exists_Cb *cb; - Ethumb_Async_Exists *async; + const char *path = NULL; + Ethumb_Async_Exists *async = NULL; + Ethumb_Exists *cb = NULL; Ecore_Thread *t; EINA_SAFETY_ON_NULL_RETURN_VAL(client, NULL); - cb = malloc(sizeof (Ethumb_Async_Exists_Cb)); - if (!cb) - { - exists_cb(client, NULL, EINA_FALSE, (void*) data); - return NULL; - } + ethumb_file_get(client->ethumb, &path, NULL); + if (!path) goto on_error; - cb->exists_cb = exists_cb; - cb->data = data; - - async = eina_hash_find(_exists_request, client->ethumb); - if (async) - { - EINA_REFCOUNT_REF(async); - async->callbacks = eina_list_append(async->callbacks, cb); - return (Ethumb_Exists*) async; - } - - async = malloc(sizeof (Ethumb_Async_Exists)); + async = eina_hash_find(_exists_request, path); if (!async) { - free(cb); - exists_cb(client, NULL, EINA_FALSE, (void*) data); - return NULL; + async = malloc(sizeof (Ethumb_Async_Exists)); + if (!async) goto on_error; + + async->path = eina_stringshare_ref(path); + async->callbacks = NULL; + async->dup = ethumb_dup(client->ethumb); + + if (!async->dup) goto on_error; + + cb = malloc(sizeof (Ethumb_Exists)); + if (!cb) goto on_error; + + EINA_REFCOUNT_REF(client); + cb->client = client; + cb->dup = ethumb_dup(client->ethumb); + cb->exists_cb = exists_cb; + cb->data = data; + cb->parent = async; + + async->callbacks = eina_list_append(async->callbacks, cb); + + /* spawn a thread here */ + t = ecore_thread_run(_ethumb_client_exists_heavy, + _ethumb_client_exists_end, + _ethumb_client_exists_end, + async); + if (!t) return NULL; + async->thread = t; + + eina_hash_direct_add(_exists_request, async->path, async); + + return cb; } - async->dup = ethumb_dup(client->ethumb); - async->source = client; - EINA_REFCOUNT_REF(async->source); - async->exists = EINA_FALSE; - async->cancel = EINA_FALSE; + cb = malloc(sizeof (Ethumb_Exists)); + if (!cb) + { + async = NULL; + goto on_error; + } - async->callbacks = eina_list_append(NULL, cb); + EINA_REFCOUNT_REF(client); + cb->client = client; + cb->dup = ethumb_dup(client->ethumb); + cb->exists_cb = exists_cb; + cb->data = data; + cb->parent = async; - EINA_REFCOUNT_INIT(async); - t = ecore_thread_run(_ethumb_client_exists_heavy, - _ethumb_client_exists_end, - _ethumb_client_exists_end, - async); - if (!t) return NULL; + async->callbacks = eina_list_append(async->callbacks, cb); - async->thread = t; - eina_hash_direct_add(_exists_request, async->dup, async); + return cb; - return (Ethumb_Exists*) async; + on_error: + exists_cb(client, NULL, EINA_FALSE, (void*) data); + + if (async) + { + eina_stringshare_del(async->path); + if (async->dup) ethumb_free(async->dup); + free(async); + } + return NULL; } /** @@ -2221,22 +2245,18 @@ ethumb_client_thumb_exists(Ethumb_Client *client, Ethumb_Client_Thumb_Exists_Cb * @param exists the request to cancel. */ EAPI void -ethumb_client_thumb_exists_cancel(Ethumb_Exists *exists, Ethumb_Client_Thumb_Exists_Cb exists_cb, const void *data) +ethumb_client_thumb_exists_cancel(Ethumb_Exists *exists) { - Ethumb_Async_Exists_Cb *cb; - Ethumb_Async_Exists *async = (Ethumb_Async_Exists*) exists; - Eina_List *l; + Ethumb_Async_Exists *async = exists->parent; - EINA_LIST_FOREACH(async->callbacks, l, cb) - if (cb->exists_cb == exists_cb && cb->data == data) - { - async->callbacks = eina_list_remove_list(async->callbacks, l); - free(cb); - break; - } + async->callbacks = eina_list_remove(async->callbacks, exists); + if (eina_list_count(async->callbacks) <= 0) + ecore_thread_cancel(async->thread); - EINA_REFCOUNT_UNREF(async) - _ethumb_async_cancel(async); + ethumb_free(exists->dup); + EINA_REFCOUNT_UNREF(exists->client) + _ethumb_client_free(exists->client); + free(exists); } /** @@ -2248,11 +2268,11 @@ ethumb_client_thumb_exists_cancel(Ethumb_Exists *exists, Ethumb_Client_Thumb_Exi EAPI Eina_Bool ethumb_client_thumb_exists_check(Ethumb_Exists *exists) { - Ethumb_Async_Exists *async = (Ethumb_Async_Exists*) exists; + Ethumb_Async_Exists *async = exists->parent; if (!async) return EINA_TRUE; - if (async->callbacks || async->cancel) return EINA_FALSE; + if (async->callbacks) return EINA_FALSE; return ecore_thread_check(async->thread); } diff --git a/legacy/ethumb/src/lib/client/Ethumb_Client.h b/legacy/ethumb/src/lib/client/Ethumb_Client.h index 6087277738..e105693e0a 100644 --- a/legacy/ethumb/src/lib/client/Ethumb_Client.h +++ b/legacy/ethumb/src/lib/client/Ethumb_Client.h @@ -195,7 +195,7 @@ EAPI void ethumb_client_file_get(Ethumb_Client *client, const char **path, const EAPI void ethumb_client_file_free(Ethumb_Client *client); EAPI Ethumb_Exists *ethumb_client_thumb_exists(Ethumb_Client *client, Ethumb_Client_Thumb_Exists_Cb exists_cb, const void *data); -EAPI void ethumb_client_thumb_exists_cancel(Ethumb_Exists *exists, Ethumb_Client_Thumb_Exists_Cb exists_cb, const void *data); +EAPI void ethumb_client_thumb_exists_cancel(Ethumb_Exists *exists); EAPI Eina_Bool ethumb_client_thumb_exists_check(Ethumb_Exists *exists); EAPI int ethumb_client_generate(Ethumb_Client *client, Ethumb_Client_Generate_Cb generated_cb, const void *data, Eina_Free_Cb free_data); EAPI void ethumb_client_generate_cancel(Ethumb_Client *client, int id, Ethumb_Client_Generate_Cancel_Cb cancel_cb, const void *data, Eina_Free_Cb free_data); diff --git a/legacy/ethumb/src/lib/ethumb_private.h b/legacy/ethumb/src/lib/ethumb_private.h index 873b97991d..25f2cd354e 100644 --- a/legacy/ethumb/src/lib/ethumb_private.h +++ b/legacy/ethumb/src/lib/ethumb_private.h @@ -24,6 +24,7 @@ struct _Ethumb float crop_x, crop_y; int quality; int compress; + const char *src_hash; const char *src_path; const char *src_key; const char *thumb_path;