From a04093ab0d9a6d5aabfc9a9923ca7f039b7fcd89 Mon Sep 17 00:00:00 2001 From: discomfitor Date: Fri, 23 Jul 2010 16:24:35 +0000 Subject: [PATCH] +ecore_thread_{global,pool}_data_wait, to allow waiting for data in the global or pool data contexts and simulate g_async_queue in a less mutexy fashion git-svn-id: http://svn.enlightenment.org/svn/e/trunk/ecore@50454 7cbeb6ba-43b4-40fd-8cce-4c39aea84d33 --- src/lib/ecore/Ecore.h | 1 + src/lib/ecore/ecore_thread.c | 82 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 83 insertions(+) diff --git a/src/lib/ecore/Ecore.h b/src/lib/ecore/Ecore.h index 7573a60..a8caf90 100644 --- a/src/lib/ecore/Ecore.h +++ b/src/lib/ecore/Ecore.h @@ -371,6 +371,7 @@ extern "C" { EAPI void *ecore_thread_global_data_set(const char *key, const void *value); EAPI void *ecore_thread_global_data_find(const char *key); EAPI Eina_Bool ecore_thread_global_data_del(const char *key); + EAPI void *ecore_thread_global_data_wait(const char *key, double seconds); EAPI double ecore_time_get(void); diff --git a/src/lib/ecore/ecore_thread.c b/src/lib/ecore/ecore_thread.c index 19d262c..d38e805 100644 --- a/src/lib/ecore/ecore_thread.c +++ b/src/lib/ecore/ecore_thread.c @@ -925,6 +925,47 @@ ecore_thread_pool_data_del(Ecore_Thread *thread, const char *key) } /** + * @brief Find data in the pool data and optionally wait for the data if not found + * @param key The name string the data is associated with + * @param seconds The amount of time in seconds to wait for the data. If 0, the call will be async and not wait for data. + * If < 0 the call will wait indefinitely for the data. + * @return The value, or NULL on failure + * This finds data in the pool data that has been previously added with @ref ecore_thread_pool_data_add + * This function will return NULL in any case but success. + * Use @p seconds to specify the amount of time to wait. Use > 0 for an actual wait time, 0 to not wait, and < 0 to wait indefinitely. + */ +EAPI void * +ecore_thread_pool_data_wait(const char *key, double seconds) +{ + double time = 0; + void *ret; + Ecore_Pthread_Worker *worker = (Ecore_Pthread_Worker *) thread; + if ((!thread) || (!key)) + return NULL; +#ifdef EFL_HAVE_PTHREAD + if (worker->self != pthread_self()) return NULL; + if (seconds > 0) + time = ecore_time_get() + seconds; + + while (1) + { + ret = eina_hash_find(thread->hash, key); + if ((ret) || (!seconds) || ((seconds > 0) && (time <= ecore_time_get()))) + break; + //try to sleep for a reasonable amount of time + if (time) + usleep((seconds * 1000000) / 2); + else + usleep(1000000); + } + return ret; +#else + return NULL; +#endif +} + + +/** * @brief Add data to the global data * @param key The name string to add the data with * @param value The data to add @@ -1046,6 +1087,47 @@ ecore_thread_global_data_del(const char *key) #endif } +/** + * @brief Find data in the global data and optionally wait for the data if not found + * @param key The name string the data is associated with + * @param seconds The amount of time in seconds to wait for the data. If 0, the call will be async and not wait for data. + * If < 0 the call will wait indefinitely for the data. + * @return The value, or NULL on failure + * This finds data in the global data that has been previously added with @ref ecore_thread_global_data_add + * This function will return NULL in any case but success. + * Use @p seconds to specify the amount of time to wait. Use > 0 for an actual wait time, 0 to not wait, and < 0 to wait indefinitely. + */ +EAPI void * +ecore_thread_global_data_wait(const char *key, double seconds) +{ + double time = 0; + void *ret = NULL; + if (!key) + return NULL; +#ifdef EFL_HAVE_PTHREAD + if (!_ecore_thread_global_hash) + return NULL; + if (seconds > 0) + time = ecore_time_get() + seconds; + + while (1) + { + pthread_rwlock_rdlock(&_ecore_thread_global_hash_lock); + ret = eina_hash_find(_ecore_thread_global_hash, key); + pthread_rwlock_unlock(&_ecore_thread_global_hash_lock); + if ((ret) || (!seconds) || ((seconds > 0) && (time <= ecore_time_get()))) + break; + //try to sleep for a reasonable amount of time + if (time) + usleep((seconds * 1000000) / 2); + else + usleep(1000000); + } + return ret; +#else + return NULL; +#endif +} /** * @} -- 2.7.4