diff options
author | Boris Faure <billiob@gmail.com> | 2013-11-25 23:33:51 +0100 |
---|---|---|
committer | Boris Faure <billiob@gmail.com> | 2013-11-30 15:41:08 +0100 |
commit | f45618d15b00cf3619fd22df4459bb700cc25f70 (patch) | |
tree | de6a18eba4eee919cb506fe94de516f813172952 /src/lib/eina | |
parent | 1cad4c2afecd274d9fc5d913ba1137f2bee55230 (diff) |
fix eina_cow issues. Closes T581, T527
Diffstat (limited to 'src/lib/eina')
-rw-r--r-- | src/lib/eina/eina_cow.c | 57 | ||||
-rw-r--r-- | 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 | |||
80 | Eina_Cow_Ptr *ref; | 80 | Eina_Cow_Ptr *ref; |
81 | const void **dst; | 81 | const void **dst; |
82 | }; | 82 | }; |
83 | |||
84 | struct _Eina_Cow | 83 | struct _Eina_Cow |
85 | { | 84 | { |
86 | #ifdef EINA_COW_MAGIC_ON | 85 | #ifdef EINA_COW_MAGIC_ON |
@@ -91,7 +90,7 @@ struct _Eina_Cow | |||
91 | Eina_Hash *match; | 90 | Eina_Hash *match; |
92 | 91 | ||
93 | Eina_Mempool *pool; | 92 | Eina_Mempool *pool; |
94 | const void *default_value; | 93 | const Eina_Cow_Data *default_value; |
95 | 94 | ||
96 | unsigned int struct_size; | 95 | unsigned int struct_size; |
97 | unsigned int total_size; | 96 | unsigned int total_size; |
@@ -123,7 +122,7 @@ typedef int (*Eina_Cow_Hash)(const void *, int); | |||
123 | (((Eina_Cow_Ptr *)d) - 1) | 122 | (((Eina_Cow_Ptr *)d) - 1) |
124 | 123 | ||
125 | #define EINA_COW_DATA_GET(d) \ | 124 | #define EINA_COW_DATA_GET(d) \ |
126 | ((unsigned char *)(d + 1)) | 125 | (((Eina_Cow_Ptr *)d) + 1) |
127 | 126 | ||
128 | static int _eina_cow_log_dom = -1; | 127 | static int _eina_cow_log_dom = -1; |
129 | 128 | ||
@@ -142,8 +141,9 @@ static int _eina_cow_log_dom = -1; | |||
142 | #endif | 141 | #endif |
143 | #define DBG(...) EINA_LOG_DOM_DBG(_eina_cow_log_dom, __VA_ARGS__) | 142 | #define DBG(...) EINA_LOG_DOM_DBG(_eina_cow_log_dom, __VA_ARGS__) |
144 | 143 | ||
144 | |||
145 | static Eina_Mempool *gc_pool = NULL; | 145 | static Eina_Mempool *gc_pool = NULL; |
146 | 146 | ||
147 | static inline int | 147 | static inline int |
148 | _eina_cow_hash_gen(const void *key, int key_length, | 148 | _eina_cow_hash_gen(const void *key, int key_length, |
149 | Eina_Cow_Hash hash, | 149 | Eina_Cow_Hash hash, |
@@ -184,7 +184,7 @@ static int current_cow_size = 0; | |||
184 | static unsigned int | 184 | static unsigned int |
185 | _eina_cow_length(const void *key EINA_UNUSED) | 185 | _eina_cow_length(const void *key EINA_UNUSED) |
186 | { | 186 | { |
187 | /* nasty hack, has only gc need to access the hash, he will be in charge | 187 | /* nasty hack, since only gc needs to access the hash, it will be in charge |
188 | of that global. access to the hash should be considered global. | 188 | of that global. access to the hash should be considered global. |
189 | */ | 189 | */ |
190 | return current_cow_size; | 190 | return current_cow_size; |
@@ -254,26 +254,25 @@ _eina_cow_togc_add(Eina_Cow *cow, | |||
254 | } | 254 | } |
255 | 255 | ||
256 | static void | 256 | static void |
257 | _eina_cow_gc(Eina_Cow *cow, Eina_Cow_Ptr *ref, | 257 | _eina_cow_gc(Eina_Cow *cow, Eina_Cow_GC *gc) |
258 | const Eina_Cow_Data **dst, | ||
259 | void *data) | ||
260 | { | 258 | { |
261 | void *match; | 259 | Eina_Cow_Data *data; |
260 | Eina_Cow_Data *match; | ||
262 | 261 | ||
263 | ref->togc = EINA_FALSE; | 262 | data = EINA_COW_DATA_GET(gc->ref); |
264 | 263 | ||
265 | current_cow_size = cow->struct_size; | 264 | current_cow_size = cow->struct_size; |
266 | match = eina_hash_find(cow->match, data); | 265 | match = eina_hash_find(cow->match, data); |
267 | if (match) | 266 | if (match) |
268 | { | 267 | { |
269 | ref = EINA_COW_PTR_GET(match); | 268 | Eina_Cow_Ptr *ref = EINA_COW_PTR_GET(match); |
270 | #ifndef NVALGRIND | 269 | #ifndef NVALGRIND |
271 | VALGRIND_MAKE_MEM_DEFINED(ref, sizeof (*ref)); | 270 | VALGRIND_MAKE_MEM_DEFINED(ref, sizeof (*ref)); |
272 | #endif | 271 | #endif |
273 | ref->refcount++; | 272 | ref->refcount += gc->ref->refcount; |
274 | 273 | ||
275 | eina_cow_free(cow, dst); | 274 | *gc->dst = match; |
276 | *dst = match; | 275 | eina_cow_free(cow, (const Eina_Cow_Data**) &data); |
277 | 276 | ||
278 | #ifndef NVALGRIND | 277 | #ifndef NVALGRIND |
279 | VALGRIND_MAKE_MEM_NOACCESS(ref, sizeof (*ref)); | 278 | VALGRIND_MAKE_MEM_NOACCESS(ref, sizeof (*ref)); |
@@ -282,7 +281,9 @@ _eina_cow_gc(Eina_Cow *cow, Eina_Cow_Ptr *ref, | |||
282 | else | 281 | else |
283 | { | 282 | { |
284 | eina_hash_direct_add(cow->match, data, data); | 283 | eina_hash_direct_add(cow->match, data, data); |
285 | ref->hashed = EINA_TRUE; | 284 | gc->ref->hashed = EINA_TRUE; |
285 | gc->ref->togc = EINA_FALSE; | ||
286 | eina_hash_del(cow->togc, &gc->ref, gc); | ||
286 | } | 287 | } |
287 | } | 288 | } |
288 | 289 | ||
@@ -366,7 +367,7 @@ eina_cow_add(const char *name, unsigned int struct_size, unsigned int step, cons | |||
366 | _eina_cow_cmp, | 367 | _eina_cow_cmp, |
367 | _eina_cow_hash32, | 368 | _eina_cow_hash32, |
368 | NULL, | 369 | NULL, |
369 | 6); | 370 | 6); |
370 | #endif | 371 | #endif |
371 | if (gc) | 372 | if (gc) |
372 | cow->togc = eina_hash_pointer_new(_eina_cow_gc_free); | 373 | cow->togc = eina_hash_pointer_new(_eina_cow_gc_free); |
@@ -453,7 +454,7 @@ eina_cow_write(Eina_Cow *cow, | |||
453 | const Eina_Cow_Data * const *data) | 454 | const Eina_Cow_Data * const *data) |
454 | { | 455 | { |
455 | Eina_Cow_Ptr *ref; | 456 | Eina_Cow_Ptr *ref; |
456 | void *r; | 457 | Eina_Cow_Data *r; |
457 | 458 | ||
458 | #ifdef EINA_COW_MAGIC_ON | 459 | #ifdef EINA_COW_MAGIC_ON |
459 | EINA_COW_MAGIC_CHECK(cow); | 460 | EINA_COW_MAGIC_CHECK(cow); |
@@ -484,8 +485,8 @@ eina_cow_write(Eina_Cow *cow, | |||
484 | } | 485 | } |
485 | #endif | 486 | #endif |
486 | 487 | ||
487 | if (cow->togc) | 488 | if (cow->togc) |
488 | _eina_cow_hash_del(cow, *data, ref); | 489 | _eina_cow_hash_del(cow, *data, ref); |
489 | 490 | ||
490 | #ifndef NVALGRIND | 491 | #ifndef NVALGRIND |
491 | VALGRIND_MAKE_MEM_NOACCESS(ref, sizeof (*ref)); | 492 | VALGRIND_MAKE_MEM_NOACCESS(ref, sizeof (*ref)); |
@@ -509,7 +510,7 @@ eina_cow_write(Eina_Cow *cow, | |||
509 | 510 | ||
510 | r = EINA_COW_DATA_GET(ref); | 511 | r = EINA_COW_DATA_GET(ref); |
511 | memcpy(r, *data, cow->struct_size); | 512 | memcpy(r, *data, cow->struct_size); |
512 | *((void**) data) = r; | 513 | *((Eina_Cow_Data**) data) = r; |
513 | 514 | ||
514 | end: | 515 | end: |
515 | #ifndef NVALGRIND | 516 | #ifndef NVALGRIND |
@@ -602,8 +603,8 @@ eina_cow_gc(Eina_Cow *cow) | |||
602 | { | 603 | { |
603 | Eina_Cow_GC *gc; | 604 | Eina_Cow_GC *gc; |
604 | Eina_Iterator *it; | 605 | Eina_Iterator *it; |
605 | void *data; | ||
606 | Eina_Bool r; | 606 | Eina_Bool r; |
607 | Eina_Cow_Ptr *ref; | ||
607 | 608 | ||
608 | EINA_COW_MAGIC_CHECK(cow); | 609 | EINA_COW_MAGIC_CHECK(cow); |
609 | 610 | ||
@@ -613,22 +614,20 @@ eina_cow_gc(Eina_Cow *cow) | |||
613 | it = eina_hash_iterator_data_new(cow->togc); | 614 | it = eina_hash_iterator_data_new(cow->togc); |
614 | r = eina_iterator_next(it, (void**) &gc); | 615 | r = eina_iterator_next(it, (void**) &gc); |
615 | eina_iterator_free(it); | 616 | eina_iterator_free(it); |
616 | 617 | ||
617 | if (!r) return EINA_FALSE; /* Something did go wrong here */ | 618 | if (!r) return EINA_FALSE; /* Something did go wrong here */ |
618 | 619 | ||
619 | /* Do handle hash and all funky merge think here */ | 620 | /* Do handle hash and all funky merge thing here */ |
620 | data = EINA_COW_DATA_GET(gc->ref); | 621 | ref = gc->ref; |
621 | 622 | ||
622 | #ifndef NVALGRIND | 623 | #ifndef NVALGRIND |
623 | VALGRIND_MAKE_MEM_DEFINED(gc->ref, sizeof (Eina_Cow_Ptr)); | 624 | VALGRIND_MAKE_MEM_DEFINED(ref, sizeof (*ref)); |
624 | #endif | 625 | #endif |
625 | _eina_cow_gc(cow, gc->ref, gc->dst, data); | 626 | _eina_cow_gc(cow, gc); |
626 | #ifndef NVALGRIND | 627 | #ifndef NVALGRIND |
627 | VALGRIND_MAKE_MEM_NOACCESS(gc->ref, sizeof (Eina_Cow_Ptr)); | 628 | VALGRIND_MAKE_MEM_NOACCESS(ref, sizeof (*ref)); |
628 | #endif | 629 | #endif |
629 | 630 | ||
630 | eina_hash_del(cow->togc, &gc->ref, gc); | ||
631 | |||
632 | return EINA_TRUE; | 631 | return EINA_TRUE; |
633 | } | 632 | } |
634 | 633 | ||
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; | |||
56 | * | 56 | * |
57 | * @param name The name of this pool, used for debug. | 57 | * @param name The name of this pool, used for debug. |
58 | * @param struct_size The size of the object from this pool. | 58 | * @param struct_size The size of the object from this pool. |
59 | * @param step How many object to allocate when the pool get empty. | 59 | * @param step How many objects to allocate when the pool gets empty. |
60 | * @param default_value The default value returned by this pool. | 60 | * @param default_value The default value returned by this pool. |
61 | * @param gc Is it possible to run the garbage collection on this pool. | 61 | * @param gc Is it possible to run garbage collection on this pool. |
62 | * @return a valid new Eina_Cow or @c NULL on error. | 62 | * @return a valid new Eina_Cow or @c NULL on error. |
63 | */ | 63 | */ |
64 | 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; | 64 | 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 | |||
71 | EAPI void eina_cow_del(Eina_Cow *cow); | 71 | EAPI void eina_cow_del(Eina_Cow *cow); |
72 | 72 | ||
73 | /** | 73 | /** |
74 | * @brief Return a initialized pointer to the pool. | 74 | * @brief Return an initialized pointer from the pool. |
75 | * @param cow The pool to take things from. | 75 | * @param cow The pool to take things from. |
76 | */ | 76 | */ |
77 | EAPI const Eina_Cow_Data *eina_cow_alloc(Eina_Cow *cow) EINA_WARN_UNUSED_RESULT; | 77 | 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, | |||
98 | /** | 98 | /** |
99 | * @brief Set back a pointer into read only. | 99 | * @brief Set back a pointer into read only. |
100 | * @param cow The pool the pointer come from. | 100 | * @param cow The pool the pointer come from. |
101 | * @param src The read only version of the pointer. | 101 | * @param dst The read only version of the pointer. |
102 | * @param data The pointer to which data where written to. | 102 | * @param data The pointer to which data was written to. |
103 | * | 103 | * |
104 | * NOTE: this function is not thread safe, be careful. | 104 | * NOTE: this function is not thread safe, be careful. |
105 | */ | 105 | */ |
@@ -118,13 +118,13 @@ EAPI void eina_cow_memcpy(Eina_Cow *cow, | |||
118 | const Eina_Cow_Data *src); | 118 | const Eina_Cow_Data *src); |
119 | 119 | ||
120 | /** | 120 | /** |
121 | * @brief Try to find entry that do have the same content and update them. | 121 | * @brief Try to find entries that have the same content and update them. |
122 | * @param cow The cow to try to compact. | 122 | * @param cow The cow to try to compact. |
123 | * @return EINA_TRUE if something was compacted, EINA_FALSE if nothing was. | 123 | * @return EINA_TRUE if something was compacted, EINA_FALSE if nothing was. |
124 | * | 124 | * |
125 | * There is no guaranty in the time it will require, but should remain low. | 125 | * There is no guaranty in the time it will require, but should remain low. |
126 | * It does run a hash function on all possible common structure trying to | 126 | * It does run a hash function on all possible common structures trying to |
127 | * find the one that match and merge then into one pointer. | 127 | * find the one that match and merge them into one pointer. |
128 | */ | 128 | */ |
129 | EAPI Eina_Bool eina_cow_gc(Eina_Cow *cow); | 129 | EAPI Eina_Bool eina_cow_gc(Eina_Cow *cow); |
130 | 130 | ||
@@ -137,7 +137,7 @@ EAPI Eina_Bool eina_cow_gc(Eina_Cow *cow); | |||
137 | * @param Write The name of the variable where to put the writeable pointer to. | 137 | * @param Write The name of the variable where to put the writeable pointer to. |
138 | * @since 1.8.0 | 138 | * @since 1.8.0 |
139 | * | 139 | * |
140 | * Be careful this macro open a C scope that it expect to be closed by | 140 | * Be careful this macro opens a C scope that is expected to be closed by |
141 | * EINA_COW_WRITE_END(). | 141 | * EINA_COW_WRITE_END(). |
142 | */ | 142 | */ |
143 | #define EINA_COW_WRITE_BEGIN(Cow, Read, Write_Type, Write) \ | 143 | #define EINA_COW_WRITE_BEGIN(Cow, Read, Write_Type, Write) \ |