return r;
}
-Evas *
+EAPI Evas *
ethumb_evas_get(const Ethumb *e)
{
EINA_SAFETY_ON_NULL_RETURN_VAL(e, NULL);
return e->sub_e;
}
-Ecore_Evas *
+EAPI Ecore_Evas *
ethumb_ecore_evas_get(const Ethumb *e)
{
EINA_SAFETY_ON_NULL_RETURN_VAL(e, NULL);
return e->sub_ee;
}
-Ethumb *
+EAPI Ethumb *
ethumb_dup(const Ethumb *e)
{
Ecore_Evas *ee;
if (e1->Param != e2->Param) \
return EINA_TRUE;
-Eina_Bool
+EAPI Eina_Bool
ethumb_cmp(const Ethumb *e1, const Ethumb *e2)
{
CHECK_DELTA(thumb_dir);
return EINA_FALSE;
}
+
+EAPI unsigned int
+ethumb_length(__UNUSED__ const void *key)
+{
+ return sizeof (Ethumb);
+}
+
+#define CMP_PARAM(Param) \
+ if (e1->Param != e2->Param) \
+ return e1->Param - e2->Param;
+
+EAPI int
+ethumb_key_cmp(const void *key1, __UNUSED__ int key1_length,
+ const void *key2, __UNUSED__ int key2_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);
+ CMP_PARAM(th);
+ CMP_PARAM(format);
+ CMP_PARAM(aspect);
+ CMP_PARAM(orientation);
+ CMP_PARAM(crop_x);
+ CMP_PARAM(crop_y);
+ CMP_PARAM(quality);
+ CMP_PARAM(compress);
+ CMP_PARAM(rw);
+ CMP_PARAM(rh);
+ CMP_PARAM(video.start);
+ CMP_PARAM(video.time);
+ CMP_PARAM(video.interval);
+ CMP_PARAM(video.ntimes);
+ CMP_PARAM(video.fps);
+ CMP_PARAM(document.page);
+ CMP_PARAM(src_path);
+ CMP_PARAM(src_key);
+
+ return 0;
+}
+
+#undef CMP_PARAM
+
+#define HASH_PARAM_I(Param) r ^= eina_hash_int32((unsigned int*) &e->Param, 0);
+#ifdef __LP64__
+# define HASH_PARAM_P(Param) r ^= eina_hash_int64((unsigned long int*) &e->Param, 0);
+#else
+# define HASH_PARAM_P(Param) r ^= eina_hash_int32((unsigned int*) &e->Param, 0);
+#endif
+#define HASH_PARAM_D(Param) r ^= eina_hash_int64((unsigned long int*)&e->Param, 0);
+#define HASH_PARAM_F(Param) r ^= eina_hash_int32((unsigned int*) &e->Param, 0);
+
+EAPI int
+ethumb_hash(const void *key, int key_length)
+{
+ const Ethumb *e = key;
+ int r = 0;
+
+ HASH_PARAM_P(thumb_dir);
+ HASH_PARAM_P(category);
+ HASH_PARAM_I(tw);
+ HASH_PARAM_I(th);
+ HASH_PARAM_I(format);
+ HASH_PARAM_I(aspect);
+ HASH_PARAM_I(orientation);
+ HASH_PARAM_F(crop_x);
+ HASH_PARAM_F(crop_y);
+ HASH_PARAM_I(quality);
+ HASH_PARAM_I(compress);
+ HASH_PARAM_P(src_path);
+ HASH_PARAM_P(src_key);
+ HASH_PARAM_I(rw);
+ HASH_PARAM_I(rh);
+ HASH_PARAM_D(video.start);
+ HASH_PARAM_D(video.time);
+ HASH_PARAM_D(video.interval);
+ HASH_PARAM_I(video.ntimes);
+ HASH_PARAM_I(video.fps);
+ HASH_PARAM_I(document.page);
+
+ return r;
+}
};
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;
- Ethumb_Client_Thumb_Exists_Cb exists_cb;
- const void *data;
+ Eina_List *callbacks;
Ecore_Thread *thread;
int refcount;
Eina_Bool exists : 1;
};
+struct _Ethumb_Async_Exists_Cb
+{
+ Ethumb_Client_Thumb_Exists_Cb exists_cb;
+ const void *data;
+};
+
static const char _ethumb_dbus_bus_name[] = "org.enlightenment.Ethumb";
static const char _ethumb_dbus_interface[] = "org.enlightenment.Ethumb";
static const char _ethumb_dbus_objects_interface[] = "org.enlightenment.Ethumb.objects";
static const char fdo_path[] = "/org/freedesktop/DBus";
static int _initcount = 0;
+static Eina_Hash *_exists_request = NULL;
static void _ethumb_client_generated_cb(void *data, DBusMessage *msg);
static void _ethumb_client_get_name_owner(void *data, DBusMessage *msg, DBusError *err);
while (0)
static void
+_ethumb_async_delete(void *data)
+{
+ Ethumb_Async_Exists *async = data;
+
+ ethumb_free(async->dup);
+ async->source->refcount--;
+
+ if (async->source->delete_me == EINA_TRUE)
+ ethumb_client_disconnect(async->source);
+
+ free(async);
+}
+
+static void
_ethumb_client_name_owner_changed(void *data, DBusMessage *msg)
{
DBusError err;
_ethumb_client_exists_end(void *data, Ecore_Thread *thread)
{
Ethumb_Async_Exists *async = data;
+ Ethumb_Async_Exists_Cb *cb;
Ethumb *tmp = async->source->ethumb;
async->source->ethumb = async->dup;
async->source->ethumb_dirty = ethumb_cmp(tmp, async->dup);
- async->exists_cb(async->source, (Ethumb_Exists*) async, async->exists, (void*) async->data);
- async->source->ethumb = tmp;
- ethumb_free(async->dup);
- async->source->refcount--;
+ EINA_LIST_FREE(async->callbacks, cb)
+ cb->exists_cb(async->source, (Ethumb_Exists*) async, async->exists, (void*) cb->data);
- if (async->source->delete_me == EINA_TRUE)
- ethumb_client_disconnect(async->source);
+ async->source->ethumb = tmp;
+ async->thread = NULL;
- free(async);
+ eina_hash_del(_exists_request, async->dup, async);
}
static void
_ethumb_client_exists_cancel(void *data, Ecore_Thread *thread)
{
+ Ethumb_Async_Exists_Cb *cb;
Ethumb_Async_Exists *async = data;
Ethumb *tmp = async->source->ethumb;
async->source->ethumb = async->dup;
async->source->ethumb_dirty = ethumb_cmp(tmp, async->dup);
- async->exists_cb(async->source, (Ethumb_Exists*) async, EINA_FALSE, (void*) async->data);
- async->source->ethumb = tmp;
- ethumb_free(async->dup);
- async->source->refcount--;
+ EINA_LIST_FREE(async->callbacks, cb)
+ cb->exists_cb(async->source, (Ethumb_Exists*) async, EINA_FALSE, (void*) cb->data);
- if (async->source->delete_me == EINA_TRUE)
- ethumb_client_disconnect(async->source);
+ async->source->ethumb = tmp;
+ async->thread = NULL;
- free(async);
+ eina_hash_del(_exists_request, async->dup, async);
}
/**
ethumb_init();
e_dbus_init();
+ _exists_request = eina_hash_new(ethumb_length,
+ ethumb_key_cmp,
+ ethumb_hash,
+ _ethumb_async_delete,
+ 3);
+
return ++_initcount;
}
if (_initcount > 0)
return _initcount;
+ /* should find a non racy solution to closing all pending exists request */
+
e_dbus_shutdown();
ethumb_shutdown();
eina_log_domain_unregister(_log_dom);
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;
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;
+ }
+
+ cb->exists_cb = exists_cb;
+ cb->data = data;
+
+ async = eina_hash_find(_exists_request, client->ethumb);
+ if (async)
+ {
+ async->refcount++;
+ async->callbacks = eina_list_append(async->callbacks, cb);
+ return (Ethumb_Exists*) async;
+ }
+
async = malloc(sizeof (Ethumb_Async_Exists));
if (!async)
{
+ free(cb);
exists_cb(client, NULL, EINA_FALSE, (void*) data);
return NULL;
}
async->dup = ethumb_dup(client->ethumb);
async->source = client;
async->source->refcount++;
- async->exists_cb = exists_cb;
- async->data = data;
async->exists = EINA_FALSE;
+ async->callbacks = eina_list_append(NULL, cb);
+
async->refcount = 1;
async->thread = ecore_thread_run(_ethumb_client_exists_heavy,
_ethumb_client_exists_end,
_ethumb_client_exists_cancel,
async);
+ eina_hash_direct_add(_exists_request, async->dup, async);
+
return (Ethumb_Exists*) async;
}