struct _Eina_Array
{
void **data; /**< Pointer to a vector of pointer to payload */
- unsigned int total; /**< Total number of slot in the vector */
- unsigned int count; /**< Number of activ slot in the vector */
+ unsigned int total; /**< Total number of slots in the vector */
+ unsigned int count; /**< Number of active slots in the vector */
unsigned int step; /**< How much must we grow the vector when it is full */
+#ifdef EINA_RWLOCKS_ENABLED
+ pthread_rwlock_t lock;
+#endif
EINA_MAGIC
};
static inline Eina_Bool eina_array_push(Eina_Array *array, const void *data) EINA_ARG_NONNULL(1, 2);
static inline void * eina_array_pop(Eina_Array *array) EINA_ARG_NONNULL(1);
-static inline void * eina_array_data_get(const Eina_Array *array, unsigned int idx) EINA_ARG_NONNULL(1);
-static inline void eina_array_data_set(const Eina_Array *array, unsigned int idx, const void *data) EINA_ARG_NONNULL(1, 3);
-static inline unsigned int eina_array_count_get(const Eina_Array *array) EINA_ARG_NONNULL(1);
+static inline void * eina_array_data_get(Eina_Array *array, unsigned int idx) EINA_ARG_NONNULL(1);
+static inline void eina_array_data_set(Eina_Array *array, unsigned int idx, const void *data) EINA_ARG_NONNULL(1, 3);
+static inline unsigned int eina_array_count_get(Eina_Array *array) EINA_ARG_NONNULL(1);
-EAPI Eina_Iterator * eina_array_iterator_new(const Eina_Array *array) EINA_MALLOC EINA_ARG_NONNULL(1) EINA_WARN_UNUSED_RESULT;
-EAPI Eina_Accessor * eina_array_accessor_new(const Eina_Array *array) EINA_MALLOC EINA_ARG_NONNULL(1) EINA_WARN_UNUSED_RESULT;
+EAPI Eina_Iterator * eina_array_iterator_new(Eina_Array *array) EINA_MALLOC EINA_ARG_NONNULL(1) EINA_WARN_UNUSED_RESULT;
+EAPI Eina_Accessor * eina_array_accessor_new(Eina_Array *array) EINA_MALLOC EINA_ARG_NONNULL(1) EINA_WARN_UNUSED_RESULT;
/**
* @def EINA_ARRAY_ITER_NEXT
* @param item The data
* @param iterator The iterator
*
- * This macro allow the iteration over @p array in an easy way. It
+ * This macro allows the iteration over @p array in an easy way. It
* iterates from the first element to the last one. @p index is an
- * integer that increase from 0 to the number of elements. @p item is
+ * integer that increases from 0 to the number of elements. @p item is
* the data of each element of @p array, so it is a pointer to a type
* chosen by the user. @p iterator is of type #Eina_Array_Iterator.
*
(index < eina_array_count_get(array)) && ((item = *((iterator)++))); \
++(index))
+#ifdef EINA_RWLOCKS_ENABLED
+/**
+ * @def EINA_ARRAY_THREADSAFE_ITER_NEXT
+ * @brief Macro to iterate over an array easily while mutexing.
+ *
+ * @param array The array to iterate over.
+ * @param index The integer number that is increased while itareting.
+ * @param item The data
+ * @param iterator The iterator
+ * @param code The code in the iterator loop
+ *
+ * This macro allows the iteration over @p array in an easy way. It
+ * iterates from the first element to the last one. @p index is an
+ * integer that increases from 0 to the number of elements. @p item is
+ * the data of each element of @p array, so it is a pointer to a type
+ * chosen by the user. @p iterator is of type #Eina_Array_Iterator.
+ * @p code is the entire chunk of code which will be in the iterator loop,
+ * terminated by a semicolon.
+ *
+ * This macro can be used for safely freeing the data of an array in a thread,
+ * like in the following example:
+ *
+ * @code
+ * Eina_Array *array;
+ * char *item;
+ * Eina_Array_Iterator iterator;
+ * unsigned int i;
+ *
+ * // array is already filled,
+ * // its elements are just duplicated strings,
+ * // EINA_ARRAY_ITER_NEXT will be used to free those strings
+ *
+ * EINA_ARRAY_THREADSAFE_ITER_NEXT(array, i, item, iterator,
+ * {
+ * if (item)
+ * free(item);
+ * }
+ * );
+ * @endcode
+ */
+#define EINA_ARRAY_THREADSAFE_ITER_NEXT(array, index, item, iterator, code...) \
+ if (_eina_array_threadsafety) \
+ pthread_rwlock_wrlock(&(array)->lock); \
+ for (index = 0, iterator = (array)->data; \
+ (index < (array)->count) && ((item = *((iterator)++))); \
+ ++(index)) \
+ code \
+ if (_eina_array_threadsafety) \
+ pthread_rwlock_unlock(&(array)->lock)
+
+#else
+#define EINA_ARRAY_THREADSAFE_ITER_NEXT(array, index, item, iterator, code...) \
+ do \
+ { \
+ for (index = 0, iterator = (array)->data; \
+ (index < (array)->count) && ((item = *((iterator)++))); \
+ ++(index)) \
+ code \
+ } \
+ while (0)
+#endif
+
+#ifdef EINA_RWLOCKS_ENABLED
+
+/**
+ * @def EINA_ARRAY_THREADSAFE_ITER_RETURN
+ * @brief Macro to perform a return while using EINA_ARRAY_THREADSAFE_ITER_NEXT
+ *
+ * @param array The array being iterated over.
+ * @param retval The value to be returned
+ *
+ * This macro should be used any time the user wishes to perform a return
+ * statement while using EINA_ARRAY_THREADSAFE_ITER_RETURN to unlock any mutexes
+ * which may have been locked while iterating. Failure to use this will likely
+ * result in a deadlock.
+ *
+ * example:
+ *
+ * @code
+ * Eina_Array *array;
+ * char *item;
+ * Eina_Array_Iterator iterator;
+ * unsigned int i;
+ *
+ * // array is already filled,
+ * // its elements are just duplicated strings,
+ * // EINA_ARRAY_ITER_NEXT will be used to free those strings
+ *
+ * EINA_ARRAY_THREADSAFE_ITER_NEXT(array, i, item, iterator,
+ * {
+ * if (item)
+ * free(item);
+ * else
+ * EINA_ARRAY_THREADSAFE_ITER_RETURN(array, NULL);
+ * }
+ * );
+ * @endcode
+ */
+#define EINA_ARRAY_THREADSAFE_ITER_RETURN(array, retval) \
+do \
+ { \
+ if (_eina_array_threadsafety) \
+ pthread_rwlock_unlock(&(array)->lock); \
+ return (retval); \
+ } \
+while (0)
+
+#else
+
+#define EINA_ARRAY_THREADSAFE_ITER_RETURN(array, retval) \
+ return (retval)
+
+#endif
+
#include "eina_inline_array.x"
/**
#ifndef EINA_INLINE_ARRAY_X_
#define EINA_INLINE_ARRAY_X_
+#ifdef EINA_RWLOCKS_ENABLED
+# include <pthread.h>
+#endif
+extern Eina_Bool _eina_array_threadsafety;
/**
* @cond LOCAL
*/
{
if (!data) return EINA_FALSE;
+#ifdef EINA_RWLOCKS_ENABLED
+ if (_eina_array_threadsafety)
+ pthread_rwlock_wrlock(&array->lock);
+#endif
+
if (EINA_UNLIKELY((array->count + 1) > array->total))
- if (!eina_array_grow(array)) return EINA_FALSE;
+ if (!eina_array_grow(array))
+ {
+
+#ifdef EINA_RWLOCKS_ENABLED
+ if (_eina_array_threadsafety)
+ pthread_rwlock_unlock(&array->lock);
+#endif
+
+ return EINA_FALSE;
+ }
array->data[array->count++] = (void*) data;
+
+#ifdef EINA_RWLOCKS_ENABLED
+ if (_eina_array_threadsafety)
+ pthread_rwlock_unlock(&array->lock);
+#endif
+
return EINA_TRUE;
}
static inline void *
eina_array_pop(Eina_Array *array)
{
- if (array->count <= 0) return NULL;
- return array->data[--array->count];
+ void *ret = NULL;
+
+#ifdef EINA_RWLOCKS_ENABLED
+ if (_eina_array_threadsafety)
+ pthread_rwlock_wrlock(&array->lock);
+#endif
+
+ if (array->count <= 0)
+ {
+
+#ifdef EINA_RWLOCKS_ENABLED
+ if (_eina_array_threadsafety)
+ pthread_rwlock_unlock(&array->lock);
+#endif
+
+ return NULL;
+ }
+ ret = array->data[--array->count];
+
+#ifdef EINA_RWLOCKS_ENABLED
+ if (_eina_array_threadsafety)
+ pthread_rwlock_unlock(&array->lock);
+#endif
+
+ return ret;
}
/**
* idx. If it is @c NULL or invalid, the program may crash.
*/
static inline void *
-eina_array_data_get(const Eina_Array *array, unsigned int idx)
+eina_array_data_get(Eina_Array *array, unsigned int idx)
{
- return array->data[idx];
+ void *ret = NULL;
+
+#ifdef EINA_RWLOCKS_ENABLED
+ if (_eina_array_threadsafety)
+ pthread_rwlock_rdlock(&array->lock);
+#endif
+
+ ret = array->data[idx];
+
+#ifdef EINA_RWLOCKS_ENABLED
+ if (_eina_array_threadsafety)
+ pthread_rwlock_unlock(&array->lock);
+#endif
+
+ return ret;
}
/**
- * @brief Return the data at a given position in an array.
+ * @brief Set the data at a given position in an array.
*
* @param array The array.
* @param idx The potition of the data to set.
* @param data The data to set.
*
- * This function returns the data at the position @p idx in @p
+ * This function sets the data at the position @p idx in @p
* array. For performance reasons, there is no check of @p array or @p
* idx. If it is @c NULL or invalid, the program may crash.
*/
static inline void
-eina_array_data_set(const Eina_Array *array, unsigned int idx, const void *data)
+eina_array_data_set(Eina_Array *array, unsigned int idx, const void *data)
{
+#ifdef EINA_RWLOCKS_ENABLED
+ if (_eina_array_threadsafety)
+ pthread_rwlock_wrlock(&array->lock);
+#endif
+
array->data[idx] = (void*) data;
+
+#ifdef EINA_RWLOCKS_ENABLED
+ if (_eina_array_threadsafety)
+ pthread_rwlock_unlock(&array->lock);
+#endif
}
/**
* @c NULL or invalid, the program may crash.
*/
static inline unsigned int
-eina_array_count_get(const Eina_Array *array)
+eina_array_count_get(Eina_Array *array)
{
+#ifdef EINA_RWLOCKS_ENABLED
+ if (_eina_array_threadsafety)
+ pthread_rwlock_rdlock(&array->lock);
+#endif
+
return array->count;
+
+#ifdef EINA_RWLOCKS_ENABLED
+ if (_eina_array_threadsafety)
+ pthread_rwlock_unlock(&array->lock);
+#endif
}
/**
EAPI void
eina_module_list_free(Eina_Array *list) EINA_ARG_NONNULL(1);
EAPI Eina_Module *
-eina_module_find(const Eina_Array *array, const char *module) EINA_ARG_NONNULL(
+eina_module_find(Eina_Array *array, const char *module) EINA_ARG_NONNULL(
1,
2);
void eina_share_common_threads_shutdown(void);
void eina_log_threads_init(void);
void eina_log_threads_shutdown(void);
+#ifdef EINA_RWLOCKS_ENABLE
+void eina_array_threadsafety_init(void);
+void eina_array_threadsafety_shutdown(void);
+#endif
#endif
#endif /* EINA_PRIVATE_H_ */
#include <string.h>
#include <stdio.h>
+#ifdef EFL_HAVE_POSIX_THREADS_RWLOCK
+# include <pthread.h>
+#endif
+
#include "eina_config.h"
#include "eina_private.h"
#include "eina_error.h"
{
Eina_Iterator iterator;
- const Eina_Array *array;
+ Eina_Array *array;
unsigned int index;
EINA_MAGIC
struct _Eina_Accessor_Array
{
Eina_Accessor accessor;
- const Eina_Array *array;
+ Eina_Array *array;
EINA_MAGIC
};
static int _eina_array_log_dom = -1;
+#ifdef EFL_HAVE_POSIX_THREADS_RWLOCK
+Eina_Bool _eina_array_threadsafety = EINA_FALSE;
+#endif
+
#ifdef ERR
#undef ERR
#endif
#endif
#define DBG(...) EINA_LOG_DOM_DBG(_eina_array_log_dom, __VA_ARGS__)
-static void eina_array_iterator_free(Eina_Iterator_Array *it)
-EINA_ARG_NONNULL(1);
-static Eina_Array *eina_array_iterator_get_container(Eina_Iterator_Array *it)
-EINA_ARG_NONNULL(1);
+static void eina_array_iterator_free(Eina_Iterator_Array *it) EINA_ARG_NONNULL(1);
+static Eina_Array *eina_array_iterator_get_container(Eina_Iterator_Array *it) EINA_ARG_NONNULL(1);
static Eina_Bool eina_array_iterator_next(Eina_Iterator_Array *it,
void **data) EINA_ARG_NONNULL(1);
static Eina_Bool eina_array_accessor_get_at(Eina_Accessor_Array *it,
unsigned int idx,
void **data) EINA_ARG_NONNULL(1);
-static Eina_Array *eina_array_accessor_get_container(Eina_Accessor_Array *it)
-EINA_ARG_NONNULL(1);
-static void eina_array_accessor_free(Eina_Accessor_Array *it)
-EINA_ARG_NONNULL(1);
+static Eina_Array *eina_array_accessor_get_container(Eina_Accessor_Array *it) EINA_ARG_NONNULL(1);
+static void eina_array_accessor_free(Eina_Accessor_Array *it) EINA_ARG_NONNULL(1);
static Eina_Bool
eina_array_iterator_next(Eina_Iterator_Array *it, void **data)
return EINA_TRUE;
}
+#ifdef EFL_HAVE_POSIX_THREADS_RWLOCK
+/**
+ * @brief Enable threadsafe mode in arrays
+ *
+ * This function enables threadsafe mode in all arrays.
+ *
+ * @warning Once enabled, this CANNOT be disabled.
+ */
+
+void
+eina_array_threadsafety_init(void)
+{
+ _eina_array_threadsafety = EINA_TRUE;
+}
+
+/**
+ * @brief Disable threadsafe mode in arrays
+ *
+ * This function disables threadsafe mode in all arrays.
+ */
+
+void
+eina_array_threadsafety_shutdown(void)
+{
+ _eina_array_threadsafety = EINA_TRUE;
+}
+
+#endif
+
+
/*============================================================================*
* API *
*============================================================================*/
array->total = 0;
array->count = 0;
array->step = step;
+#ifdef EFL_HAVE_POSIX_THREADS_RWLOCK
+ pthread_rwlock_init(&array->lock, NULL);
+#endif
DBG("array=%p", array);
* @param array The array to free.
*
* This function frees @p array. It calls first eina_array_flush() then
- * free the memory of the pointeur. It does not free the memory
+ * free the memory of the pointer. It does not free the memory
* allocated for the elements of @p array. To free them, use
* #EINA_ARRAY_ITER_NEXT. For performance reasons, there is no check
* of @p array.
EAPI void
eina_array_free(Eina_Array *array)
{
+#ifdef EFL_HAVE_POSIX_THREADS_RWLOCK
+ if (_eina_array_threadsafety)
+ pthread_rwlock_wrlock(&array->lock);
+#endif
eina_array_flush(array);
EINA_MAGIC_CHECK_ARRAY(array);
EINA_SAFETY_ON_NULL_RETURN(array);
DBG("array=%p", array);
+#ifdef EFL_HAVE_POSIX_THREADS_RWLOCK
+ if (_eina_array_threadsafety)
+ pthread_rwlock_destroy(&array->lock);
+#endif
MAGIC_FREE(array);
}
eina_array_step_set(Eina_Array *array, unsigned int step)
{
EINA_SAFETY_ON_NULL_RETURN(array);
+#ifdef EFL_HAVE_POSIX_THREADS_RWLOCK
+ if (_eina_array_threadsafety)
+ pthread_rwlock_wrlock(&array->lock);
+#endif
array->data = NULL;
array->total = 0;
array->count = 0;
array->step = step;
EINA_MAGIC_SET(array, EINA_MAGIC_ARRAY);
DBG("array=%p, step=%u", array, step);
+#ifdef EFL_HAVE_POSIX_THREADS_RWLOCK
+ if (_eina_array_threadsafety)
+ pthread_rwlock_unlock(&array->lock);
+#endif
}
/**
EAPI void
eina_array_clean(Eina_Array *array)
{
- EINA_MAGIC_CHECK_ARRAY(array);
EINA_SAFETY_ON_NULL_RETURN(array);
+ EINA_MAGIC_CHECK_ARRAY(array);
+#ifdef EFL_HAVE_POSIX_THREADS_RWLOCK
+ if (_eina_array_threadsafety)
+ pthread_rwlock_wrlock(&array->lock);
+#endif
array->count = 0;
DBG("array=%p", array);
+#ifdef EFL_HAVE_POSIX_THREADS_RWLOCK
+ if (_eina_array_threadsafety)
+ pthread_rwlock_unlock(&array->lock);
+#endif
}
/**
EAPI void
eina_array_flush(Eina_Array *array)
{
- EINA_MAGIC_CHECK_ARRAY(array);
EINA_SAFETY_ON_NULL_RETURN(array);
+ EINA_MAGIC_CHECK_ARRAY(array);
+#ifdef EFL_HAVE_POSIX_THREADS_RWLOCK
+ if (_eina_array_threadsafety)
+ pthread_rwlock_wrlock(&array->lock);
+#endif
DBG("array=%p", array);
array->count = 0;
array->total = 0;
free(array->data);
array->data = NULL;
+#ifdef EFL_HAVE_POSIX_THREADS_RWLOCK
+ if (_eina_array_threadsafety)
+ pthread_rwlock_unlock(&array->lock);
+#endif
}
/**
unsigned int limit;
unsigned int i;
- EINA_MAGIC_CHECK_ARRAY(array);
EINA_SAFETY_ON_NULL_RETURN_VAL(array, EINA_FALSE);
EINA_SAFETY_ON_NULL_RETURN_VAL(keep, EINA_FALSE);
-
+ EINA_MAGIC_CHECK_ARRAY(array);
+#ifdef EFL_HAVE_POSIX_THREADS_RWLOCK
+ if (_eina_array_threadsafety)
+ pthread_rwlock_wrlock(&array->lock);
+#endif
DBG("array=%p, keep=%p, gdata=%p", array, keep, gdata);
if (array->total == 0)
array->data = tmp;
array->count = total;
-
+#ifdef EFL_HAVE_POSIX_THREADS_RWLOCK
+ if (_eina_array_threadsafety)
+ pthread_rwlock_unlock(&array->lock);
+#endif
return EINA_TRUE;
}
* set. Otherwise, a valid iterator is returned.
*/
EAPI Eina_Iterator *
-eina_array_iterator_new(const Eina_Array *array)
+eina_array_iterator_new(Eina_Array *array)
{
Eina_Iterator_Array *it;
- EINA_MAGIC_CHECK_ARRAY(array);
EINA_SAFETY_ON_NULL_RETURN_VAL(array, NULL);
+ EINA_MAGIC_CHECK_ARRAY(array);
eina_error_set(0);
it = calloc(1, sizeof (Eina_Iterator_Array));
EINA_MAGIC_SET(it, EINA_MAGIC_ARRAY_ITERATOR);
EINA_MAGIC_SET(&it->iterator, EINA_MAGIC_ITERATOR);
+#ifdef EFL_HAVE_POSIX_THREADS_RWLOCK
+ if (_eina_array_threadsafety)
+ pthread_rwlock_rdlock(&array->lock);
+#endif
it->array = array;
it->iterator.next = FUNC_ITERATOR_NEXT(eina_array_iterator_next);
it->iterator.free = FUNC_ITERATOR_FREE(eina_array_iterator_free);
DBG("array=%p, iterator=%p", array, it);
-
+#ifdef EFL_HAVE_POSIX_THREADS_RWLOCK
+ if (_eina_array_threadsafety)
+ pthread_rwlock_unlock(&array->lock);
+#endif
return &it->iterator;
}
* set. Otherwise, a valid accessor is returned.
*/
EAPI Eina_Accessor *
-eina_array_accessor_new(const Eina_Array *array)
+eina_array_accessor_new(Eina_Array *array)
{
Eina_Accessor_Array *it;
- EINA_MAGIC_CHECK_ARRAY(array);
EINA_SAFETY_ON_NULL_RETURN_VAL(array, NULL);
+ EINA_MAGIC_CHECK_ARRAY(array);
eina_error_set(0);
it = calloc(1, sizeof (Eina_Accessor_Array));
EINA_MAGIC_SET(it, EINA_MAGIC_ARRAY_ACCESSOR);
EINA_MAGIC_SET(&it->accessor, EINA_MAGIC_ACCESSOR);
+#ifdef EFL_HAVE_POSIX_THREADS_RWLOCK
+ if (_eina_array_threadsafety)
+ pthread_rwlock_rdlock(&array->lock);
+#endif
it->array = array;
it->accessor.get_at = FUNC_ACCESSOR_GET_AT(eina_array_accessor_get_at);
it->accessor.free = FUNC_ACCESSOR_FREE(eina_array_accessor_free);
DBG("array=%p, accessor=%p", array, it);
-
+#ifdef EFL_HAVE_POSIX_THREADS_RWLOCK
+ if (_eina_array_threadsafety)
+ pthread_rwlock_unlock(&array->lock);
+#endif
return &it->accessor;
}
char *tmp;
unsigned int i;
- EINA_ARRAY_ITER_NEXT(names, i, tmp, it)
- free(tmp);
+ EINA_ARRAY_THREADSAFE_ITER_NEXT(names, i, tmp, it,
+ free(tmp);
+ );
eina_array_free(names);
}
eina_share_common_threads_init();
eina_log_threads_init();
+#ifdef EFL_RWLOCKS_ENABLE
+ eina_array_threadsafety_init();
+#endif
_threads_activated = EINA_TRUE;
return ret;
eina_share_common_threads_shutdown();
eina_log_threads_shutdown();
+#ifdef EFL_RWLOCKS_ENABLE
+ eina_array_threadsafety_shutdown();
+#endif
_threads_activated = EINA_FALSE;
* If the element is found return the module else NULL.
*/
EAPI Eina_Module *
-eina_module_find(const Eina_Array *array, const char *module)
+eina_module_find(Eina_Array *array, const char *module)
{
unsigned int i;
Eina_Array_Iterator iterator;
Eina_Module *m;
- EINA_ARRAY_ITER_NEXT(array, i, m, iterator)
- {
- char *file_m;
- char *tmp;
- ssize_t len;
-
- /* basename() can modify its argument, so we first get a copie */
- /* do not use strdupa, as opensolaris does not have it */
- len = strlen(eina_module_file_get(m));
- tmp = alloca(len + 1);
- memcpy(tmp, eina_module_file_get(m), len + 1);
- file_m = basename(tmp);
- len = strlen(file_m);
- len -= sizeof(SHARED_LIB_SUFFIX) - 1;
- if (len <= 0)
- continue;
-
- if (!strncmp(module, file_m, len))
- return m;
- }
+ EINA_ARRAY_THREADSAFE_ITER_NEXT(array, i, m, iterator,
+ {
+ char *file_m;
+ char *tmp;
+ ssize_t len;
+
+ /* basename() can modify its argument, so we first get a copie */
+ /* do not use strdupa, as opensolaris does not have it */
+ len = strlen(eina_module_file_get(m));
+ tmp = alloca(len + 1);
+ memcpy(tmp, eina_module_file_get(m), len + 1);
+ file_m = basename(tmp);
+ len = strlen(file_m);
+ len -= sizeof(SHARED_LIB_SUFFIX) - 1;
+ if (len <= 0)
+ continue;
+
+ if (!strncmp(module, file_m, len))
+ EINA_ARRAY_THREADSAFE_ITER_RETURN(array, m);
+ }
+ );
return NULL;
}
EINA_SAFETY_ON_NULL_RETURN(array);
DBG("array %p, count %u", array, array->count);
- EINA_ARRAY_ITER_NEXT(array, i, m, iterator)
- eina_module_load(m);
+ EINA_ARRAY_THREADSAFE_ITER_NEXT(array, i, m, iterator,
+ eina_module_load(m);
+ );
}
/**
EINA_SAFETY_ON_NULL_RETURN(array);
DBG("array %p, count %u", array, array->count);
- EINA_ARRAY_ITER_NEXT(array, i, m, iterator)
- eina_module_unload(m);
+ EINA_ARRAY_THREADSAFE_ITER_NEXT(array, i, m, iterator,
+ eina_module_unload(m);
+ );
}
/**
EINA_SAFETY_ON_NULL_RETURN(array);
DBG("array %p, count %u", array, array->count);
- EINA_ARRAY_ITER_NEXT(array, i, m, iterator)
- eina_module_free(m);
+ EINA_ARRAY_THREADSAFE_ITER_NEXT(array, i, m, iterator,
+ eina_module_free(m);
+ );
eina_array_flush(array);
}
Eina_Array_Iterator et;
unsigned int i;
- EINA_ARRAY_ITER_NEXT(it->stack, i, item, et)
- free(item);
+ EINA_ARRAY_THREADSAFE_ITER_NEXT(it->stack, i, item, et,
+ free(item);
+ );
eina_array_free(it->stack);
free(it);
if (i == 500)
{
- EINA_ARRAY_ITER_NEXT(array, j, ebo, it)
- free(ebo);
+ EINA_ARRAY_THREADSAFE_ITER_NEXT(array, j, ebo, it,
+ free(ebo);
+ );
eina_array_clean(array);
}
else if (i % 30 == 0)
eina_array_remove(array, keep, NULL);
- EINA_ARRAY_ITER_NEXT(array, j, ebo, it)
- ebo->keep = rand() < (RAND_MAX / 2) ? ebo->keep : EINA_FALSE;
+ EINA_ARRAY_THREADSAFE_ITER_NEXT(array, j, ebo, it,
+ ebo->keep = rand() < (RAND_MAX / 2) ? ebo->keep : EINA_FALSE;
+ );
}
- EINA_ARRAY_ITER_NEXT(array, j, ebo, it)
- free(ebo);
+ EINA_ARRAY_THREADSAFE_ITER_NEXT(array, j, ebo, it,
+ free(ebo);
+ );
eina_array_free(array);
evas_hash_free(hash);
- EINA_ARRAY_ITER_NEXT(array, i, tmp_val, it)
- free(tmp_val);
+ EINA_ARRAY_THREADSAFE_ITER_NEXT(array, i, tmp_val, it,
+ free(tmp_val);
+ );
eina_array_free(array);
}
fail_if(atoi(tmp) != 200);
free(tmp);
- EINA_ARRAY_ITER_NEXT(ea, i, tmp, it)
- {
- fail_if((unsigned int)atoi(tmp) != i);
- free(tmp);
- }
+ EINA_ARRAY_THREADSAFE_ITER_NEXT(ea, i, tmp, it,
+ {
+ fail_if((unsigned int)atoi(tmp) != i);
+ free(tmp);
+ }
+ );
fail_if(i != 200);
fail_if(eina_array_data_get(&sea, 10) == NULL);
fail_if(atoi(eina_array_data_get(&sea, 10)) != 10);
- EINA_ARRAY_ITER_NEXT(&sea, i, tmp, it)
- {
- fail_if((unsigned int)atoi(tmp) != i);
- free(tmp);
- }
+ EINA_ARRAY_THREADSAFE_ITER_NEXT(&sea, i, tmp, it,
+ {
+ fail_if((unsigned int)atoi(tmp) != i);
+ free(tmp);
+ }
+ );
fail_if(i != 200);
fail_if(eina_array_remove(ea, keep_int, NULL) != EINA_TRUE);
fail_if(eina_array_count_get(ea) != 990);
- EINA_ARRAY_ITER_NEXT(ea, i, tmp, it)
- fail_if(*tmp == 0);
+ EINA_ARRAY_THREADSAFE_ITER_NEXT(ea, i, tmp, it,
+ fail_if(*tmp == 0);
+ );
// Remove the last items
for (i = 980; i < 990; ++i)
// Remove all items
fail_if(eina_array_count_get(ea) != 980);
- EINA_ARRAY_ITER_NEXT(ea, i, tmp, it)
- {
- fail_if(*tmp == 0);
- *tmp = 0;
- }
+ EINA_ARRAY_THREADSAFE_ITER_NEXT(ea, i, tmp, it,
+ {
+ fail_if(*tmp == 0);
+ *tmp = 0;
+ }
+ );
eina_array_remove(ea, keep_int, NULL);
ea = eina_benchmark_run(eb);
fail_if(!ea);
- EINA_ARRAY_ITER_NEXT(ea, i, tmp, it)
- {
- fail_if(!tmp);
- fail_if(unlink(tmp));
- }
+ EINA_ARRAY_THREADSAFE_ITER_NEXT(ea, i, tmp, it,
+ {
+ fail_if(!tmp);
+ fail_if(unlink(tmp));
+ }
+ );
fail_if(global_test != 499500);
_eina_rbtree_black_height(&root->node,
EINA_RBTREE_CMP_NODE_CB(eina_rbtree_int_cmp));
- EINA_ARRAY_ITER_NEXT(ea, i, item, it)
- {
- root = (Eina_Rbtree_Int *)eina_rbtree_inline_remove(
- &root->node,
- &item->node,
- EINA_RBTREE_CMP_NODE_CB(
- eina_rbtree_int_cmp),
- NULL);
- _eina_rbtree_black_height(&root->node,
- EINA_RBTREE_CMP_NODE_CB(eina_rbtree_int_cmp));
- }
+ EINA_ARRAY_THREADSAFE_ITER_NEXT(ea, i, item, it,
+ {
+ root = (Eina_Rbtree_Int *)eina_rbtree_inline_remove(
+ &root->node,
+ &item->node,
+ EINA_RBTREE_CMP_NODE_CB(
+ eina_rbtree_int_cmp),
+ NULL);
+ _eina_rbtree_black_height(&root->node,
+ EINA_RBTREE_CMP_NODE_CB(eina_rbtree_int_cmp));
+ }
+ );
fail_if(root != NULL);