# include <config.h>
#endif
+#include <sys/time.h>
+
#ifdef HAVE_EVIL
# include <Evil.h>
#endif
# include <pthread.h>
# ifdef __linux__
# include <sched.h>
-# include <sys/time.h>
# include <sys/resource.h>
# include <unistd.h>
# include <sys/syscall.h>
# define PHJ(x, p) _ecore_thread_win32_join(x, (void**)(&(p)))
# define PHA(x) TerminateThread(x->thread, 0)
+# define LK(x) HANDLE x
+# define LKI(x) x = CreateMutex(NULL, FALSE, NULL)
+# define LKD(x) CloseHandle(x)
+# define LKL(x) WaitForSingleObject(x, INFINITE)
+# define LKU(x) ReleaseMutex(x)
+
typedef struct
{
HANDLE semaphore;
LeaveCriticalSection (&x->threads_count_lock); \
} while (0)
-# define CDW(x, y, t) \
-do { \
- DWORD val = t->tv_sec * 1000 + (tv_nsec / 1000000); \
- LKL(y); \
- EnterCriticalSection (&x->threads_count_lock); \
- x->threads_count++; \
- LeaveCriticalSection (&x->threads_count_lock); \
- LKU(y); \
- WaitForingleObject(x->semaphore, val); \
- } while (0)
-
-# define LK(x) HANDLE x
-# define LKI(x) x = CreateMutex(NULL, FALSE, NULL)
-# define LKD(x) CloseHandle(x)
-# define LKL(x) WaitForSingleObject(x, INFINITE)
-# define LKU(x) ReleaseMutex(x)
+int _ecore_thread_win32_cond_timedwait(win32_cond *c, HANDLE *external_mutex, struct timeval *t)
+{
+ DWORD res;
+ DWORD val = t->tv_sec * 1000 + (t->tv_usec / 1000);
+ LKL(external_mutex);
+ EnterCriticalSection (&c->threads_count_lock);
+ c->threads_count++;
+ LeaveCriticalSection (&c->threads_count_lock);
+ LKU(external_mutex);
+ res = WaitForSingleObject(c->semaphore, val);
+ if (res == WAIT_OBJECT_0)
+ return 0;
+ else
+ return -1;
+}
+# define CDW(x, y, t) _ecore_thread_win32_cond_timedwait(x, y, t)
typedef struct
{
- HANDLE semaphore_read;
- HANDLE semaphore_write;
- SRWLOCK l;
+ LONG readers_count;
+ LONG writers_count;
+ int readers;
+ int writers;
+ LK(mutex);
+ CD(cond_read);
+ CD(cond_write);
} win32_rwl;
# define LRWK(x) win32_rwl *x
-# define LRWKI(x) \
-do { \
- x = (win32_rwl *)calloc(1, sizeof(win32_rwl)); \
- if (x) \
- { \
- InitializeSRWLock(&x->l); \
- x->semaphore_read = CreateSemaphore (NULL, 0, 1, NULL); \
- if (x->semaphore_read) \
- { \
- x->semaphore_write = CreateSemaphore (NULL, 0, 1, NULL); \
- if (!semaphore_write) \
- { \
- CloseHandle(x->semaphore_read); \
- free(x); \
- x = NULL; \
- } \
- } \
- else \
- { \
- free(x); \
- x = NULL; \
- } \
- } \
- } while (0)
+# define LRWKI(x) \
+ do { \
+ x = (win32_rwl *)calloc(1, sizeof(win32_rwl)); \
+ if (x) \
+ { \
+ LKI(x->mutex); \
+ if (x->mutex) \
+ { \
+ CDI(x->cond_read); \
+ if (x->cond_read) \
+ { \
+ CDI(x->cond_write); \
+ if (!x->cond_write) \
+ { \
+ CDD(x->cond_read); \
+ LKD(x->mutex); \
+ free(x); \
+ x = NULL; \
+ } \
+ } \
+ else \
+ { \
+ LKD(x->mutex); \
+ free(x); \
+ x = NULL; \
+ } \
+ } \
+ else \
+ { \
+ free(x); \
+ x = NULL; \
+ } \
+ } \
+ } while (0)
# define LRWKD(x) \
do { \
- CloseHandle(x->semaphore_write); \
- CloseHandle(x->semaphore_read); \
+ LKU(x->mutex); \
+ LKD(x->mutex); \
+ CDD(x->cond_write); \
+ CDD(x->cond_read); \
free(x); \
} while (0)
-# define LRWKWL(x) AcquireSRWLockExclusive(&x->l)
-# define LRWKRL(x) AcquireSRWLockShared(&x->l)
-# define LRWKU(x) ReleaseSRWLockExclusive(&x->l)
+# define LRWKWL(x) \
+ do { \
+ DWORD res; \
+ LKU(x->mutex); \
+ if (x->writers || x->readers > 0) \
+ { \
+ x->writers_count++; \
+ while (x->writers || x->readers > 0) \
+ { \
+ EnterCriticalSection(&x->cond_write->threads_count_lock); \
+ x->cond_read->threads_count++; \
+ LeaveCriticalSection(&x->cond_write->threads_count_lock); \
+ res = WaitForSingleObject(x->cond_write->semaphore, INFINITE); \
+ if (res != WAIT_OBJECT_0) break; \
+ } \
+ x->writers_count--; \
+ } \
+ if (res == 0) x->writers_count = 1; \
+ LKU(x->mutex); \
+ } while (0)
+# define LRWKRL(x) \
+ do { \
+ DWORD res; \
+ LKL(x->mutex); \
+ if (x->writers) \
+ { \
+ x->readers_count++; \
+ while (x->writers) \
+ { \
+ EnterCriticalSection(&x->cond_write->threads_count_lock); \
+ x->cond_read->threads_count++; \
+ LeaveCriticalSection(&x->cond_write->threads_count_lock); \
+ res = WaitForSingleObject(x->cond_write->semaphore, INFINITE); \
+ if (res != WAIT_OBJECT_0) break; \
+ } \
+ x->readers_count--; \
+ } \
+ if (res == 0) \
+ x->readers++; \
+ LKU(x->mutex); \
+ } while (0)
+# define LRWKU(x) \
+ do { \
+ LKL(x->mutex); \
+ if (x->writers) \
+ { \
+ x->writers = 0; \
+ if (x->readers_count == 1) \
+ { \
+ EnterCriticalSection(&x->cond_read->threads_count_lock); \
+ if (x->cond_read->threads_count > 0) \
+ ReleaseSemaphore(x->cond_read->semaphore, 1, 0); \
+ LeaveCriticalSection(&x->cond_read->threads_count_lock); \
+ } \
+ else if (x->readers_count > 0) \
+ CDB(x->cond_read); \
+ else if (x->writers_count > 0) \
+ { \
+ EnterCriticalSection (&x->cond_write->threads_count_lock); \
+ if (x->cond_write->threads_count > 0) \
+ ReleaseSemaphore(x->cond_write->semaphore, 1, 0); \
+ LeaveCriticalSection (&x->cond_write->threads_count_lock); \
+ } \
+ } \
+ else if (x->readers > 0) \
+ { \
+ x->readers--; \
+ if (x->readers == 0 && x->writers_count > 0) \
+ { \
+ EnterCriticalSection (&x->cond_write->threads_count_lock); \
+ if (x->cond_write->threads_count > 0) \
+ ReleaseSemaphore(x->cond_write->semaphore, 1, 0); \
+ LeaveCriticalSection (&x->cond_write->threads_count_lock); \
+ } \
+ } \
+ LKU(x->mutex); \
+ } while (0)
# endif
{
Ecore_Pthread_Data *pth;
+#ifdef EFL_POSIX_THREADS
pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL);
+#endif
+
eina_sched_prio_drop();
pth = malloc(sizeof (Ecore_Pthread_Data));
{
Ecore_Pthread_Worker *work;
+#ifdef EFL_POSIX_THREADS
pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL);
+#endif
+
eina_sched_prio_drop();
LKL(_ecore_pending_job_threads_mutex);
void *ret;
if ((!thread) || (!key) || (!value))
return NULL;
-#ifdef EFL_HAVE_PTHREAD
+#ifdef EFL_HAVE_THREADS
if (!PHE(worker->self, PHS())) return NULL;
if (!worker->hash)
if ((!thread) || (!key))
return NULL;
-#ifdef EFL_HAVE_PTHREAD
+#ifdef EFL_HAVE_THREADS
if (!PHE(worker->self, PHS())) return NULL;
if (!worker->hash)
Ecore_Thread_Data *d;
if ((!thread) || (!key))
return EINA_FALSE;
-#ifdef EFL_HAVE_PTHREAD
+#ifdef EFL_HAVE_THREADS
if (!PHE(worker->self, PHS())) return EINA_FALSE;
if (!worker->hash)
if ((!key) || (!value))
return EINA_FALSE;
-#ifdef EFL_HAVE_PTHREAD
+#ifdef EFL_HAVE_THREADS
LRWKWL(_ecore_thread_global_hash_lock);
if (!_ecore_thread_global_hash)
_ecore_thread_global_hash = eina_hash_string_small_new(_ecore_thread_data_free);
if ((!key) || (!value))
return NULL;
-#ifdef EFL_HAVE_PTHREAD
+#ifdef EFL_HAVE_THREADS
LRWKWL(_ecore_thread_global_hash_lock);
if (!_ecore_thread_global_hash)
_ecore_thread_global_hash = eina_hash_string_small_new(_ecore_thread_data_free);
Ecore_Thread_Data *ret;
if (!key)
return NULL;
-#ifdef EFL_HAVE_PTHREAD
+#ifdef EFL_HAVE_THREADS
if (!_ecore_thread_global_hash) return NULL;
LRWKRL(_ecore_thread_global_hash_lock);
if (!key)
return EINA_FALSE;
-#ifdef EFL_HAVE_PTHREAD
+#ifdef EFL_HAVE_THREADS
if (!_ecore_thread_global_hash)
return EINA_FALSE;
Ecore_Thread_Data *ret = NULL;
if (!key)
return NULL;
-#ifdef EFL_HAVE_PTHREAD
+#ifdef EFL_HAVE_THREADS
if (!_ecore_thread_global_hash)
return NULL;
if (seconds > 0)
while (1)
{
+#ifndef _WIN32
struct timespec t = { 0, 0 };
t.tv_sec = (long int)time;
t.tv_nsec = (long int)((time - (double)t.tv_sec) * 1000000000);
+#else
+ struct timeval t = { 0, 0 };
+
+ t.tv_sec = (long int)time;
+ t.tv_usec = (long int)((time - (double)t.tv_sec) * 1000000);
+#endif
LRWKRL(_ecore_thread_global_hash_lock);
ret = eina_hash_find(_ecore_thread_global_hash, key);
LRWKU(_ecore_thread_global_hash_lock);