lots of cleanups... actually tested! :)
authorraster <raster@7cbeb6ba-43b4-40fd-8cce-4c39aea84d33>
Thu, 9 Sep 2010 07:08:10 +0000 (07:08 +0000)
committerraster <raster@7cbeb6ba-43b4-40fd-8cce-4c39aea84d33>
Thu, 9 Sep 2010 07:08:10 +0000 (07:08 +0000)
git-svn-id: svn+ssh://svn.enlightenment.org/var/svn/e/trunk/evas@52030 7cbeb6ba-43b4-40fd-8cce-4c39aea84d33

src/lib/cache/evas_preload.c

index 0dfa5f9..188b373 100644 (file)
 #include "evas_private.h"
 #include "Evas.h"
 
+static int _threads_max = 0;
+
 #ifdef BUILD_ASYNC_PRELOAD
+
 typedef struct _Evas_Preload_Pthread_Worker Evas_Preload_Pthread_Worker;
 typedef struct _Evas_Preload_Pthread_Data Evas_Preload_Pthread_Data;
 
@@ -25,9 +28,7 @@ struct _Evas_Preload_Pthread_Worker
    _evas_preload_pthread_func func_heavy;
    _evas_preload_pthread_func func_end;
    _evas_preload_pthread_func func_cancel;
-
-   const void *data;
-
+   void *data;
    Eina_Bool cancel : 1;
 };
 
@@ -35,89 +36,73 @@ struct _Evas_Preload_Pthread_Data
 {
    pthread_t thread;
 };
-#endif
 
-static int _evas_preload_thread_count_max = 0;
-
-#ifdef BUILD_ASYNC_PRELOAD
-static int _evas_preload_thread_count = 0;
-static Eina_List *_evas_preload_thread_data = NULL;
-static Eina_List *_evas_preload_thread = NULL;
+static int _threads_count = 0;
+static Eina_List *_workers = NULL;
 
 static LK(_mutex) = PTHREAD_MUTEX_INITIALIZER;
 
 static void
-_evas_preload_thread_end(Evas_Preload_Pthread_Data *pth)
+_evas_preload_thread_end(void *data)
 {
-   Evas_Preload_Pthread_Data *p;
-
-   if (pthread_join(pth->thread, (void **) &p) != 0)
-     return ;
+   Evas_Preload_Pthread_Data *pth = data;
+   Evas_Preload_Pthread_Data *p = NULL;
 
-   _evas_preload_thread = eina_list_remove(_evas_preload_thread, pth);
+   if (pthread_join(pth->thread, (void **)&p) != 0) free(p);
 }
 
 static void
 _evas_preload_thread_done(void *target __UNUSED__, Evas_Callback_Type type __UNUSED__, void *event_info)
 {
-   Evas_Preload_Pthread_Worker *work;
-
-   work = event_info;
-
+   Evas_Preload_Pthread_Worker *work = event_info;
    if (work->cancel)
      {
-       if (work->func_cancel)
-         work->func_cancel((void *) work->data);
+       if (work->func_cancel) work->func_cancel(work->data);
      }
    else
-     {
-       work->func_end((void *) work->data);
-     }
-
+      work->func_end(work->data);
    free(work);
 }
 
 static void *
-_evas_preload_thread_worker(Evas_Preload_Pthread_Data *pth)
+_evas_preload_thread_worker(void *data)
 {
+   Evas_Preload_Pthread_Data *pth = data;
    Evas_Preload_Pthread_Worker *work;
-
+   
    pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
    pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL);
-
- on_error:
-
-   while (_evas_preload_thread_data)
+on_error:
+   for (;;)
      {
        LKL(_mutex);
-
-       if (!_evas_preload_thread_data)
+       if (!_workers)
          {
             LKU(_mutex);
             break;
          }
 
-       work = eina_list_data_get(_evas_preload_thread_data);
-       _evas_preload_thread_data = eina_list_remove_list(_evas_preload_thread_data, _evas_preload_thread_data);
+       work = eina_list_data_get(_workers);
+       _workers = eina_list_remove_list(_workers, _workers);
 
        LKU(_mutex);
 
-       work->func_heavy((void *) work->data);
-
+       if (work->func_heavy) work->func_heavy(work->data);
        evas_async_events_put(pth, 0, work, _evas_preload_thread_done);
      }
 
    LKL(_mutex);
-   if (_evas_preload_thread_data)
+   if (_workers)
      {
        LKU(_mutex);
        goto on_error;
      }
-   _evas_preload_thread_count--;
+   _threads_count--;
 
    LKU(_mutex);
 
-   work = malloc(sizeof (Evas_Preload_Pthread_Worker));
+   // dummy worker to wake things up
+   work = malloc(sizeof(Evas_Preload_Pthread_Worker));
    if (!work) return NULL;
 
    work->data = pth;
@@ -135,9 +120,8 @@ _evas_preload_thread_worker(Evas_Preload_Pthread_Data *pth)
 void
 _evas_preload_thread_init(void)
 {
-   _evas_preload_thread_count_max = eina_cpu_count();
-   if (_evas_preload_thread_count_max <= 0)
-     _evas_preload_thread_count_max = 1;
+   _threads_max = eina_cpu_count();
+   if (_threads_max <= 0) _threads_max = 1;
 }
 
 void
