From f45618d15b00cf3619fd22df4459bb700cc25f70 Mon Sep 17 00:00:00 2001 From: Boris Faure Date: Mon, 25 Nov 2013 23:33:51 +0100 Subject: fix eina_cow issues. Closes T581, T527 --- src/lib/eina/eina_cow.c | 57 ++++++++++++++++++++++++------------------------- src/lib/eina/eina_cow.h | 18 ++++++++-------- 2 files changed, 37 insertions(+), 38 deletions(-) diff --git a/src/lib/eina/eina_cow.c b/src/lib/eina/eina_cow.c index ca99f5c596..2b1a3e502f 100644 --- a/src/lib/eina/eina_cow.c +++ b/src/lib/eina/eina_cow.c @@ -80,7 +80,6 @@ struct _Eina_Cow_GC Eina_Cow_Ptr *ref; const void **dst; }; - struct _Eina_Cow { #ifdef EINA_COW_MAGIC_ON @@ -91,7 +90,7 @@ struct _Eina_Cow Eina_Hash *match; Eina_Mempool *pool; - const void *default_value; + const Eina_Cow_Data *default_value; unsigned int struct_size; unsigned int total_size; @@ -123,7 +122,7 @@ typedef int (*Eina_Cow_Hash)(const void *, int); (((Eina_Cow_Ptr *)d) - 1) #define EINA_COW_DATA_GET(d) \ - ((unsigned char *)(d + 1)) + (((Eina_Cow_Ptr *)d) + 1) static int _eina_cow_log_dom = -1; @@ -142,8 +141,9 @@ static int _eina_cow_log_dom = -1; #endif #define DBG(...) EINA_LOG_DOM_DBG(_eina_cow_log_dom, __VA_ARGS__) + static Eina_Mempool *gc_pool = NULL; - + static inline int _eina_cow_hash_gen(const void *key, int key_length, Eina_Cow_Hash hash, @@ -184,7 +184,7 @@ static int current_cow_size = 0; static unsigned int _eina_cow_length(const void *key EINA_UNUSED) { - /* nasty hack, has only gc need to access the hash, he will be in charge + /* nasty hack, since only gc needs to access the hash, it will be in charge of that global. access to the hash should be considered global. */ return current_cow_size; @@ -254,26 +254,25 @@ _eina_cow_togc_add(Eina_Cow *cow, } static void -_eina_cow_gc(Eina_Cow *cow, Eina_Cow_Ptr *ref, - const Eina_Cow_Data **dst, - void *data) +_eina_cow_gc(Eina_Cow *cow, Eina_Cow_GC *gc) { - void *match; + Eina_Cow_Data *data; + Eina_Cow_Data *match; - ref->togc = EINA_FALSE; + data = EINA_COW_DATA_GET(gc->ref); current_cow_size = cow->struct_size; match = eina_hash_find(cow->match, data); if (match) { - ref = EINA_COW_PTR_GET(match); + Eina_Cow_Ptr *ref = EINA_COW_PTR_GET(match); #ifndef NVALGRIND VALGRIND_MAKE_MEM_DEFINED(ref, sizeof (*ref)); #endif - ref->refcount++; + ref->refcount += gc->ref->refcount; - eina_cow_free(cow, dst); - *dst = match; + *gc->dst = match; + eina_cow_free(cow, (const Eina_Cow_Data**) &data); #ifndef NVALGRIND VALGRIND_MAKE_MEM_NOACCESS(ref, sizeof (*ref)); @@ -282,7 +281,9 @@ _eina_cow_gc(Eina_Cow *cow, Eina_Cow_Ptr *ref, else { eina_hash_direct_add(cow->match, data, data); - ref->hashed = EINA_TRUE; + gc->ref->hashed = EINA_TRUE; + gc->ref->togc = EINA_FALSE; + eina_hash_del(cow->togc, &gc->ref, gc); } } @@ -366,7 +367,7 @@ eina_cow_add(const char *name, unsigned int struct_size, unsigned int step, cons _eina_cow_cmp, _eina_cow_hash32, NULL, - 6); + 6); #endif if (gc) cow->togc = eina_hash_pointer_new(_eina_cow_gc_free); @@ -453,7 +454,7 @@ eina_cow_write(Eina_Cow *cow, const Eina_Cow_Data * const *data) { Eina_Cow_Ptr *ref; - void *r; + Eina_Cow_Data *r; #ifdef EINA_COW_MAGIC_ON EINA_COW_MAGIC_CHECK(cow); @@ -484,8 +485,8 @@ eina_cow_write(Eina_Cow *cow, } #endif - if (cow->togc) - _eina_cow_hash_del(cow, *data, ref); + if (cow->togc) + _eina_cow_hash_del(cow, *data, ref); #ifndef NVALGRIND VALGRIND_MAKE_MEM_NOACCESS(ref, sizeof (*ref)); @@ -509,7 +510,7 @@ eina_cow_write(Eina_Cow *cow, r = EINA_COW_DATA_GET(ref); memcpy(r, *data, cow->struct_size); - *((void**) data) = r; + *((Eina_Cow_Data**) data) = r; end: #ifndef NVALGRIND @@ -602,8 +603,8 @@ eina_cow_gc(Eina_Cow *cow) { Eina_Cow_GC *gc; Eina_Iterator *it; - void *data; Eina_Bool r; + Eina_Cow_Ptr *ref; EINA_COW_MAGIC_CHECK(cow); @@ -613,22 +614,20 @@ eina_cow_gc(Eina_Cow *cow) it = eina_hash_iterator_data_new(cow->togc); r = eina_iterator_next(it, (void**) &gc); eina_iterator_free(it); - + if (!r) return EINA_FALSE; /* Something did go wrong here */ - /* Do handle hash and all funky merge think here */ - data = EINA_COW_DATA_GET(gc->ref); + /* Do handle hash and all funky merge thing here */ + ref = gc->ref; #ifndef NVALGRIND - VALGRIND_MAKE_MEM_DEFINED(gc->ref, sizeof (Eina_Cow_Ptr)); + VALGRIND_MAKE_MEM_DEFINED(ref, sizeof (*ref)); #endif - _eina_cow_gc(cow, gc->ref, gc->dst, data); + _eina_cow_gc(cow, gc); #ifndef NVALGRIND - VALGRIND_MAKE_MEM_NOACCESS(gc->ref, sizeof (Eina_Cow_Ptr)); + VALGRIND_MAKE_MEM_NOACCESS(ref, sizeof (*ref)); #endif - eina_hash_del(cow->togc, &gc->ref, gc); - return EINA_TRUE; } diff --git a/src/lib/eina/eina_cow.h b/src/lib/eina/eina_cow.h index 10cb34d28d..bbbcf4b677 100644 --- a/src/lib/eina/eina_cow.h +++ b/src/lib/eina/eina_cow.h @@ -56,9 +56,9 @@ typedef void Eina_Cow_Data; * * @param name The name of this pool, used for debug. * @param struct_size The size of the object from this pool. - * @param step How many object to allocate when the pool get empty. + * @param step How many objects to allocate when the pool gets empty. * @param default_value The default value returned by this pool. - * @param gc Is it possible to run the garbage collection on this pool. + * @param gc Is it possible to run garbage collection on this pool. * @return a valid new Eina_Cow or @c NULL on error. */ EAPI Eina_Cow *eina_cow_add(const char *name, unsigned int struct_size, unsigned int step, const void *default_value, Eina_Bool gc) EINA_WARN_UNUSED_RESULT; @@ -71,7 +71,7 @@ EAPI Eina_Cow *eina_cow_add(const char *name, unsigned int struct_size, unsigned EAPI void eina_cow_del(Eina_Cow *cow); /** - * @brief Return a initialized pointer to the pool. + * @brief Return an initialized pointer from the pool. * @param cow The pool to take things from. */ EAPI const Eina_Cow_Data *eina_cow_alloc(Eina_Cow *cow) EINA_WARN_UNUSED_RESULT; @@ -98,8 +98,8 @@ EAPI void *eina_cow_write(Eina_Cow *cow, /** * @brief Set back a pointer into read only. * @param cow The pool the pointer come from. - * @param src The read only version of the pointer. - * @param data The pointer to which data where written to. + * @param dst The read only version of the pointer. + * @param data The pointer to which data was written to. * * NOTE: this function is not thread safe, be careful. */ @@ -118,13 +118,13 @@ EAPI void eina_cow_memcpy(Eina_Cow *cow, const Eina_Cow_Data *src); /** - * @brief Try to find entry that do have the same content and update them. + * @brief Try to find entries that have the same content and update them. * @param cow The cow to try to compact. * @return EINA_TRUE if something was compacted, EINA_FALSE if nothing was. * * There is no guaranty in the time it will require, but should remain low. - * It does run a hash function on all possible common structure trying to - * find the one that match and merge then into one pointer. + * It does run a hash function on all possible common structures trying to + * find the one that match and merge them into one pointer. */ EAPI Eina_Bool eina_cow_gc(Eina_Cow *cow); @@ -137,7 +137,7 @@ EAPI Eina_Bool eina_cow_gc(Eina_Cow *cow); * @param Write The name of the variable where to put the writeable pointer to. * @since 1.8.0 * - * Be careful this macro open a C scope that it expect to be closed by + * Be careful this macro opens a C scope that is expected to be closed by * EINA_COW_WRITE_END(). */ #define EINA_COW_WRITE_BEGIN(Cow, Read, Write_Type, Write) \ -- cgit v1.2.1