forked from enlightenment/efl
Eina : now eina stringshare is thread safe if eina_threads_init() is called. Eina log which was thread safe is now thread safe only if the previous functions is called
SVN revision: 43398
This commit is contained in:
parent
b2ac7c110a
commit
6ea6dc0856
|
@ -35,6 +35,10 @@ EAPI int eina_init(void);
|
|||
|
||||
EAPI int eina_shutdown(void);
|
||||
|
||||
EAPI int eina_threads_init(void);
|
||||
|
||||
EAPI int eina_threads_shutdown(void);
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
|
|
@ -116,5 +116,12 @@
|
|||
} \
|
||||
} while(0);
|
||||
|
||||
#ifdef EFL_HAVE_PTHREAD
|
||||
void eina_stringshare_threads_init(void);
|
||||
void eina_stringshare_threads_shutdown(void);
|
||||
void eina_log_threads_init(void);
|
||||
void eina_log_threads_shutdown(void);
|
||||
#endif
|
||||
|
||||
#endif /* EINA_PRIVATE_H_ */
|
||||
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
// vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
|
||||
|
||||
/* EINA - EFL data type library
|
||||
* Copyright (C) 2002-2008 Carsten Haitzler, Gustavo Sverzut Barbieri, Tilman Sauerbeck,
|
||||
* Vincent Torri, Cedric Bail, Jorge Luis Zapata Muga,
|
||||
|
@ -1590,15 +1592,15 @@ eina_list_merge(Eina_List *left, Eina_List *right)
|
|||
* @param right The head of the new right list.
|
||||
* @return The new left list
|
||||
*
|
||||
* This function split @p list into two lists ( left and right ) after the node @p relative. @p Relative
|
||||
* will become the last node of the left list. If @p list or @p right are NULL list is returns.
|
||||
* This function split @p list into two lists ( left and right ) after the node @p relative. @p Relative
|
||||
* will become the last node of the left list. If @p list or @p right are NULL list is returns.
|
||||
* If @p relative is NULL right is set to @p list and NULL is returns.
|
||||
* If @p relative is the last node of @p list list is returns and @p right is set to NULL.
|
||||
*
|
||||
* list does not exist anymore after the split.
|
||||
*
|
||||
*/
|
||||
EAPI Eina_List *
|
||||
EAPI Eina_List *
|
||||
eina_list_split_list(Eina_List *list, Eina_List *relative, Eina_List **right)
|
||||
{
|
||||
Eina_List *next;
|
||||
|
@ -1610,12 +1612,12 @@ eina_list_split_list(Eina_List *list, Eina_List *relative, Eina_List **right)
|
|||
if (!list) return NULL;
|
||||
if (!relative)
|
||||
{
|
||||
*right = list;
|
||||
return NULL;
|
||||
*right = list;
|
||||
return NULL;
|
||||
}
|
||||
if (relative == eina_list_last(list)) return list;
|
||||
|
||||
next = eina_list_next(relative);
|
||||
next = eina_list_next(relative);
|
||||
next->prev = NULL;
|
||||
next->accounting = _eina_list_mempool_accounting_new(next);
|
||||
next->accounting->last = list->accounting->last;
|
||||
|
@ -1624,14 +1626,14 @@ eina_list_split_list(Eina_List *list, Eina_List *relative, Eina_List **right)
|
|||
itr = next;
|
||||
do
|
||||
{
|
||||
itr->accounting = next->accounting;
|
||||
next->accounting->count++;
|
||||
itr = itr->next;
|
||||
itr->accounting = next->accounting;
|
||||
next->accounting->count++;
|
||||
itr = itr->next;
|
||||
}
|
||||
while (itr);
|
||||
while (itr);
|
||||
|
||||
relative->next = NULL;
|
||||
list->accounting->last = relative;
|
||||
list->accounting->last = relative;
|
||||
list->accounting->count = list->accounting->count - next->accounting->count;
|
||||
|
||||
return list;
|
||||
|
|
|
@ -376,6 +376,7 @@ static pthread_t _main_thread;
|
|||
#ifdef EINA_PTHREAD_SPIN
|
||||
static pthread_spinlock_t _log_lock;
|
||||
#define LOCK() \
|
||||
if(_threads_enabled) \
|
||||
do { \
|
||||
if (0) \
|
||||
fprintf(stderr, "+++LOG LOCKED! [%s, %lu]\n", \
|
||||
|
@ -384,6 +385,7 @@ static pthread_spinlock_t _log_lock;
|
|||
pthread_spin_lock(&_log_lock); \
|
||||
} while (0)
|
||||
#define UNLOCK() \
|
||||
if(_threads_enabled) \
|
||||
do { \
|
||||
if (EINA_UNLIKELY(_threads_enabled)) \
|
||||
pthread_spin_unlock(&_log_lock); \
|
||||
|
@ -396,8 +398,8 @@ static pthread_spinlock_t _log_lock;
|
|||
#define SHUTDOWN() pthread_spin_destroy(&_log_lock);
|
||||
#else
|
||||
static pthread_mutex_t _log_mutex = PTHREAD_MUTEX_INITIALIZER;
|
||||
#define LOCK() pthread_mutex_lock(&_log_mutex);
|
||||
#define UNLOCK() pthread_mutex_unlock(&_log_mutex);
|
||||
#define LOCK() if(_threads_enabled) pthread_mutex_lock(&_log_mutex);
|
||||
#define UNLOCK() if(_threads_enabled) pthread_mutex_unlock(&_log_mutex);
|
||||
#define INIT() do {} while (0)
|
||||
#define SHUTDOWN() do {} while (0)
|
||||
#endif
|
||||
|
@ -700,7 +702,6 @@ eina_log_print_prefix_update(void)
|
|||
#undef S
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Creates a colored domain name string.
|
||||
*/
|
||||
|
@ -965,11 +966,6 @@ eina_log_init(void)
|
|||
assert((sizeof(_names)/sizeof(_names[0])) == EINA_LOG_LEVELS);
|
||||
assert((sizeof(_colors)/sizeof(_colors[0])) == EINA_LOG_LEVELS + 1);
|
||||
|
||||
#ifdef EFL_HAVE_PTHREAD
|
||||
_main_thread = pthread_self();
|
||||
INIT();
|
||||
#endif
|
||||
|
||||
// Check if color is disabled
|
||||
if ((tmp = getenv(EINA_LOG_ENV_COLOR_DISABLE)) && (atoi(tmp) == 1))
|
||||
_disable_color = EINA_TRUE;
|
||||
|
@ -1056,14 +1052,48 @@ eina_log_shutdown(void)
|
|||
free(tmp);
|
||||
}
|
||||
|
||||
#ifdef EFL_HAVE_PTHREAD
|
||||
SHUTDOWN();
|
||||
_threads_enabled = 0;
|
||||
#endif
|
||||
|
||||
return EINA_TRUE;
|
||||
}
|
||||
|
||||
|
||||
#ifdef EFL_HAVE_PTHREAD
|
||||
|
||||
/**
|
||||
* @internal
|
||||
* @brief Activate the log mutex.
|
||||
*
|
||||
* This function activate the mutex in the eina log module. It is called by
|
||||
* eina_thread_init().
|
||||
*
|
||||
* @see eina_thread_init()
|
||||
*/
|
||||
void
|
||||
eina_log_threads_init(void)
|
||||
{
|
||||
_main_thread = pthread_self();
|
||||
_threads_enabled = EINA_TRUE;
|
||||
INIT();
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
* @brief Shut down the log mutex.
|
||||
*
|
||||
* This function shuts down the mutex in the log module.
|
||||
* It is called by eina_thread_shutdown().
|
||||
*
|
||||
* @see eina_thread_shutdown()
|
||||
*/
|
||||
void
|
||||
eina_log_threads_shutdown(void)
|
||||
{
|
||||
SHUTDOWN();
|
||||
_threads_enabled = EINA_FALSE;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
/**
|
||||
* Enable logging module to handle threads.
|
||||
*
|
||||
|
@ -1471,3 +1501,4 @@ eina_log_vprint(int domain, Eina_Log_Level level, const char *file,
|
|||
eina_log_print_unlocked(domain, level, file, fnc, line, fmt, args);
|
||||
UNLOCK();
|
||||
}
|
||||
|
||||
|
|
|
@ -48,6 +48,7 @@
|
|||
*/
|
||||
|
||||
static int _eina_main_count = 0;
|
||||
static int _eina_main_thread_count = 0;
|
||||
static int _eina_log_dom = -1;
|
||||
|
||||
#ifdef ERR
|
||||
|
@ -60,6 +61,18 @@ static int _eina_log_dom = -1;
|
|||
#endif
|
||||
#define DBG(...) EINA_LOG_DOM_DBG(_eina_log_dom, __VA_ARGS__)
|
||||
|
||||
#ifdef EFL_HAVE_PTHREAD
|
||||
#include <pthread.h>
|
||||
static Eina_Bool _threads_activated = EINA_FALSE;
|
||||
static pthread_mutex_t _mutex = PTHREAD_MUTEX_INITIALIZER;
|
||||
#define LOCK() if(_threads_activated) pthread_mutex_lock(&_mutex);
|
||||
#define UNLOCK() if(_threads_activated) pthread_mutex_unlock(&_mutex);
|
||||
#define UNLOCK_FORCE() pthread_mutex_unlock(&_mutex);
|
||||
#else
|
||||
#define LOCK() do {} while (0)
|
||||
#define UNLOCK() do {} while (0)
|
||||
#define UNLOCK_FORCE() do {} while (0)
|
||||
#endif
|
||||
|
||||
/* place module init/shutdown functions here to avoid other modules
|
||||
* calling them by mistake.
|
||||
|
@ -220,6 +233,88 @@ eina_shutdown(void)
|
|||
return _eina_main_count;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Initialize the mutexs of the Eina library.
|
||||
*
|
||||
* @return 1 or greater on success, 0 on error.
|
||||
*
|
||||
* This function sets up all the mutexs in all eina modules. It returns 0 on
|
||||
* failure (that is, when one of the module fails to initialize),
|
||||
* otherwise it returns the number of times it has already been
|
||||
* called.
|
||||
*
|
||||
* When the mutexs are not used anymore, call eina_thread_shutdown() to shut down
|
||||
* the mutexs.
|
||||
*/
|
||||
EAPI int
|
||||
eina_threads_init(void)
|
||||
{
|
||||
#ifdef EFL_HAVE_PTHREAD
|
||||
int ret;
|
||||
|
||||
LOCK();
|
||||
++_eina_main_thread_count;
|
||||
ret = _eina_main_thread_count;
|
||||
|
||||
if(_eina_main_thread_count > 1)
|
||||
{
|
||||
UNLOCK();
|
||||
return ret;
|
||||
}
|
||||
|
||||
eina_stringshare_threads_init();
|
||||
eina_log_threads_init();
|
||||
_threads_activated = EINA_TRUE;
|
||||
|
||||
return ret;
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Shut down mutexs in the Eina library.
|
||||
*
|
||||
* @return 0 when all mutexs are completely shut down, 1 or
|
||||
* greater otherwise.
|
||||
*
|
||||
* This function shuts down the mutexs in the Eina library. It returns 0 when it has
|
||||
* been called the same number of times than eina_thread_init(). In that case
|
||||
* it shut down all the mutexs.
|
||||
*
|
||||
* Once this function succeeds (that is, @c 0 is returned), you must
|
||||
* not call any of the Eina function in a thread anymore. You must call
|
||||
* eina_thread_init() again to use the Eina functions in a thread again.
|
||||
*/
|
||||
EAPI int
|
||||
eina_threads_shutdown(void)
|
||||
{
|
||||
#ifdef EFL_HAVE_PTHREAD
|
||||
int ret;
|
||||
|
||||
LOCK();
|
||||
ret = --_eina_main_thread_count;
|
||||
if(_eina_main_thread_count > 0)
|
||||
{
|
||||
UNLOCK();
|
||||
return ret;
|
||||
}
|
||||
|
||||
eina_stringshare_threads_shutdown();
|
||||
eina_log_threads_shutdown();
|
||||
|
||||
_threads_activated = EINA_FALSE;
|
||||
|
||||
UNLOCK_FORCE();
|
||||
|
||||
return ret;
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
|
|
@ -100,19 +100,23 @@ static const char EINA_MAGIC_STRINGSHARE_HEAD_STR[] = "Eina Stringshare Head";
|
|||
static const char EINA_MAGIC_STRINGSHARE_NODE_STR[] = "Eina Stringshare Node";
|
||||
|
||||
|
||||
#define EINA_MAGIC_CHECK_STRINGSHARE_HEAD(d, ...) \
|
||||
#define EINA_MAGIC_CHECK_STRINGSHARE_HEAD(d, unlock, ...) \
|
||||
do { \
|
||||
if (!EINA_MAGIC_CHECK((d), EINA_MAGIC_STRINGSHARE_HEAD)) \
|
||||
{ \
|
||||
EINA_MAGIC_FAIL((d), EINA_MAGIC_STRINGSHARE_HEAD); \
|
||||
unlock; \
|
||||
return __VA_ARGS__; \
|
||||
} \
|
||||
} while (0);
|
||||
|
||||
#define EINA_MAGIC_CHECK_STRINGSHARE_NODE(d) \
|
||||
#define EINA_MAGIC_CHECK_STRINGSHARE_NODE(d, unlock) \
|
||||
do { \
|
||||
if (!EINA_MAGIC_CHECK((d), EINA_MAGIC_STRINGSHARE_NODE)) \
|
||||
{ \
|
||||
unlock; \
|
||||
EINA_MAGIC_FAIL((d), EINA_MAGIC_STRINGSHARE_NODE); \
|
||||
} \
|
||||
} while (0);
|
||||
|
||||
typedef struct _Eina_Stringshare Eina_Stringshare;
|
||||
|
@ -170,6 +174,27 @@ static int _eina_stringshare_log_dom = -1;
|
|||
#endif
|
||||
#define DBG(...) EINA_LOG_DOM_DBG(_eina_stringshare_log_dom, __VA_ARGS__)
|
||||
|
||||
|
||||
|
||||
#ifdef EFL_HAVE_PTHREAD
|
||||
#include <pthread.h>
|
||||
static Eina_Bool _threads_activated = EINA_FALSE;
|
||||
//string < 4
|
||||
static pthread_mutex_t _mutex_small = PTHREAD_MUTEX_INITIALIZER;
|
||||
//string >= 4
|
||||
static pthread_mutex_t _mutex_big = PTHREAD_MUTEX_INITIALIZER;
|
||||
#define LOCK_SMALL() if(_threads_activated) pthread_mutex_lock(&_mutex_small);
|
||||
#define UNLOCK_SMALL() if(_threads_activated) pthread_mutex_unlock(&_mutex_small);
|
||||
#define LOCK_BIG() if(_threads_activated) pthread_mutex_lock(&_mutex_big);
|
||||
#define UNLOCK_BIG() if(_threads_activated) pthread_mutex_unlock(&_mutex_big);
|
||||
#else
|
||||
#define LOCK_SMALL() do {} while (0)
|
||||
#define UNLOCK_SMALL() do {} while (0)
|
||||
#define LOCK_BIG() do {} while (0)
|
||||
#define UNLOCK_BIG() do {} while (0)
|
||||
#endif
|
||||
|
||||
|
||||
static const unsigned char _eina_stringshare_single[512] = {
|
||||
0,0,1,0,2,0,3,0,4,0,5,0,6,0,7,0,8,0,9,0,10,0,11,0,12,0,13,0,14,0,15,0,
|
||||
16,0,17,0,18,0,19,0,20,0,21,0,22,0,23,0,24,0,25,0,26,0,27,0,28,0,29,0,30,0,
|
||||
|
@ -276,6 +301,9 @@ _eina_stringshare_population_stats(void)
|
|||
static void
|
||||
_eina_stringshare_population_add(int slen)
|
||||
{
|
||||
LOCK_SMALL();
|
||||
LOCK_BIG();
|
||||
|
||||
population.count++;
|
||||
if (population.count > population.max)
|
||||
population.max = population.count;
|
||||
|
@ -286,14 +314,23 @@ _eina_stringshare_population_add(int slen)
|
|||
if (population_group[slen].count > population_group[slen].max)
|
||||
population_group[slen].max = population_group[slen].count;
|
||||
}
|
||||
|
||||
UNLOCK_BIG();
|
||||
UNLOCK_SMALL();
|
||||
}
|
||||
|
||||
static void
|
||||
_eina_stringshare_population_del(int slen)
|
||||
{
|
||||
LOCK_SMALL();
|
||||
LOCK_BIG();
|
||||
|
||||
population.count--;
|
||||
if (slen < 4)
|
||||
population_group[slen].count--;
|
||||
|
||||
UNLOCK_BIG();
|
||||
UNLOCK_SMALL();
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -331,7 +368,7 @@ static void _eina_stringshare_population_head_del(__UNUSED__ Eina_Stringshare_He
|
|||
static int
|
||||
_eina_stringshare_cmp(const Eina_Stringshare_Head *ed, const int *hash, __UNUSED__ int length, __UNUSED__ void *data)
|
||||
{
|
||||
EINA_MAGIC_CHECK_STRINGSHARE_HEAD(ed, 0);
|
||||
EINA_MAGIC_CHECK_STRINGSHARE_HEAD(ed, , 0);
|
||||
|
||||
return ed->hash - *hash;
|
||||
}
|
||||
|
@ -339,8 +376,8 @@ _eina_stringshare_cmp(const Eina_Stringshare_Head *ed, const int *hash, __UNUSED
|
|||
static Eina_Rbtree_Direction
|
||||
_eina_stringshare_node(const Eina_Stringshare_Head *left, const Eina_Stringshare_Head *right, __UNUSED__ void *data)
|
||||
{
|
||||
EINA_MAGIC_CHECK_STRINGSHARE_HEAD(left, 0);
|
||||
EINA_MAGIC_CHECK_STRINGSHARE_HEAD(right, 0);
|
||||
EINA_MAGIC_CHECK_STRINGSHARE_HEAD(left, , 0);
|
||||
EINA_MAGIC_CHECK_STRINGSHARE_HEAD(right, , 0);
|
||||
|
||||
if (left->hash - right->hash < 0)
|
||||
return EINA_RBTREE_LEFT;
|
||||
|
@ -350,7 +387,7 @@ _eina_stringshare_node(const Eina_Stringshare_Head *left, const Eina_Stringshare
|
|||
static void
|
||||
_eina_stringshare_head_free(Eina_Stringshare_Head *ed, __UNUSED__ void *data)
|
||||
{
|
||||
EINA_MAGIC_CHECK_STRINGSHARE_HEAD(ed);
|
||||
EINA_MAGIC_CHECK_STRINGSHARE_HEAD(ed, );
|
||||
|
||||
while (ed->head)
|
||||
{
|
||||
|
@ -879,6 +916,9 @@ eina_stringshare_shutdown(void)
|
|||
{
|
||||
unsigned int i;
|
||||
|
||||
LOCK_SMALL();
|
||||
LOCK_BIG();
|
||||
|
||||
_eina_stringshare_population_stats();
|
||||
|
||||
/* remove any string still in the table */
|
||||
|
@ -893,9 +933,48 @@ eina_stringshare_shutdown(void)
|
|||
_eina_stringshare_small_shutdown();
|
||||
eina_log_domain_unregister(_eina_stringshare_log_dom);
|
||||
_eina_stringshare_log_dom = -1;
|
||||
|
||||
UNLOCK_BIG();
|
||||
UNLOCK_SMALL();
|
||||
|
||||
|
||||
return EINA_TRUE;
|
||||
}
|
||||
|
||||
#ifdef EFL_HAVE_PTHREAD
|
||||
|
||||
/**
|
||||
* @internal
|
||||
* @brief Activate the stringshare mutexs.
|
||||
*
|
||||
* This function activate the mutexs in the eina stringshare module. It is called by
|
||||
* eina_thread_init().
|
||||
*
|
||||
* @see eina_thread_init()
|
||||
*/
|
||||
void
|
||||
eina_stringshare_threads_init(void)
|
||||
{
|
||||
_threads_activated = EINA_TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
* @brief Shut down the stringshare mutexs.
|
||||
*
|
||||
* This function shuts down the mutexs in the stringshare module.
|
||||
* It is called by eina_thread_shutdown().
|
||||
*
|
||||
* @see eina_thread_shutdown()
|
||||
*/
|
||||
void
|
||||
eina_stringshare_threads_shutdown(void)
|
||||
{
|
||||
_threads_activated = EINA_FALSE;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Retrieve an instance of a string for use in a program.
|
||||
*
|
||||
|
@ -936,36 +1015,53 @@ eina_stringshare_add_length(const char *str, unsigned int slen)
|
|||
else if (slen == 1)
|
||||
return (const char *)_eina_stringshare_single + ((*str) << 1);
|
||||
else if (slen < 4)
|
||||
return _eina_stringshare_small_add(str, slen);
|
||||
{
|
||||
LOCK_SMALL();
|
||||
const char *s = _eina_stringshare_small_add(str, slen);
|
||||
UNLOCK_SMALL();
|
||||
return s;
|
||||
}
|
||||
|
||||
hash = eina_hash_superfast(str, slen);
|
||||
hash_num = hash & 0xFF;
|
||||
hash = (hash >> 8) & EINA_STRINGSHARE_MASK;
|
||||
|
||||
LOCK_BIG();
|
||||
p_bucket = share->buckets + hash_num;
|
||||
|
||||
ed = _eina_stringshare_find_hash(*p_bucket, hash);
|
||||
if (!ed)
|
||||
return _eina_stringshare_add_head(p_bucket, hash, str, slen);
|
||||
{
|
||||
const char *s = _eina_stringshare_add_head(p_bucket, hash, str, slen);
|
||||
UNLOCK_BIG();
|
||||
return s;
|
||||
}
|
||||
|
||||
EINA_MAGIC_CHECK_STRINGSHARE_HEAD(ed, NULL);
|
||||
EINA_MAGIC_CHECK_STRINGSHARE_HEAD(ed, UNLOCK_BIG(), NULL);
|
||||
|
||||
el = _eina_stringshare_head_find(ed, str, slen);
|
||||
if (el)
|
||||
{
|
||||
EINA_MAGIC_CHECK_STRINGSHARE_NODE(el);
|
||||
EINA_MAGIC_CHECK_STRINGSHARE_NODE(el, UNLOCK_BIG());
|
||||
el->references++;
|
||||
UNLOCK_BIG();
|
||||
return el->str;
|
||||
}
|
||||
|
||||
el = _eina_stringshare_node_alloc(slen);
|
||||
if (!el)
|
||||
return NULL;
|
||||
{
|
||||
UNLOCK_BIG();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
_eina_stringshare_node_init(el, str, slen);
|
||||
el->next = ed->head;
|
||||
ed->head = el;
|
||||
_eina_stringshare_population_head_add(ed);
|
||||
|
||||
UNLOCK_BIG();
|
||||
|
||||
return el->str;
|
||||
}
|
||||
|
||||
|
@ -1014,7 +1110,7 @@ _eina_stringshare_node_from_str(const char *str)
|
|||
const size_t offset = (char *)&(t.str) - (char *)&t;
|
||||
|
||||
node = (Eina_Stringshare_Node *)(str - offset);
|
||||
EINA_MAGIC_CHECK_STRINGSHARE_NODE(node);
|
||||
EINA_MAGIC_CHECK_STRINGSHARE_NODE(node, );
|
||||
return node;
|
||||
}
|
||||
|
||||
|
@ -1047,18 +1143,27 @@ eina_stringshare_ref(const char *str)
|
|||
if (slen < 2)
|
||||
{
|
||||
_eina_stringshare_population_add(slen);
|
||||
|
||||
return str;
|
||||
}
|
||||
else if (slen < 4)
|
||||
{
|
||||
_eina_stringshare_population_add(slen);
|
||||
return _eina_stringshare_small_add(str, slen);
|
||||
|
||||
LOCK_SMALL();
|
||||
const char *s = _eina_stringshare_small_add(str, slen);
|
||||
UNLOCK_SMALL();
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
LOCK_BIG();
|
||||
node = _eina_stringshare_node_from_str(str);
|
||||
node->references++;
|
||||
DBG("str=%p (%s) refs=%u", str, str, node->references);
|
||||
|
||||
UNLOCK_BIG();
|
||||
|
||||
_eina_stringshare_population_add(node->length);
|
||||
|
||||
return str;
|
||||
|
@ -1102,15 +1207,20 @@ eina_stringshare_del(const char *str)
|
|||
return;
|
||||
else if (slen < 4)
|
||||
{
|
||||
LOCK_SMALL();
|
||||
_eina_stringshare_small_del(str, slen);
|
||||
UNLOCK_SMALL();
|
||||
return;
|
||||
}
|
||||
|
||||
LOCK_BIG();
|
||||
|
||||
node = _eina_stringshare_node_from_str(str);
|
||||
if (node->references > 1)
|
||||
{
|
||||
node->references--;
|
||||
DBG("str=%p (%s) refs=%u", str, str, node->references);
|
||||
UNLOCK_BIG();
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1127,7 +1237,7 @@ eina_stringshare_del(const char *str)
|
|||
if (!ed)
|
||||
goto on_error;
|
||||
|
||||
EINA_MAGIC_CHECK_STRINGSHARE_HEAD(ed);
|
||||
EINA_MAGIC_CHECK_STRINGSHARE_HEAD(ed, UNLOCK_BIG());
|
||||
|
||||
if (!_eina_stringshare_head_remove_node(ed, node))
|
||||
goto on_error;
|
||||
|
@ -1140,9 +1250,12 @@ eina_stringshare_del(const char *str)
|
|||
else
|
||||
_eina_stringshare_population_head_del(ed);
|
||||
|
||||
UNLOCK_BIG();
|
||||
|
||||
return;
|
||||
|
||||
on_error:
|
||||
UNLOCK_BIG();
|
||||
/* possible segfault happened before here, but... */
|
||||
CRITICAL("EEEK trying to del non-shared stringshare \"%s\"", str);
|
||||
}
|
||||
|
@ -1231,7 +1344,10 @@ static Eina_Bool
|
|||
eina_iterator_array_check(const Eina_Rbtree *rbtree __UNUSED__, Eina_Stringshare_Head *head, struct dumpinfo *fdata)
|
||||
{
|
||||
Eina_Stringshare_Node *node;
|
||||
|
||||
|
||||
LOCK_SMALL();
|
||||
LOCK_BIG();
|
||||
|
||||
fdata->used += sizeof(Eina_Stringshare_Head);
|
||||
for (node = head->head; node; node = node->next)
|
||||
{
|
||||
|
@ -1243,6 +1359,10 @@ eina_iterator_array_check(const Eina_Rbtree *rbtree __UNUSED__, Eina_Stringshare
|
|||
fdata->dups += node->references - 1;
|
||||
fdata->unique++;
|
||||
}
|
||||
|
||||
UNLOCK_BIG();
|
||||
UNLOCK_SMALL();
|
||||
|
||||
return EINA_TRUE;
|
||||
}
|
||||
|
||||
|
@ -1266,7 +1386,12 @@ eina_stringshare_dump(void)
|
|||
di.unique = 0;
|
||||
printf("DDD: len ref string\n");
|
||||
printf("DDD:-------------------\n");
|
||||
|
||||
LOCK_SMALL();
|
||||
_eina_stringshare_small_dump(&di);
|
||||
UNLOCK_SMALL();
|
||||
|
||||
LOCK_BIG();
|
||||
for (i = 0; i < EINA_STRINGSHARE_BUCKETS; i++)
|
||||
{
|
||||
if (!share->buckets[i]) continue;
|
||||
|
@ -1294,8 +1419,11 @@ eina_stringshare_dump(void)
|
|||
for (i = 0; i < sizeof (population_group) / sizeof (population_group[0]); ++i)
|
||||
fprintf(stderr, "DDD: %i strings of length %i, max strings: %i\n", population_group[i].count, i, population_group[i].max);
|
||||
#endif
|
||||
|
||||
UNLOCK_BIG();
|
||||
}
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
|
Loading…
Reference in New Issue