@@ -153,22 +137,13 @@ _evas_preload_thread_shutdown(void)
 
    LKL(_mutex);
 
-   EINA_LIST_FREE(_evas_preload_thread_data, work)
+   EINA_LIST_FREE(_workers, work)
      {
-       if (work->func_cancel)
-         work->func_cancel((void *)work->data);
+       if (work->func_cancel) work->func_cancel(work->data);
        free(work);
      }
-
+   
    LKU(_mutex);
-
-   EINA_LIST_FREE(_evas_preload_thread, pth)
-     {
-       Evas_Preload_Pthread_Data *p;
-
-       pthread_cancel(pth->thread);
-       pthread_join(pth->thread, (void **) &p);
-     }
 #endif
 }
 
@@ -182,7 +157,7 @@ evas_preload_thread_run(void (*func_heavy) (void *data),
    Evas_Preload_Pthread_Worker *work;
    Evas_Preload_Pthread_Data *pth;
 
-   work = malloc(sizeof (Evas_Preload_Pthread_Worker));
+   work = malloc(sizeof(Evas_Preload_Pthread_Worker));
    if (!work)
      {
        func_cancel((void *)data);
@@ -193,25 +168,24 @@ evas_preload_thread_run(void (*func_heavy) (void *data),
    work->func_end = func_end;
    work->func_cancel = func_cancel;
    work->cancel = EINA_FALSE;
-   work->data = data;
+   work->data = (void *)data;
 
    LKL(_mutex);
-   _evas_preload_thread_data = eina_list_append(_evas_preload_thread_data, work);
+   _workers = eina_list_append(_workers, work);
 
-   if (_evas_preload_thread_count == _evas_preload_thread_count_max)
+   if (_threads_count == _threads_max)
      {
        pthread_mutex_unlock(&_mutex);
-       return (Evas_Preload_Pthread*) work;
+       return (Evas_Preload_Pthread *)work;
      }
 
    LKU(_mutex);
 
    /* One more thread could be created. */
-   pth = malloc(sizeof (Evas_Preload_Pthread_Data));
-   if (!pth)
-     goto on_error;
-
-   if (pthread_create(&pth->thread, NULL, (void *) _evas_preload_thread_worker, pth) == 0)
+   pth = malloc(sizeof(Evas_Preload_Pthread_Data));
+   if (!pth) goto on_error;
+   
+   if (pthread_create(&pth->thread, NULL, _evas_preload_thread_worker, pth) == 0)
      {
 #ifdef __linux__
         struct sched_param param;
@@ -239,27 +213,25 @@ evas_preload_thread_run(void (*func_heavy) (void *data),
 #endif
 
        LKL(_mutex);
-       _evas_preload_thread_count++;
+       _threads_count++;
        LKU(_mutex);
-       return (Evas_Preload_Pthread*) work;
+       return (Evas_Preload_Pthread*)work;
      }
 
  on_error:
-   if (_evas_preload_thread_count == 0)
+   if (_threads_count == 0)
      {
-       if (work->func_cancel)
-         work->func_cancel((void *) work->data);
+       if (work->func_cancel) work->func_cancel(work->data);
        free(work);
      }
    return NULL;
 #else
    /*
-     If no thread and as we don't want to break app that rely on this
-     facility, we will lock the interface until we are done.
+    If no thread and as we don't want to break app that rely on this
+    facility, we will lock the interface until we are done.
     */
-   func_heavy((void *) data);
-   func_end((void *) data);
-
+   func_heavy((void *)data);
+   func_end((void *)data);
    return EINA_TRUE;
 #endif
 }
@@ -272,25 +244,21 @@ evas_preload_thread_cancel(Evas_Preload_Pthread *thread)
    Eina_List *l;
 
    LKL(_mutex);
-
-   EINA_LIST_FOREACH(_evas_preload_thread_data, l, work)
-     if ((void *) work == (void *) thread)
-       {
-         _evas_preload_thread_data = eina_list_remove_list(_evas_preload_thread_data, l);
-
-         LKU(_mutex);
-
-         if (work->func_cancel)
-           work->func_cancel((void *) work->data);
-         free(work);
-
-         return EINA_TRUE;
-       }
-
+   EINA_LIST_FOREACH(_workers, l, work)
+     {
+        if (work == (Evas_Preload_Pthread_Worker *)thread)
+          {
+             _workers = eina_list_remove_list(_workers, l);
+             LKU(_mutex);
+             if (work->func_cancel) work->func_cancel(work->data);
+             free(work);
+             return EINA_TRUE;
+          }
+     }
    LKU(_mutex);
-
+   
    /* Delay the destruction */
-   work = (Evas_Preload_Pthread_Worker *) thread;
+   work = (Evas_Preload_Pthread_Worker *)thread;
    work->cancel = EINA_TRUE;
    return EINA_FALSE;
 #else