forked from enlightenment/efl
* eina: remove thread safe data type for now. They will be back !
SVN revision: 51179
This commit is contained in:
parent
128e61649d
commit
f75eab161d
|
@ -29,11 +29,6 @@
|
||||||
#include "eina_accessor.h"
|
#include "eina_accessor.h"
|
||||||
#include "eina_magic.h"
|
#include "eina_magic.h"
|
||||||
|
|
||||||
#ifdef EINA_RWLOCKS_ENABLED
|
|
||||||
# include <pthread.h>
|
|
||||||
# include <errno.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @addtogroup Eina_Data_Types_Group Data Types
|
* @addtogroup Eina_Data_Types_Group Data Types
|
||||||
*
|
*
|
||||||
|
|
|
@ -23,10 +23,6 @@
|
||||||
#include "eina_types.h"
|
#include "eina_types.h"
|
||||||
#include "eina_iterator.h"
|
#include "eina_iterator.h"
|
||||||
|
|
||||||
#ifdef EINA_RWLOCKS_ENABLED
|
|
||||||
# include <pthread.h>
|
|
||||||
# include <errno.h>
|
|
||||||
#endif
|
|
||||||
/**
|
/**
|
||||||
* @addtogroup Eina_Data_Types_Group Data Types
|
* @addtogroup Eina_Data_Types_Group Data Types
|
||||||
*
|
*
|
||||||
|
|
|
@ -19,10 +19,6 @@
|
||||||
#ifndef EINA_INLINE_ARRAY_X_
|
#ifndef EINA_INLINE_ARRAY_X_
|
||||||
#define EINA_INLINE_ARRAY_X_
|
#define EINA_INLINE_ARRAY_X_
|
||||||
|
|
||||||
#ifdef EINA_RWLOCKS_ENABLED
|
|
||||||
# include <pthread.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @cond LOCAL
|
* @cond LOCAL
|
||||||
*/
|
*/
|
||||||
|
@ -62,20 +58,12 @@ eina_array_push(Eina_Array *array, const void *data)
|
||||||
{
|
{
|
||||||
if (!data) return EINA_FALSE;
|
if (!data) return EINA_FALSE;
|
||||||
|
|
||||||
if (EINA_UNLIKELY(!eina_array_wrlock(array)))
|
|
||||||
return EINA_FALSE;
|
|
||||||
|
|
||||||
if (EINA_UNLIKELY((array->count + 1) > array->total))
|
if (EINA_UNLIKELY((array->count + 1) > array->total))
|
||||||
if (!eina_array_grow(array))
|
if (!eina_array_grow(array))
|
||||||
{
|
return EINA_FALSE;
|
||||||
eina_array_unlock(array);
|
|
||||||
return EINA_FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
array->data[array->count++] = (void*) data;
|
array->data[array->count++] = (void*) data;
|
||||||
|
|
||||||
eina_array_unlock(array);
|
|
||||||
|
|
||||||
return EINA_TRUE;
|
return EINA_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -96,17 +84,12 @@ eina_array_pop(Eina_Array *array)
|
||||||
{
|
{
|
||||||
void *ret = NULL;
|
void *ret = NULL;
|
||||||
|
|
||||||
if (EINA_UNLIKELY(!eina_array_wrlock(array)))
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
if (array->count <= 0)
|
if (array->count <= 0)
|
||||||
goto on_empty;
|
goto on_empty;
|
||||||
|
|
||||||
ret = array->data[--array->count];
|
ret = array->data[--array->count];
|
||||||
|
|
||||||
on_empty:
|
on_empty:
|
||||||
eina_array_unlock(array);
|
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -160,71 +143,6 @@ eina_array_count_get(const Eina_Array *array)
|
||||||
return array->count;
|
return array->count;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef EINA_RWLOCKS_ENABLED
|
|
||||||
static inline Eina_Bool
|
|
||||||
eina_array_rdlock(const Eina_Array *array)
|
|
||||||
{
|
|
||||||
if (!array) return EINA_FALSE;
|
|
||||||
if (array->threadsafe)
|
|
||||||
{
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
ret = pthread_rwlock_rdlock(&((Eina_Array*) array)->lock);
|
|
||||||
if ((ret != 0) && (ret != EDEADLK))
|
|
||||||
return EINA_FALSE;
|
|
||||||
}
|
|
||||||
return EINA_TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline Eina_Bool
|
|
||||||
eina_array_wrlock(Eina_Array *array)
|
|
||||||
{
|
|
||||||
if (!array) return EINA_FALSE;
|
|
||||||
if (array->threadsafe)
|
|
||||||
{
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
ret = pthread_rwlock_wrlock(&array->lock);
|
|
||||||
if ((ret != 0) && (ret != EDEADLK))
|
|
||||||
return EINA_FALSE;
|
|
||||||
}
|
|
||||||
return EINA_TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline Eina_Bool
|
|
||||||
eina_array_unlock(const Eina_Array *array)
|
|
||||||
{
|
|
||||||
if (!array) return EINA_FALSE;
|
|
||||||
if (array->threadsafe)
|
|
||||||
if (pthread_rwlock_unlock(&((Eina_Array*) array)->lock))
|
|
||||||
return EINA_FALSE;
|
|
||||||
return EINA_TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
static inline Eina_Bool
|
|
||||||
eina_array_rdlock(const Eina_Array *array)
|
|
||||||
{
|
|
||||||
if (!array) return EINA_FALSE;
|
|
||||||
return EINA_TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline Eina_Bool
|
|
||||||
eina_array_wrlock(Eina_Array *array)
|
|
||||||
{
|
|
||||||
if (!array) return EINA_FALSE;
|
|
||||||
return EINA_TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline Eina_Bool
|
|
||||||
eina_array_unlock(const Eina_Array *array)
|
|
||||||
{
|
|
||||||
if (!array) return EINA_FALSE;
|
|
||||||
return EINA_TRUE;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Provide a safe way to iterate over an array
|
* @brief Provide a safe way to iterate over an array
|
||||||
*
|
*
|
||||||
|
@ -233,12 +151,9 @@ eina_array_unlock(const Eina_Array *array)
|
||||||
* @param fdata The user data to pass to the callback.
|
* @param fdata The user data to pass to the callback.
|
||||||
* @return EINA_TRUE if it successfully iterate all items of the array.
|
* @return EINA_TRUE if it successfully iterate all items of the array.
|
||||||
*
|
*
|
||||||
* This function provide a safe way to iterate over an array. If
|
* This function provide a safe way to iterate over an array. @p cb should
|
||||||
* the array was created with @p eina_array_threadsafe_new, it will
|
* return EINA_TRUE as long as you want the function to continue iterating,
|
||||||
* be correctly locked and unlocked. @p cb should return EINA_TRUE
|
* by returning EINA_FALSE it will stop and return EINA_FALSE as a result.
|
||||||
* as long as you want the function to continue iterating, by
|
|
||||||
* returning EINA_FALSE it will stop and return EINA_FALSE as a
|
|
||||||
* result.
|
|
||||||
*/
|
*/
|
||||||
static inline Eina_Bool
|
static inline Eina_Bool
|
||||||
eina_array_foreach(Eina_Array *array, Eina_Each_Cb cb, void *fdata)
|
eina_array_foreach(Eina_Array *array, Eina_Each_Cb cb, void *fdata)
|
||||||
|
@ -248,9 +163,6 @@ eina_array_foreach(Eina_Array *array, Eina_Each_Cb cb, void *fdata)
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
Eina_Bool ret = EINA_TRUE;
|
Eina_Bool ret = EINA_TRUE;
|
||||||
|
|
||||||
if (EINA_UNLIKELY(!eina_array_wrlock(array)))
|
|
||||||
return EINA_FALSE;
|
|
||||||
|
|
||||||
EINA_ARRAY_ITER_NEXT(array, i, data, iterator)
|
EINA_ARRAY_ITER_NEXT(array, i, data, iterator)
|
||||||
if (cb(array, data, fdata) != EINA_TRUE)
|
if (cb(array, data, fdata) != EINA_TRUE)
|
||||||
{
|
{
|
||||||
|
@ -258,8 +170,6 @@ eina_array_foreach(Eina_Array *array, Eina_Each_Cb cb, void *fdata)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
eina_array_unlock(array);
|
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -231,21 +231,6 @@ eina_array_iterator_free(Eina_Iterator_Array *it)
|
||||||
MAGIC_FREE(it);
|
MAGIC_FREE(it);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef EFL_HAVE_POSIX_THREADS_RWLOCK
|
|
||||||
static Eina_Bool
|
|
||||||
eina_array_iterator_lock(Eina_Iterator_Array *it)
|
|
||||||
{
|
|
||||||
EINA_MAGIC_CHECK_ARRAY_ITERATOR(it, EINA_FALSE);
|
|
||||||
return eina_array_wrlock((Eina_Array *) it->array);
|
|
||||||
}
|
|
||||||
|
|
||||||
static Eina_Bool
|
|
||||||
eina_array_iterator_unlock(Eina_Iterator_Array *it)
|
|
||||||
{
|
|
||||||
EINA_MAGIC_CHECK_ARRAY_ITERATOR(it, EINA_FALSE);
|
|
||||||
return eina_array_unlock(it->array);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
static Eina_Bool
|
static Eina_Bool
|
||||||
eina_array_accessor_get_at(Eina_Accessor_Array *it,
|
eina_array_accessor_get_at(Eina_Accessor_Array *it,
|
||||||
unsigned int idx,
|
unsigned int idx,
|
||||||
|
@ -276,21 +261,6 @@ eina_array_accessor_free(Eina_Accessor_Array *it)
|
||||||
MAGIC_FREE(it);
|
MAGIC_FREE(it);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef EFL_HAVE_POSIX_THREADS_RWLOCK
|
|
||||||
static Eina_Bool
|
|
||||||
eina_array_accessor_lock(Eina_Accessor_Array *it)
|
|
||||||
{
|
|
||||||
EINA_MAGIC_CHECK_ARRAY_ITERATOR(it, EINA_FALSE);
|
|
||||||
return eina_array_wrlock((Eina_Array *) it->array);
|
|
||||||
}
|
|
||||||
|
|
||||||
static Eina_Bool
|
|
||||||
eina_array_accessor_unlock(Eina_Accessor_Array *it)
|
|
||||||
{
|
|
||||||
EINA_MAGIC_CHECK_ARRAY_ITERATOR(it, EINA_FALSE);
|
|
||||||
return eina_array_unlock(it->array);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
EAPI Eina_Bool
|
EAPI Eina_Bool
|
||||||
eina_array_grow(Eina_Array *array)
|
eina_array_grow(Eina_Array *array)
|
||||||
{
|
{
|
||||||
|
@ -449,63 +419,10 @@ eina_array_new(unsigned int step)
|
||||||
array->total = 0;
|
array->total = 0;
|
||||||
array->count = 0;
|
array->count = 0;
|
||||||
array->step = step;
|
array->step = step;
|
||||||
#ifdef EINA_RWLOCKS_ENABLED
|
|
||||||
array->threadsafe = EINA_FALSE;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return array;
|
return array;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Create a new array that is threadsafe.
|
|
||||||
*
|
|
||||||
* @param step The count of pointers to add when increasing the array size.
|
|
||||||
* @return @c NULL on failure, non @c NULL otherwise.
|
|
||||||
*
|
|
||||||
* This function creates a new array which is different than a normal array.
|
|
||||||
* Arrays created with this function will automatically mutex themselves in eina_array_*
|
|
||||||
* function calls. In order to ensure that the created array operates successfully
|
|
||||||
* in a threadsafe environment, only EINA_ARRAY_THREADSAFE_* macros can be used with
|
|
||||||
* this type of list.
|
|
||||||
* When adding an element, the array allocates @p step elements. When that buffer is
|
|
||||||
* full, then adding another element will increase the buffer of @p step elements again.
|
|
||||||
*
|
|
||||||
* This function return a valid array on success, or @c NULL if memory
|
|
||||||
* allocation fails. In that case, the error is set to
|
|
||||||
* #EINA_ERROR_OUT_OF_MEMORY.
|
|
||||||
*/
|
|
||||||
EAPI Eina_Array *
|
|
||||||
eina_array_threadsafe_new(unsigned int step)
|
|
||||||
{
|
|
||||||
#ifdef EINA_RWLOCKS_ENABLED
|
|
||||||
Eina_Array *array;
|
|
||||||
|
|
||||||
eina_error_set(0);
|
|
||||||
array = malloc(sizeof (Eina_Array));
|
|
||||||
if (!array)
|
|
||||||
{
|
|
||||||
eina_error_set(EINA_ERROR_OUT_OF_MEMORY);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
EINA_MAGIC_SET(array, EINA_MAGIC_ARRAY);
|
|
||||||
|
|
||||||
array->data = NULL;
|
|
||||||
array->total = 0;
|
|
||||||
array->count = 0;
|
|
||||||
array->step = step;
|
|
||||||
|
|
||||||
pthread_rwlock_init(&array->lock, NULL);
|
|
||||||
array->threadsafe = EINA_TRUE;
|
|
||||||
|
|
||||||
return array;
|
|
||||||
#else
|
|
||||||
(void) step;
|
|
||||||
|
|
||||||
return NULL;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Free an array.
|
* @brief Free an array.
|
||||||
*
|
*
|
||||||
|
@ -523,13 +440,7 @@ eina_array_free(Eina_Array *array)
|
||||||
eina_array_flush(array);
|
eina_array_flush(array);
|
||||||
|
|
||||||
EINA_SAFETY_ON_NULL_RETURN(array);
|
EINA_SAFETY_ON_NULL_RETURN(array);
|
||||||
if (!eina_array_wrlock(array))
|
|
||||||
return;
|
|
||||||
EINA_MAGIC_CHECK_ARRAY(array);
|
EINA_MAGIC_CHECK_ARRAY(array);
|
||||||
#ifdef EINA_RWLOCKS_ENABLED
|
|
||||||
if (array->threadsafe)
|
|
||||||
pthread_rwlock_destroy(&array->lock);
|
|
||||||
#endif
|
|
||||||
MAGIC_FREE(array);
|
MAGIC_FREE(array);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -552,9 +463,6 @@ eina_array_step_set(Eina_Array *array, unsigned int step)
|
||||||
array->total = 0;
|
array->total = 0;
|
||||||
array->count = 0;
|
array->count = 0;
|
||||||
array->step = step;
|
array->step = step;
|
||||||
#ifdef EINA_RWLOCKS_ENABLED
|
|
||||||
array->threadsafe = EINA_FALSE;
|
|
||||||
#endif
|
|
||||||
EINA_MAGIC_SET(array, EINA_MAGIC_ARRAY);
|
EINA_MAGIC_SET(array, EINA_MAGIC_ARRAY);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -573,11 +481,7 @@ eina_array_clean(Eina_Array *array)
|
||||||
EINA_SAFETY_ON_NULL_RETURN(array);
|
EINA_SAFETY_ON_NULL_RETURN(array);
|
||||||
EINA_MAGIC_CHECK_ARRAY(array);
|
EINA_MAGIC_CHECK_ARRAY(array);
|
||||||
|
|
||||||
if (!eina_array_wrlock(array))
|
|
||||||
return;
|
|
||||||
|
|
||||||
array->count = 0;
|
array->count = 0;
|
||||||
eina_array_unlock(array);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -595,8 +499,7 @@ eina_array_flush(Eina_Array *array)
|
||||||
{
|
{
|
||||||
EINA_SAFETY_ON_NULL_RETURN(array);
|
EINA_SAFETY_ON_NULL_RETURN(array);
|
||||||
EINA_MAGIC_CHECK_ARRAY(array);
|
EINA_MAGIC_CHECK_ARRAY(array);
|
||||||
if (!eina_array_wrlock(array))
|
|
||||||
return;
|
|
||||||
array->count = 0;
|
array->count = 0;
|
||||||
array->total = 0;
|
array->total = 0;
|
||||||
|
|
||||||
|
@ -605,7 +508,6 @@ eina_array_flush(Eina_Array *array)
|
||||||
|
|
||||||
free(array->data);
|
free(array->data);
|
||||||
array->data = NULL;
|
array->data = NULL;
|
||||||
eina_array_unlock(array);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -642,8 +544,6 @@ eina_array_remove(Eina_Array *array, Eina_Bool (*keep)(void *data,
|
||||||
|
|
||||||
EINA_SAFETY_ON_NULL_RETURN_VAL(array, EINA_FALSE);
|
EINA_SAFETY_ON_NULL_RETURN_VAL(array, EINA_FALSE);
|
||||||
EINA_SAFETY_ON_NULL_RETURN_VAL(keep, EINA_FALSE);
|
EINA_SAFETY_ON_NULL_RETURN_VAL(keep, EINA_FALSE);
|
||||||
if (!eina_array_wrlock(array))
|
|
||||||
return EINA_FALSE;
|
|
||||||
EINA_MAGIC_CHECK_ARRAY(array);
|
EINA_MAGIC_CHECK_ARRAY(array);
|
||||||
|
|
||||||
if (array->total == 0)
|
if (array->total == 0)
|
||||||
|
@ -718,7 +618,6 @@ eina_array_remove(Eina_Array *array, Eina_Bool (*keep)(void *data,
|
||||||
|
|
||||||
array->data = tmp;
|
array->data = tmp;
|
||||||
array->count = total;
|
array->count = total;
|
||||||
eina_array_unlock(array);
|
|
||||||
return EINA_TRUE;
|
return EINA_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -760,14 +659,6 @@ eina_array_iterator_new(const Eina_Array *array)
|
||||||
eina_array_iterator_get_container);
|
eina_array_iterator_get_container);
|
||||||
it->iterator.free = FUNC_ITERATOR_FREE(eina_array_iterator_free);
|
it->iterator.free = FUNC_ITERATOR_FREE(eina_array_iterator_free);
|
||||||
|
|
||||||
#ifdef EFL_HAVE_POSIX_THREADS_RWLOCK
|
|
||||||
if (array->threadsafe)
|
|
||||||
{
|
|
||||||
it->iterator.lock = FUNC_ITERATOR_LOCK(eina_array_iterator_lock);
|
|
||||||
it->iterator.unlock = FUNC_ITERATOR_LOCK(eina_array_iterator_unlock);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return &it->iterator;
|
return &it->iterator;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -809,13 +700,6 @@ eina_array_accessor_new(const Eina_Array *array)
|
||||||
eina_array_accessor_get_container);
|
eina_array_accessor_get_container);
|
||||||
it->accessor.free = FUNC_ACCESSOR_FREE(eina_array_accessor_free);
|
it->accessor.free = FUNC_ACCESSOR_FREE(eina_array_accessor_free);
|
||||||
|
|
||||||
#ifdef EFL_HAVE_POSIX_THREADS_RWLOCK
|
|
||||||
if (array->threadsafe)
|
|
||||||
{
|
|
||||||
it->accessor.lock = FUNC_ACCESSOR_LOCK(eina_array_accessor_lock);
|
|
||||||
it->accessor.unlock = FUNC_ACCESSOR_LOCK(eina_array_accessor_unlock);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
return &it->accessor;
|
return &it->accessor;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -86,11 +86,6 @@ struct _Eina_Hash
|
||||||
|
|
||||||
int population;
|
int population;
|
||||||
|
|
||||||
#ifdef EFL_HAVE_POSIX_THREADS_RWLOCK
|
|
||||||
pthread_rwlock_t lock;
|
|
||||||
Eina_Bool threadsafe:1;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
EINA_MAGIC
|
EINA_MAGIC
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -154,71 +149,6 @@ struct _Eina_Hash_Each
|
||||||
+ (uint32_t)(((const uint8_t *)(d))[0]))
|
+ (uint32_t)(((const uint8_t *)(d))[0]))
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef EINA_RWLOCKS_ENABLED
|
|
||||||
static inline Eina_Bool
|
|
||||||
eina_hash_rdlock(const Eina_Hash *hash)
|
|
||||||
{
|
|
||||||
if (!hash) return EINA_FALSE;
|
|
||||||
if (hash->threadsafe)
|
|
||||||
{
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
ret = pthread_rwlock_rdlock(&((Eina_Hash*) hash)->lock);
|
|
||||||
if ((ret != 0) && (ret != EDEADLK))
|
|
||||||
return EINA_FALSE;
|
|
||||||
}
|
|
||||||
return EINA_TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline Eina_Bool
|
|
||||||
eina_hash_wrlock(Eina_Hash *hash)
|
|
||||||
{
|
|
||||||
if (!hash) return EINA_FALSE;
|
|
||||||
if (hash->threadsafe)
|
|
||||||
{
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
ret = pthread_rwlock_wrlock(&hash->lock);
|
|
||||||
if ((ret != 0) && (ret != EDEADLK))
|
|
||||||
return EINA_FALSE;
|
|
||||||
}
|
|
||||||
return EINA_TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline Eina_Bool
|
|
||||||
eina_hash_unlock(const Eina_Hash *hash)
|
|
||||||
{
|
|
||||||
if (!hash) return EINA_FALSE;
|
|
||||||
if (hash->threadsafe)
|
|
||||||
if (pthread_rwlock_unlock(&((Eina_Hash*) hash)->lock))
|
|
||||||
return EINA_FALSE;
|
|
||||||
return EINA_TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
static inline Eina_Bool
|
|
||||||
eina_hash_rdlock(const Eina_Hash *hash)
|
|
||||||
{
|
|
||||||
if (!hash) return EINA_FALSE;
|
|
||||||
return EINA_TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline Eina_Bool
|
|
||||||
eina_hash_wrlock(Eina_Hash *hash)
|
|
||||||
{
|
|
||||||
if (!hash) return EINA_FALSE;
|
|
||||||
return EINA_TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline Eina_Bool
|
|
||||||
eina_hash_unlock(const Eina_Hash *hash)
|
|
||||||
{
|
|
||||||
if (!hash) return EINA_FALSE;
|
|
||||||
return EINA_TRUE;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static inline int
|
static inline int
|
||||||
_eina_hash_hash_rbtree_cmp_hash(const Eina_Hash_Head *hash_head,
|
_eina_hash_hash_rbtree_cmp_hash(const Eina_Hash_Head *hash_head,
|
||||||
const int *hash,
|
const int *hash,
|
||||||
|
@ -760,22 +690,6 @@ _eina_hash_iterator_free(Eina_Iterator_Hash *it)
|
||||||
free(it);
|
free(it);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef EFL_HAVE_POSIX_THREADS_RWLOCK
|
|
||||||
static Eina_Bool
|
|
||||||
_eina_hash_iterator_lock(Eina_Iterator_Hash *it)
|
|
||||||
{
|
|
||||||
EINA_MAGIC_CHECK_HASH_ITERATOR(it, EINA_FALSE);
|
|
||||||
return eina_hash_wrlock((Eina_Hash*)it->hash);
|
|
||||||
}
|
|
||||||
|
|
||||||
static Eina_Bool
|
|
||||||
_eina_hash_iterator_unlock(Eina_Iterator_Hash *it)
|
|
||||||
{
|
|
||||||
EINA_MAGIC_CHECK_HASH_ITERATOR(it, EINA_FALSE);
|
|
||||||
return eina_hash_unlock((Eina_Hash*)it->hash);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @endcond
|
* @endcond
|
||||||
*/
|
*/
|
||||||
|
@ -839,9 +753,6 @@ eina_hash_new(Eina_Key_Length key_length_cb,
|
||||||
new->data_free_cb = data_free_cb;
|
new->data_free_cb = data_free_cb;
|
||||||
new->buckets = NULL;
|
new->buckets = NULL;
|
||||||
new->population = 0;
|
new->population = 0;
|
||||||
#ifdef EFL_HAVE_POSIX_THREADS_RWLOCK
|
|
||||||
new->threadsafe = EINA_FALSE;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
new->size = 1 << buckets_power_size;
|
new->size = 1 << buckets_power_size;
|
||||||
new->mask = new->size - 1;
|
new->mask = new->size - 1;
|
||||||
|
@ -1050,18 +961,12 @@ eina_hash_free(Eina_Hash *hash)
|
||||||
EINA_MAGIC_CHECK_HASH(hash);
|
EINA_MAGIC_CHECK_HASH(hash);
|
||||||
EINA_SAFETY_ON_NULL_RETURN(hash);
|
EINA_SAFETY_ON_NULL_RETURN(hash);
|
||||||
|
|
||||||
if (!eina_hash_wrlock(hash))
|
|
||||||
return;
|
|
||||||
if (hash->buckets)
|
if (hash->buckets)
|
||||||
{
|
{
|
||||||
for (i = 0; i < hash->size; i++)
|
for (i = 0; i < hash->size; i++)
|
||||||
eina_rbtree_delete(hash->buckets[i], EINA_RBTREE_FREE_CB(_eina_hash_head_free), hash);
|
eina_rbtree_delete(hash->buckets[i], EINA_RBTREE_FREE_CB(_eina_hash_head_free), hash);
|
||||||
free(hash->buckets);
|
free(hash->buckets);
|
||||||
}
|
}
|
||||||
#ifdef EFL_HAVE_POSIX_THREADS_RWLOCK
|
|
||||||
if (hash->threadsafe)
|
|
||||||
pthread_rwlock_destroy(&hash->lock);
|
|
||||||
#endif
|
|
||||||
free(hash);
|
free(hash);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1082,8 +987,6 @@ eina_hash_free_buckets(Eina_Hash *hash)
|
||||||
EINA_MAGIC_CHECK_HASH(hash);
|
EINA_MAGIC_CHECK_HASH(hash);
|
||||||
EINA_SAFETY_ON_NULL_RETURN(hash);
|
EINA_SAFETY_ON_NULL_RETURN(hash);
|
||||||
|
|
||||||
if (!eina_hash_wrlock(hash))
|
|
||||||
return;
|
|
||||||
if (hash->buckets)
|
if (hash->buckets)
|
||||||
{
|
{
|
||||||
for (i = 0; i < hash->size; i++)
|
for (i = 0; i < hash->size; i++)
|
||||||
|
@ -1093,7 +996,6 @@ eina_hash_free_buckets(Eina_Hash *hash)
|
||||||
hash->buckets = NULL;
|
hash->buckets = NULL;
|
||||||
hash->population = 0;
|
hash->population = 0;
|
||||||
}
|
}
|
||||||
eina_hash_unlock(hash);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1125,18 +1027,12 @@ eina_hash_add_by_hash(Eina_Hash *hash,
|
||||||
const void *key, int key_length, int key_hash,
|
const void *key, int key_length, int key_hash,
|
||||||
const void *data)
|
const void *data)
|
||||||
{
|
{
|
||||||
Eina_Bool ret;
|
return eina_hash_add_alloc_by_hash(hash,
|
||||||
if (!eina_hash_wrlock(hash))
|
key,
|
||||||
return EINA_FALSE;
|
|
||||||
|
|
||||||
ret = eina_hash_add_alloc_by_hash(hash,
|
|
||||||
key,
|
|
||||||
key_length,
|
key_length,
|
||||||
key_length,
|
key_length,
|
||||||
key_hash,
|
key_hash,
|
||||||
data);
|
data);
|
||||||
eina_hash_unlock(hash);
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1169,13 +1065,7 @@ eina_hash_direct_add_by_hash(Eina_Hash *hash,
|
||||||
const void *key, int key_length, int key_hash,
|
const void *key, int key_length, int key_hash,
|
||||||
const void *data)
|
const void *data)
|
||||||
{
|
{
|
||||||
Eina_Bool ret;
|
return eina_hash_add_alloc_by_hash(hash, key, key_length, 0, key_hash, data);
|
||||||
if (!eina_hash_wrlock(hash))
|
|
||||||
return EINA_FALSE;
|
|
||||||
|
|
||||||
ret = eina_hash_add_alloc_by_hash(hash, key, key_length, 0, key_hash, data);
|
|
||||||
eina_hash_unlock(hash);
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1204,7 +1094,6 @@ eina_hash_add(Eina_Hash *hash, const void *key, const void *data)
|
||||||
{
|
{
|
||||||
unsigned int key_length;
|
unsigned int key_length;
|
||||||
int key_hash;
|
int key_hash;
|
||||||
Eina_Bool ret;
|
|
||||||
|
|
||||||
EINA_MAGIC_CHECK_HASH(hash);
|
EINA_MAGIC_CHECK_HASH(hash);
|
||||||
EINA_SAFETY_ON_NULL_RETURN_VAL(hash, EINA_FALSE);
|
EINA_SAFETY_ON_NULL_RETURN_VAL(hash, EINA_FALSE);
|
||||||
|
@ -1212,15 +1101,10 @@ eina_hash_add(Eina_Hash *hash, const void *key, const void *data)
|
||||||
EINA_SAFETY_ON_NULL_RETURN_VAL(key, EINA_FALSE);
|
EINA_SAFETY_ON_NULL_RETURN_VAL(key, EINA_FALSE);
|
||||||
EINA_SAFETY_ON_NULL_RETURN_VAL(data, EINA_FALSE);
|
EINA_SAFETY_ON_NULL_RETURN_VAL(data, EINA_FALSE);
|
||||||
|
|
||||||
if (!eina_hash_wrlock(hash))
|
|
||||||
return EINA_FALSE;
|
|
||||||
|
|
||||||
key_length = hash->key_length_cb ? hash->key_length_cb(key) : 0;
|
key_length = hash->key_length_cb ? hash->key_length_cb(key) : 0;
|
||||||
key_hash = hash->key_hash_cb(key, key_length);
|
key_hash = hash->key_hash_cb(key, key_length);
|
||||||
|
|
||||||
ret = eina_hash_add_alloc_by_hash(hash, key, key_length, key_length, key_hash, data);
|
return eina_hash_add_alloc_by_hash(hash, key, key_length, key_length, key_hash, data);
|
||||||
eina_hash_unlock(hash);
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1251,7 +1135,6 @@ eina_hash_direct_add(Eina_Hash *hash, const void *key, const void *data)
|
||||||
{
|
{
|
||||||
int key_length;
|
int key_length;
|
||||||
int key_hash;
|
int key_hash;
|
||||||
Eina_Bool ret;
|
|
||||||
|
|
||||||
EINA_SAFETY_ON_NULL_RETURN_VAL(hash, EINA_FALSE);
|
EINA_SAFETY_ON_NULL_RETURN_VAL(hash, EINA_FALSE);
|
||||||
EINA_SAFETY_ON_NULL_RETURN_VAL(hash->key_hash_cb, EINA_FALSE);
|
EINA_SAFETY_ON_NULL_RETURN_VAL(hash->key_hash_cb, EINA_FALSE);
|
||||||
|
@ -1259,15 +1142,10 @@ eina_hash_direct_add(Eina_Hash *hash, const void *key, const void *data)
|
||||||
EINA_SAFETY_ON_NULL_RETURN_VAL(data, EINA_FALSE);
|
EINA_SAFETY_ON_NULL_RETURN_VAL(data, EINA_FALSE);
|
||||||
EINA_MAGIC_CHECK_HASH(hash);
|
EINA_MAGIC_CHECK_HASH(hash);
|
||||||
|
|
||||||
if (!eina_hash_wrlock(hash))
|
|
||||||
return EINA_FALSE;
|
|
||||||
|
|
||||||
key_length = hash->key_length_cb ? hash->key_length_cb(key) : 0;
|
key_length = hash->key_length_cb ? hash->key_length_cb(key) : 0;
|
||||||
key_hash = hash->key_hash_cb(key, key_length);
|
key_hash = hash->key_hash_cb(key, key_length);
|
||||||
|
|
||||||
ret = eina_hash_add_alloc_by_hash(hash, key, key_length, 0, key_hash, data);
|
return eina_hash_add_alloc_by_hash(hash, key, key_length, 0, key_hash, data);
|
||||||
eina_hash_unlock(hash);
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1292,16 +1170,10 @@ eina_hash_del_by_key_hash(Eina_Hash *hash,
|
||||||
int key_length,
|
int key_length,
|
||||||
int key_hash)
|
int key_hash)
|
||||||
{
|
{
|
||||||
Eina_Bool ret;
|
|
||||||
EINA_SAFETY_ON_NULL_RETURN_VAL(hash, EINA_FALSE);
|
EINA_SAFETY_ON_NULL_RETURN_VAL(hash, EINA_FALSE);
|
||||||
EINA_SAFETY_ON_NULL_RETURN_VAL(key, EINA_FALSE);
|
EINA_SAFETY_ON_NULL_RETURN_VAL(key, EINA_FALSE);
|
||||||
|
|
||||||
if (!eina_hash_wrlock(hash))
|
return _eina_hash_del_by_key_hash(hash, key, key_length, key_hash, NULL);
|
||||||
return EINA_FALSE;
|
|
||||||
ret = _eina_hash_del_by_key_hash(hash, key, key_length, key_hash, NULL);
|
|
||||||
|
|
||||||
eina_hash_unlock(hash);
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1323,15 +1195,10 @@ eina_hash_del_by_key_hash(Eina_Hash *hash,
|
||||||
EAPI Eina_Bool
|
EAPI Eina_Bool
|
||||||
eina_hash_del_by_key(Eina_Hash *hash, const void *key)
|
eina_hash_del_by_key(Eina_Hash *hash, const void *key)
|
||||||
{
|
{
|
||||||
Eina_Bool ret;
|
|
||||||
EINA_SAFETY_ON_NULL_RETURN_VAL(hash, EINA_FALSE);
|
EINA_SAFETY_ON_NULL_RETURN_VAL(hash, EINA_FALSE);
|
||||||
EINA_SAFETY_ON_NULL_RETURN_VAL(key, EINA_FALSE);
|
EINA_SAFETY_ON_NULL_RETURN_VAL(key, EINA_FALSE);
|
||||||
|
|
||||||
if (!eina_hash_wrlock(hash))
|
return _eina_hash_del_by_key(hash, key, NULL);
|
||||||
return EINA_FALSE;
|
|
||||||
ret = _eina_hash_del_by_key(hash, key, NULL);
|
|
||||||
eina_hash_unlock(hash);
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1351,7 +1218,6 @@ eina_hash_del_by_key(Eina_Hash *hash, const void *key)
|
||||||
EAPI Eina_Bool
|
EAPI Eina_Bool
|
||||||
eina_hash_del_by_data(Eina_Hash *hash, const void *data)
|
eina_hash_del_by_data(Eina_Hash *hash, const void *data)
|
||||||
{
|
{
|
||||||
Eina_Bool ret = EINA_FALSE;
|
|
||||||
Eina_Hash_Element *hash_element;
|
Eina_Hash_Element *hash_element;
|
||||||
Eina_Hash_Head *hash_head;
|
Eina_Hash_Head *hash_head;
|
||||||
int key_hash;
|
int key_hash;
|
||||||
|
@ -1360,9 +1226,6 @@ eina_hash_del_by_data(Eina_Hash *hash, const void *data)
|
||||||
EINA_SAFETY_ON_NULL_RETURN_VAL(data, EINA_FALSE);
|
EINA_SAFETY_ON_NULL_RETURN_VAL(data, EINA_FALSE);
|
||||||
EINA_MAGIC_CHECK_HASH(hash);
|
EINA_MAGIC_CHECK_HASH(hash);
|
||||||
|
|
||||||
if (!eina_hash_wrlock(hash))
|
|
||||||
return EINA_FALSE;
|
|
||||||
|
|
||||||
hash_element = _eina_hash_find_by_data(hash, data, &key_hash, &hash_head);
|
hash_element = _eina_hash_find_by_data(hash, data, &key_hash, &hash_head);
|
||||||
if (!hash_element)
|
if (!hash_element)
|
||||||
goto error;
|
goto error;
|
||||||
|
@ -1370,11 +1233,10 @@ eina_hash_del_by_data(Eina_Hash *hash, const void *data)
|
||||||
if (hash_element->tuple.data != data)
|
if (hash_element->tuple.data != data)
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
ret = _eina_hash_del_by_hash_el(hash, hash_element, hash_head, key_hash);
|
return _eina_hash_del_by_hash_el(hash, hash_element, hash_head, key_hash);
|
||||||
|
|
||||||
error:
|
error:
|
||||||
eina_hash_unlock(hash);
|
return EINA_FALSE;
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1407,17 +1269,15 @@ eina_hash_del_by_hash(Eina_Hash *hash,
|
||||||
const void *data)
|
const void *data)
|
||||||
{
|
{
|
||||||
Eina_Bool ret;
|
Eina_Bool ret;
|
||||||
|
|
||||||
EINA_SAFETY_ON_NULL_RETURN_VAL(hash, EINA_FALSE);
|
EINA_SAFETY_ON_NULL_RETURN_VAL(hash, EINA_FALSE);
|
||||||
EINA_MAGIC_CHECK_HASH(hash);
|
EINA_MAGIC_CHECK_HASH(hash);
|
||||||
|
|
||||||
if (!eina_hash_wrlock(hash))
|
|
||||||
return EINA_FALSE;
|
|
||||||
|
|
||||||
if (key)
|
if (key)
|
||||||
ret = _eina_hash_del_by_key_hash(hash, key, key_length, key_hash, data);
|
ret = _eina_hash_del_by_key_hash(hash, key, key_length, key_hash, data);
|
||||||
else
|
else
|
||||||
ret = eina_hash_del_by_data(hash, data);
|
ret = eina_hash_del_by_data(hash, data);
|
||||||
eina_hash_unlock(hash);
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1445,19 +1305,13 @@ eina_hash_del_by_hash(Eina_Hash *hash,
|
||||||
EAPI Eina_Bool
|
EAPI Eina_Bool
|
||||||
eina_hash_del(Eina_Hash *hash, const void *key, const void *data)
|
eina_hash_del(Eina_Hash *hash, const void *key, const void *data)
|
||||||
{
|
{
|
||||||
Eina_Bool ret;
|
|
||||||
EINA_SAFETY_ON_NULL_RETURN_VAL(hash, EINA_FALSE);
|
EINA_SAFETY_ON_NULL_RETURN_VAL(hash, EINA_FALSE);
|
||||||
EINA_MAGIC_CHECK_HASH(hash);
|
EINA_MAGIC_CHECK_HASH(hash);
|
||||||
|
|
||||||
if (!key)
|
if (!key)
|
||||||
return eina_hash_del_by_data(hash, data);
|
return eina_hash_del_by_data(hash, data);
|
||||||
|
|
||||||
if (!eina_hash_wrlock(hash))
|
return _eina_hash_del_by_key(hash, key, data);
|
||||||
return EINA_FALSE;
|
|
||||||
|
|
||||||
ret = _eina_hash_del_by_key(hash, key, data);
|
|
||||||
eina_hash_unlock(hash);
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1489,11 +1343,7 @@ eina_hash_find_by_hash(const Eina_Hash *hash,
|
||||||
tuple.key_length = key_length;
|
tuple.key_length = key_length;
|
||||||
tuple.data = NULL;
|
tuple.data = NULL;
|
||||||
|
|
||||||
if (!eina_hash_rdlock(hash))
|
|
||||||
return NULL;;
|
|
||||||
|
|
||||||
hash_element = _eina_hash_find_by_hash(hash, &tuple, key_hash, &hash_head);
|
hash_element = _eina_hash_find_by_hash(hash, &tuple, key_hash, &hash_head);
|
||||||
eina_hash_unlock(hash);
|
|
||||||
if (hash_element)
|
if (hash_element)
|
||||||
return hash_element->tuple.data;
|
return hash_element->tuple.data;
|
||||||
|
|
||||||
|
@ -1520,9 +1370,6 @@ eina_hash_find(const Eina_Hash *hash, const void *key)
|
||||||
EINA_SAFETY_ON_NULL_RETURN_VAL(key, NULL);
|
EINA_SAFETY_ON_NULL_RETURN_VAL(key, NULL);
|
||||||
EINA_MAGIC_CHECK_HASH(hash);
|
EINA_MAGIC_CHECK_HASH(hash);
|
||||||
|
|
||||||
if (!eina_hash_rdlock(hash))
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
key_length = hash->key_length_cb ? hash->key_length_cb(key) : 0;
|
key_length = hash->key_length_cb ? hash->key_length_cb(key) : 0;
|
||||||
hash_num = hash->key_hash_cb(key, key_length);
|
hash_num = hash->key_hash_cb(key, key_length);
|
||||||
|
|
||||||
|
@ -1561,9 +1408,6 @@ eina_hash_modify_by_hash(Eina_Hash *hash,
|
||||||
tuple.key_length = key_length;
|
tuple.key_length = key_length;
|
||||||
tuple.data = NULL;
|
tuple.data = NULL;
|
||||||
|
|
||||||
if (!eina_hash_rdlock(hash))
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
hash_element = _eina_hash_find_by_hash(hash, &tuple, key_hash, &hash_head);
|
hash_element = _eina_hash_find_by_hash(hash, &tuple, key_hash, &hash_head);
|
||||||
if (hash_element)
|
if (hash_element)
|
||||||
{
|
{
|
||||||
|
@ -1571,7 +1415,6 @@ eina_hash_modify_by_hash(Eina_Hash *hash,
|
||||||
hash_element->tuple.data = (void *)data;
|
hash_element->tuple.data = (void *)data;
|
||||||
}
|
}
|
||||||
|
|
||||||
eina_hash_unlock(hash);
|
|
||||||
return old_data;
|
return old_data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1602,9 +1445,6 @@ eina_hash_set(Eina_Hash *hash, const void *key, const void *data)
|
||||||
EINA_SAFETY_ON_NULL_RETURN_VAL(data, NULL);
|
EINA_SAFETY_ON_NULL_RETURN_VAL(data, NULL);
|
||||||
EINA_MAGIC_CHECK_HASH(hash);
|
EINA_MAGIC_CHECK_HASH(hash);
|
||||||
|
|
||||||
if (!eina_hash_wrlock(hash))
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
key_length = hash->key_length_cb ? hash->key_length_cb(key) : 0;
|
key_length = hash->key_length_cb ? hash->key_length_cb(key) : 0;
|
||||||
key_hash = hash->key_hash_cb(key, key_length);
|
key_hash = hash->key_hash_cb(key, key_length);
|
||||||
|
|
||||||
|
@ -1619,7 +1459,6 @@ eina_hash_set(Eina_Hash *hash, const void *key, const void *data)
|
||||||
|
|
||||||
old_data = hash_element->tuple.data;
|
old_data = hash_element->tuple.data;
|
||||||
hash_element->tuple.data = (void *)data;
|
hash_element->tuple.data = (void *)data;
|
||||||
eina_hash_unlock(hash);
|
|
||||||
return old_data;
|
return old_data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1652,9 +1491,6 @@ eina_hash_modify(Eina_Hash *hash, const void *key, const void *data)
|
||||||
EINA_SAFETY_ON_NULL_RETURN_VAL(data, NULL);
|
EINA_SAFETY_ON_NULL_RETURN_VAL(data, NULL);
|
||||||
EINA_MAGIC_CHECK_HASH(hash);
|
EINA_MAGIC_CHECK_HASH(hash);
|
||||||
|
|
||||||
if (!eina_hash_wrlock(hash))
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
key_length = hash->key_length_cb ? hash->key_length_cb(key) : 0;
|
key_length = hash->key_length_cb ? hash->key_length_cb(key) : 0;
|
||||||
hash_num = hash->key_hash_cb(key, key_length);
|
hash_num = hash->key_hash_cb(key, key_length);
|
||||||
|
|
||||||
|
@ -1684,11 +1520,7 @@ eina_hash_move(Eina_Hash *hash, const void *old_key, const void *new_key)
|
||||||
EINA_SAFETY_ON_NULL_RETURN_VAL(new_key, EINA_FALSE);
|
EINA_SAFETY_ON_NULL_RETURN_VAL(new_key, EINA_FALSE);
|
||||||
EINA_MAGIC_CHECK_HASH(hash);
|
EINA_MAGIC_CHECK_HASH(hash);
|
||||||
|
|
||||||
if (!eina_hash_wrlock(hash))
|
|
||||||
return EINA_FALSE;
|
|
||||||
|
|
||||||
data = eina_hash_find(hash, old_key);
|
data = eina_hash_find(hash, old_key);
|
||||||
|
|
||||||
if (!data) goto error;
|
if (!data) goto error;
|
||||||
|
|
||||||
hash_free_cb = hash->data_free_cb;
|
hash_free_cb = hash->data_free_cb;
|
||||||
|
@ -1700,7 +1532,6 @@ eina_hash_move(Eina_Hash *hash, const void *old_key, const void *new_key)
|
||||||
hash->data_free_cb = hash_free_cb;
|
hash->data_free_cb = hash_free_cb;
|
||||||
|
|
||||||
error:
|
error:
|
||||||
eina_hash_unlock(hash);
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1805,13 +1636,7 @@ eina_hash_iterator_data_new(const Eina_Hash *hash)
|
||||||
it->iterator.get_container = FUNC_ITERATOR_GET_CONTAINER(
|
it->iterator.get_container = FUNC_ITERATOR_GET_CONTAINER(
|
||||||
_eina_hash_iterator_get_container);
|
_eina_hash_iterator_get_container);
|
||||||
it->iterator.free = FUNC_ITERATOR_FREE(_eina_hash_iterator_free);
|
it->iterator.free = FUNC_ITERATOR_FREE(_eina_hash_iterator_free);
|
||||||
#ifdef EFL_HAVE_POSIX_THREADS_RWLOCK
|
|
||||||
if (hash->threadsafe)
|
|
||||||
{
|
|
||||||
it->iterator.lock = (Eina_Iterator_Lock_Callback)_eina_hash_iterator_lock;
|
|
||||||
it->iterator.unlock = (Eina_Iterator_Lock_Callback)_eina_hash_iterator_unlock;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
EINA_MAGIC_SET(&it->iterator, EINA_MAGIC_ITERATOR);
|
EINA_MAGIC_SET(&it->iterator, EINA_MAGIC_ITERATOR);
|
||||||
EINA_MAGIC_SET(it, EINA_MAGIC_HASH_ITERATOR);
|
EINA_MAGIC_SET(it, EINA_MAGIC_HASH_ITERATOR);
|
||||||
|
|
||||||
|
@ -1857,13 +1682,6 @@ eina_hash_iterator_key_new(const Eina_Hash *hash)
|
||||||
it->get_content = FUNC_ITERATOR_GET_CONTENT(
|
it->get_content = FUNC_ITERATOR_GET_CONTENT(
|
||||||
_eina_hash_iterator_key_get_content);
|
_eina_hash_iterator_key_get_content);
|
||||||
|
|
||||||
#ifdef EFL_HAVE_POSIX_THREADS_RWLOCK
|
|
||||||
if (hash->threadsafe)
|
|
||||||
{
|
|
||||||
it->iterator.lock = (Eina_Iterator_Lock_Callback)_eina_hash_iterator_lock;
|
|
||||||
it->iterator.unlock = (Eina_Iterator_Lock_Callback)_eina_hash_iterator_unlock;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
it->iterator.next = FUNC_ITERATOR_NEXT(_eina_hash_iterator_next);
|
it->iterator.next = FUNC_ITERATOR_NEXT(_eina_hash_iterator_next);
|
||||||
it->iterator.get_container = FUNC_ITERATOR_GET_CONTAINER(
|
it->iterator.get_container = FUNC_ITERATOR_GET_CONTAINER(
|
||||||
_eina_hash_iterator_get_container);
|
_eina_hash_iterator_get_container);
|
||||||
|
@ -1918,14 +1736,6 @@ eina_hash_iterator_tuple_new(const Eina_Hash *hash)
|
||||||
it->get_content = FUNC_ITERATOR_GET_CONTENT(
|
it->get_content = FUNC_ITERATOR_GET_CONTENT(
|
||||||
_eina_hash_iterator_tuple_get_content);
|
_eina_hash_iterator_tuple_get_content);
|
||||||
|
|
||||||
#ifdef EFL_HAVE_POSIX_THREADS_RWLOCK
|
|
||||||
if (hash->threadsafe)
|
|
||||||
{
|
|
||||||
it->iterator.lock = (Eina_Iterator_Lock_Callback)_eina_hash_iterator_lock;
|
|
||||||
it->iterator.unlock = (Eina_Iterator_Lock_Callback)_eina_hash_iterator_unlock;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
it->iterator.next = FUNC_ITERATOR_NEXT(_eina_hash_iterator_next);
|
it->iterator.next = FUNC_ITERATOR_NEXT(_eina_hash_iterator_next);
|
||||||
it->iterator.get_container = FUNC_ITERATOR_GET_CONTAINER(
|
it->iterator.get_container = FUNC_ITERATOR_GET_CONTAINER(
|
||||||
_eina_hash_iterator_get_container);
|
_eina_hash_iterator_get_container);
|
||||||
|
@ -1993,147 +1803,6 @@ eina_hash_superfast(const char *key, int len)
|
||||||
return hash;
|
return hash;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* *************************************************
|
|
||||||
* THREADSAFE
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @addtogroup Eina_Hash_Threadsafe_Group Threadsafe Hash
|
|
||||||
* @brief This hash will automatically lock itself upon being accessed, and is safe to use without mutexes in threads.
|
|
||||||
* Threadsafe hash types are identical to regular hash types except that they will always mutex themselves properly upon being accessed
|
|
||||||
* to prevent pointer collision when using the same hash in multiple threads. They function in exactly the same manner as a regular
|
|
||||||
* hash table, and regular api functions will automatically lock threadsafe hashes.
|
|
||||||
*
|
|
||||||
* All threadsafe api functions have identical arguments to regular api functions.
|
|
||||||
* @{
|
|
||||||
*/
|
|
||||||
EAPI Eina_Hash *
|
|
||||||
eina_hash_threadsafe_new(__UNUSED__ Eina_Key_Length key_length_cb,
|
|
||||||
__UNUSED__ Eina_Key_Cmp key_cmp_cb,
|
|
||||||
__UNUSED__ Eina_Key_Hash key_hash_cb,
|
|
||||||
__UNUSED__ Eina_Free_Cb data_free_cb,
|
|
||||||
__UNUSED__ int buckets_power_size)
|
|
||||||
{
|
|
||||||
#ifdef EFL_HAVE_POSIX_THREADS_RWLOCK
|
|
||||||
/* FIXME: Use mempool. */
|
|
||||||
Eina_Hash *new;
|
|
||||||
|
|
||||||
if (!(new = eina_hash_new(key_length_cb, key_cmp_cb, key_hash_cb, data_free_cb, buckets_power_size)))
|
|
||||||
return NULL;
|
|
||||||
new->threadsafe = EINA_TRUE;
|
|
||||||
if (pthread_rwlock_init(&new->lock, NULL))
|
|
||||||
{
|
|
||||||
free(new);
|
|
||||||
goto on_error;
|
|
||||||
}
|
|
||||||
|
|
||||||
return new;
|
|
||||||
|
|
||||||
on_error:
|
|
||||||
eina_error_set(EINA_ERROR_OUT_OF_MEMORY);
|
|
||||||
#endif
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @see eina_hash_string_djb2_new
|
|
||||||
*/
|
|
||||||
EAPI Eina_Hash *
|
|
||||||
eina_hash_threadsafe_string_djb2_new(Eina_Free_Cb data_free_cb)
|
|
||||||
{
|
|
||||||
return eina_hash_new(EINA_KEY_LENGTH(_eina_string_key_length),
|
|
||||||
EINA_KEY_CMP(_eina_string_key_cmp),
|
|
||||||
EINA_KEY_HASH(eina_hash_djb2),
|
|
||||||
data_free_cb,
|
|
||||||
EINA_HASH_BUCKET_SIZE);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief
|
|
||||||
* @see eina_hash_string_superfast_new
|
|
||||||
*/
|
|
||||||
EAPI Eina_Hash *
|
|
||||||
eina_hash_threadsafe_string_superfast_new(Eina_Free_Cb data_free_cb)
|
|
||||||
{
|
|
||||||
return eina_hash_new(EINA_KEY_LENGTH(_eina_string_key_length),
|
|
||||||
EINA_KEY_CMP(_eina_string_key_cmp),
|
|
||||||
EINA_KEY_HASH(eina_hash_superfast),
|
|
||||||
data_free_cb,
|
|
||||||
EINA_HASH_BUCKET_SIZE);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @see eina_hash_string_small_new
|
|
||||||
*/
|
|
||||||
EAPI Eina_Hash *
|
|
||||||
eina_hash_threadsafe_string_small_new(Eina_Free_Cb data_free_cb)
|
|
||||||
{
|
|
||||||
return eina_hash_new(EINA_KEY_LENGTH(_eina_string_key_length),
|
|
||||||
EINA_KEY_CMP(_eina_string_key_cmp),
|
|
||||||
EINA_KEY_HASH(eina_hash_superfast),
|
|
||||||
data_free_cb,
|
|
||||||
EINA_HASH_SMALL_BUCKET_SIZE);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @see eina_hash_int32_new
|
|
||||||
*/
|
|
||||||
EAPI Eina_Hash *
|
|
||||||
eina_hash_threadsafe_int32_new(Eina_Free_Cb data_free_cb)
|
|
||||||
{
|
|
||||||
return eina_hash_new(EINA_KEY_LENGTH(_eina_int32_key_length),
|
|
||||||
EINA_KEY_CMP(_eina_int32_key_cmp),
|
|
||||||
EINA_KEY_HASH(eina_hash_int32),
|
|
||||||
data_free_cb,
|
|
||||||
EINA_HASH_BUCKET_SIZE);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @see eina_hash_int64_new
|
|
||||||
*/
|
|
||||||
EAPI Eina_Hash *
|
|
||||||
eina_hash_threadsafe_int64_new(Eina_Free_Cb data_free_cb)
|
|
||||||
{
|
|
||||||
return eina_hash_new(EINA_KEY_LENGTH(_eina_int64_key_length),
|
|
||||||
EINA_KEY_CMP(_eina_int64_key_cmp),
|
|
||||||
EINA_KEY_HASH(eina_hash_int64),
|
|
||||||
data_free_cb,
|
|
||||||
EINA_HASH_BUCKET_SIZE);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @see eina_hash_pointer_new
|
|
||||||
*/
|
|
||||||
EAPI Eina_Hash *
|
|
||||||
eina_hash_threadsafe_pointer_new(Eina_Free_Cb data_free_cb)
|
|
||||||
{
|
|
||||||
#ifdef __LP64__
|
|
||||||
return eina_hash_new(EINA_KEY_LENGTH(_eina_int64_key_length),
|
|
||||||
EINA_KEY_CMP(_eina_int64_key_cmp),
|
|
||||||
EINA_KEY_HASH(eina_hash_int64),
|
|
||||||
data_free_cb,
|
|
||||||
EINA_HASH_BUCKET_SIZE);
|
|
||||||
#else
|
|
||||||
return eina_hash_new(EINA_KEY_LENGTH(_eina_int32_key_length),
|
|
||||||
EINA_KEY_CMP(_eina_int32_key_cmp),
|
|
||||||
EINA_KEY_HASH(eina_hash_int32),
|
|
||||||
data_free_cb,
|
|
||||||
EINA_HASH_BUCKET_SIZE);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* @see eina_hash_stringshared_new
|
|
||||||
*/
|
|
||||||
EAPI Eina_Hash *
|
|
||||||
eina_hash_threadsafe_stringshared_new(Eina_Free_Cb data_free_cb)
|
|
||||||
{
|
|
||||||
return eina_hash_new(NULL,
|
|
||||||
EINA_KEY_CMP(_eina_stringshared_key_cmp),
|
|
||||||
EINA_KEY_HASH(eina_hash_superfast),
|
|
||||||
data_free_cb,
|
|
||||||
EINA_HASH_BUCKET_SIZE);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @}
|
* @}
|
||||||
* @}
|
* @}
|
||||||
|
|
|
@ -69,60 +69,6 @@ START_TEST(eina_array_simple)
|
||||||
}
|
}
|
||||||
END_TEST
|
END_TEST
|
||||||
|
|
||||||
#ifdef EINA_RWLOCKS_ENABLED
|
|
||||||
static Eina_Bool
|
|
||||||
_eina_array_clean(Eina_Array *ea, char *tmp, unsigned int *i)
|
|
||||||
{
|
|
||||||
fail_if(!ea);
|
|
||||||
fail_if((unsigned int)atoi(tmp) != *i);
|
|
||||||
free(tmp);
|
|
||||||
|
|
||||||
(*i)++;
|
|
||||||
|
|
||||||
return EINA_TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
START_TEST(eina_array_threadsafe)
|
|
||||||
{
|
|
||||||
Eina_Array *ea;
|
|
||||||
char *tmp;
|
|
||||||
unsigned int i;
|
|
||||||
|
|
||||||
eina_init();
|
|
||||||
|
|
||||||
ea = eina_array_threadsafe_new(11);
|
|
||||||
fail_if(!ea);
|
|
||||||
|
|
||||||
for (i = 0; i < 201; ++i)
|
|
||||||
{
|
|
||||||
tmp = malloc(sizeof(char) * 10);
|
|
||||||
fail_if(!tmp);
|
|
||||||
eina_convert_itoa(i, tmp);
|
|
||||||
|
|
||||||
eina_array_push(ea, tmp);
|
|
||||||
}
|
|
||||||
|
|
||||||
fail_if(eina_array_data_get(ea, 10) == NULL);
|
|
||||||
fail_if(atoi(eina_array_data_get(ea, 10)) != 10);
|
|
||||||
tmp = eina_array_pop(ea);
|
|
||||||
fail_if(tmp == NULL);
|
|
||||||
fail_if(atoi(tmp) != 200);
|
|
||||||
free(tmp);
|
|
||||||
|
|
||||||
i = 0;
|
|
||||||
eina_array_foreach(ea, EINA_EACH_CB(_eina_array_clean), &i);
|
|
||||||
|
|
||||||
fail_if(i != 200);
|
|
||||||
|
|
||||||
eina_array_clean(ea);
|
|
||||||
eina_array_flush(ea);
|
|
||||||
eina_array_free(ea);
|
|
||||||
|
|
||||||
eina_shutdown();
|
|
||||||
}
|
|
||||||
END_TEST
|
|
||||||
#endif
|
|
||||||
|
|
||||||
START_TEST(eina_array_static)
|
START_TEST(eina_array_static)
|
||||||
{
|
{
|
||||||
Eina_Array sea;
|
Eina_Array sea;
|
||||||
|
@ -240,9 +186,6 @@ void
|
||||||
eina_test_array(TCase *tc)
|
eina_test_array(TCase *tc)
|
||||||
{
|
{
|
||||||
tcase_add_test(tc, eina_array_simple);
|
tcase_add_test(tc, eina_array_simple);
|
||||||
#ifdef EINA_RWLOCKS_ENABLED
|
|
||||||
tcase_add_test(tc, eina_array_threadsafe);
|
|
||||||
#endif
|
|
||||||
tcase_add_test(tc, eina_array_static);
|
tcase_add_test(tc, eina_array_static);
|
||||||
tcase_add_test(tc, eina_array_remove_stuff);
|
tcase_add_test(tc, eina_array_remove_stuff);
|
||||||
}
|
}
|
||||||
|
|
|
@ -197,73 +197,10 @@ START_TEST(eina_hash_all_int)
|
||||||
}
|
}
|
||||||
END_TEST
|
END_TEST
|
||||||
|
|
||||||
#ifdef EFL_HAVE_POSIX_THREADS_RWLOCK
|
|
||||||
START_TEST(eina_hash_threadsafe_simple)
|
|
||||||
{
|
|
||||||
Eina_Hash *hash = NULL;
|
|
||||||
int *test;
|
|
||||||
int array[] = { 1, 42, 4, 5, 6 };
|
|
||||||
|
|
||||||
/* As mempool is already initialized and it use hash, we should have 2 init. */
|
|
||||||
fail_if(eina_init() != 2);
|
|
||||||
|
|
||||||
hash = eina_hash_threadsafe_string_superfast_new(NULL);
|
|
||||||
fail_if(hash == NULL);
|
|
||||||
|
|
||||||
fail_if(eina_hash_add(hash, "1", &array[0]) != EINA_TRUE);
|
|
||||||
fail_if(eina_hash_add(hash, "42", &array[1]) != EINA_TRUE);
|
|
||||||
fail_if(eina_hash_direct_add(hash, "4", &array[2]) != EINA_TRUE);
|
|
||||||
fail_if(eina_hash_direct_add(hash, "5", &array[3]) != EINA_TRUE);
|
|
||||||
fail_if(eina_hash_add(hash, "", "") != EINA_TRUE);
|
|
||||||
|
|
||||||
test = eina_hash_find(hash, "4");
|
|
||||||
fail_if(!test);
|
|
||||||
fail_if(*test != 4);
|
|
||||||
|
|
||||||
test = eina_hash_find(hash, "42");
|
|
||||||
fail_if(!test);
|
|
||||||
fail_if(*test != 42);
|
|
||||||
|
|
||||||
eina_hash_foreach(hash, eina_foreach_check, NULL);
|
|
||||||
|
|
||||||
test = eina_hash_modify(hash, "5", &array[4]);
|
|
||||||
fail_if(!test);
|
|
||||||
fail_if(*test != 5);
|
|
||||||
|
|
||||||
test = eina_hash_find(hash, "5");
|
|
||||||
fail_if(!test);
|
|
||||||
fail_if(*test != 6);
|
|
||||||
|
|
||||||
fail_if(eina_hash_population(hash) != 5);
|
|
||||||
|
|
||||||
fail_if(eina_hash_find(hash, "120") != NULL);
|
|
||||||
|
|
||||||
fail_if(eina_hash_del(hash, "5", NULL) != EINA_TRUE);
|
|
||||||
fail_if(eina_hash_find(hash, "5") != NULL);
|
|
||||||
|
|
||||||
fail_if(eina_hash_del(hash, NULL, &array[2]) != EINA_TRUE);
|
|
||||||
fail_if(eina_hash_find(hash, "4") != NULL);
|
|
||||||
|
|
||||||
fail_if(eina_hash_del(hash, NULL, &array[2]) != EINA_FALSE);
|
|
||||||
|
|
||||||
fail_if(eina_hash_del(hash, "1", NULL) != EINA_TRUE);
|
|
||||||
fail_if(eina_hash_del(hash, "42", NULL) != EINA_TRUE);
|
|
||||||
|
|
||||||
eina_hash_free(hash);
|
|
||||||
|
|
||||||
/* Same comment as eina_init */
|
|
||||||
fail_if(eina_shutdown() != 1);
|
|
||||||
}
|
|
||||||
END_TEST
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void eina_test_hash(TCase *tc)
|
void eina_test_hash(TCase *tc)
|
||||||
{
|
{
|
||||||
tcase_add_test(tc, eina_hash_simple);
|
tcase_add_test(tc, eina_hash_simple);
|
||||||
tcase_add_test(tc, eina_hash_extended);
|
tcase_add_test(tc, eina_hash_extended);
|
||||||
tcase_add_test(tc, eina_hash_double_item);
|
tcase_add_test(tc, eina_hash_double_item);
|
||||||
tcase_add_test(tc, eina_hash_all_int);
|
tcase_add_test(tc, eina_hash_all_int);
|
||||||
#ifdef EFL_HAVE_POSIX_THREADS_RWLOCK
|
|
||||||
tcase_add_test(tc, eina_hash_threadsafe_simple);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue