discomfitor pushed a commit to branch master.

http://git.enlightenment.org/core/efl.git/commit/?id=bea602f258092f109b9dc55190358909f58bddfb

commit bea602f258092f109b9dc55190358909f58bddfb
Author: Mike Blumenkrantz <[email protected]>
Date:   Fri Jun 22 15:49:34 2018 -0400

    evas/thread_render: improve thread safety
    
    this resolves some invalid read/write operations between threads without 
locking
    and also attempts to improve thread-related behavior after fork() calls
    
    ref T7027
    
    Differential Revision: https://phab.enlightenment.org/D6370
---
 src/lib/evas/common/evas_thread_render.c | 29 +++++++++++++++++++++++++----
 1 file changed, 25 insertions(+), 4 deletions(-)

diff --git a/src/lib/evas/common/evas_thread_render.c 
b/src/lib/evas/common/evas_thread_render.c
index c823125f69..a4db5f22c7 100644
--- a/src/lib/evas/common/evas_thread_render.c
+++ b/src/lib/evas/common/evas_thread_render.c
@@ -11,7 +11,8 @@ static Eina_Inarray evas_thread_queue;
 static Evas_Thread_Command *evas_thread_queue_cache = NULL;
 static unsigned int evas_thread_queue_cache_max = 0;
 
-static volatile int evas_thread_exited = 0;
+static Eina_Lock evas_thread_exited_lock;
+static int evas_thread_exited = 0;
 static Eina_Bool exit_thread = EINA_FALSE;
 static int init_count = 0;
 
@@ -132,7 +133,7 @@ evas_thread_worker_func(void *data EINA_UNUSED, Eina_Thread 
thread EINA_UNUSED)
                   eina_lock_release(&evas_thread_queue_lock);
                   goto out;
                }
-             eina_condition_wait(&evas_thread_queue_condition);
+             eina_condition_timedwait(&evas_thread_queue_condition, 
SHUTDOWN_TIMEOUT * 0.75);
           }
 
         if (!eina_inarray_count(&evas_thread_queue))
@@ -176,14 +177,20 @@ evas_thread_worker_func(void *data EINA_UNUSED, 
Eina_Thread thread EINA_UNUSED)
      }
 
 out:
-   /* WRN: add a memory barrier or use a lock if we add more code here */
+   eina_lock_take(&evas_thread_exited_lock);
    evas_thread_exited = 1;
+   eina_lock_release(&evas_thread_exited_lock);
    return NULL;
 }
 
 static void
 evas_thread_fork_reset(void *data EINA_UNUSED)
 {
+   if (!eina_lock_new(&evas_thread_exited_lock))
+     {
+        CRI("Could not create exit thread lock (%m)");
+        goto on_error;
+     }
    if (!eina_lock_new(&evas_thread_queue_lock))
      {
         CRI("Could not create draw thread lock (%m)");
@@ -205,6 +212,7 @@ evas_thread_fork_reset(void *data EINA_UNUSED)
    return ;
 
  on_error:
+   eina_lock_free(&evas_thread_exited_lock);
    eina_lock_free(&evas_thread_queue_lock);
    eina_condition_free(&evas_thread_queue_condition);
 
@@ -237,6 +245,12 @@ evas_thread_init(void)
 
    eina_inarray_step_set(&evas_thread_queue, sizeof (Eina_Inarray), sizeof 
(Evas_Thread_Command), 128);
 
+   if (!eina_lock_new(&evas_thread_exited_lock))
+     {
+        CRI("Could not create exit thread lock (%m)");
+        goto fail_on_lock_creation;
+     }
+
    if (!eina_lock_new(&evas_thread_queue_lock))
      {
         CRI("Could not create draw thread lock (%m)");
@@ -263,6 +277,7 @@ fail_on_thread_creation:
    evas_thread_worker = 0;
    eina_condition_free(&evas_thread_queue_condition);
 fail_on_cond_creation:
+   eina_lock_free(&evas_thread_exited_lock);
    eina_lock_free(&evas_thread_queue_lock);
 fail_on_lock_creation:
    eina_threads_shutdown();
@@ -300,8 +315,13 @@ evas_thread_shutdown(void)
    eina_lock_release(&evas_thread_queue_lock);
 
    _shutdown_timeout(&to, SHUTDOWN_TIMEOUT_RESET, SHUTDOWN_TIMEOUT);
-   while (!evas_thread_exited && (evas_async_events_process() != -1))
+   while (1)
      {
+        int exited;
+        eina_lock_take(&evas_thread_exited_lock);
+        exited = evas_thread_exited;
+        eina_lock_release(&evas_thread_exited_lock);
+        if (exited || (evas_async_events_process() == -1)) break;
         if(_shutdown_timeout(&to, SHUTDOWN_TIMEOUT_CHECK, SHUTDOWN_TIMEOUT))
           {
              CRI("Timeout shutdown thread. Skipping thread_join. Some 
resources could be leaked");
@@ -311,6 +331,7 @@ evas_thread_shutdown(void)
 
    eina_thread_join(evas_thread_worker);
 timeout_shutdown:
+   eina_lock_free(&evas_thread_exited_lock);
    eina_lock_free(&evas_thread_queue_lock);
    eina_condition_free(&evas_thread_queue_condition);
 

-- 


Reply via email to