remove win7 code and fix other minor problems
authorcaro <caro@7cbeb6ba-43b4-40fd-8cce-4c39aea84d33>
Fri, 26 Nov 2010 18:41:43 +0000 (18:41 +0000)
committercaro <caro@7cbeb6ba-43b4-40fd-8cce-4c39aea84d33>
Fri, 26 Nov 2010 18:41:43 +0000 (18:41 +0000)
git-svn-id: svn+ssh://svn.enlightenment.org/var/svn/e/trunk/ecore@55023 7cbeb6ba-43b4-40fd-8cce-4c39aea84d33

src/lib/ecore/ecore_thread.c

index ef7c225..27f6252 100644 (file)
@@ -2,6 +2,8 @@
 # include <config.h>
 #endif
 
+#include <sys/time.h>
+
 #ifdef HAVE_EVIL
 # include <Evil.h>
 #endif
@@ -15,7 +17,6 @@
 #  include <pthread.h>
 #  ifdef __linux__
 #   include <sched.h>
-#   include <sys/time.h>
 #   include <sys/resource.h>
 #   include <unistd.h>
 #   include <sys/syscall.h>
@@ -99,6 +100,12 @@ int _ecore_thread_win32_join(win32_thread *x, void **res)
 #  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;
@@ -139,65 +146,155 @@ do {                                                        \
   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
 
@@ -480,8 +577,11 @@ _ecore_direct_worker(Ecore_Pthread_Worker *work)
 {
    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));
@@ -528,8 +628,11 @@ _ecore_thread_worker(Ecore_Pthread_Data *pth)
 {
    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);
@@ -1311,7 +1414,7 @@ ecore_thread_local_data_set(Ecore_Thread *thread, const char *key, void *value,
    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)
@@ -1354,7 +1457,7 @@ ecore_thread_local_data_find(Ecore_Thread *thread, const char *key)
 
    if ((!thread) || (!key))
      return NULL;
-#ifdef EFL_HAVE_PTHREAD
+#ifdef EFL_HAVE_THREADS
    if (!PHE(worker->self, PHS())) return NULL;
 
    if (!worker->hash)
@@ -1383,7 +1486,7 @@ ecore_thread_local_data_del(Ecore_Thread *thread, const char *key)
    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)
@@ -1416,7 +1519,7 @@ ecore_thread_global_data_add(const char *key, void *value, Eina_Free_Cb cb, Eina
 
    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);
@@ -1464,7 +1567,7 @@ ecore_thread_global_data_set(const char *key, void *value, Eina_Free_Cb cb)
 
    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);
@@ -1511,7 +1614,7 @@ ecore_thread_global_data_find(const char *key)
    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);
@@ -1539,7 +1642,7 @@ ecore_thread_global_data_del(const char *key)
 
    if (!key)
      return EINA_FALSE;
-#ifdef EFL_HAVE_PTHREAD
+#ifdef EFL_HAVE_THREADS
    if (!_ecore_thread_global_hash)
      return EINA_FALSE;
 
@@ -1573,7 +1676,7 @@ ecore_thread_global_data_wait(const char *key, double seconds)
    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)
@@ -1581,10 +1684,17 @@ ecore_thread_global_data_wait(const char *key, double seconds)
 
    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);