bu5hm4n pushed a commit to branch master.

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

commit e7e1560e18228905d19e9a34b256fa1a8beb6347
Author: Mike Blumenkrantz <zm...@samsung.com>
Date:   Mon Jul 2 14:14:32 2018 -0400

    eina/debug: rework session thread destruction to avoid deadlock on shutdown
    
    when debugging was active, this would frequently result in the monitor 
thread
    blocking in a read() call for a fd which had already been closed by the main
    thread. the main thread would be waiting for the monitor thread to fail its 
read()
    and destroy itself, but the read() would never end without an interrupt
    
    this reworks the monitor thread destruction to stop relying on the thread to
    remove its session from the session list and instead only access the list 
from
    the main thread, allowing sessions to always be immediately destroyed
    
    fix T7103
---
 src/lib/eina/eina_debug.c | 31 ++++++++++++++++---------------
 1 file changed, 16 insertions(+), 15 deletions(-)

diff --git a/src/lib/eina/eina_debug.c b/src/lib/eina/eina_debug.c
index 6420496786..dbce08d04a 100644
--- a/src/lib/eina/eina_debug.c
+++ b/src/lib/eina/eina_debug.c
@@ -132,6 +132,8 @@ struct _Eina_Debug_Session
    void *data; /* User data */
    int cbs_length; /* cbs table size */
    int fd; /* File descriptor */
+   Eina_Lock lock; /* deletion lock */
+   Eina_Bool deleted : 1; /* set if session is dead */
 };
 
 #ifndef _WIN32
@@ -271,6 +273,17 @@ eina_debug_session_terminate(Eina_Debug_Session *session)
    /* Close fd here so the thread terminates its own session by itself */
    if (!session) return;
    close(session->fd);
+   eina_lock_take(&session->lock);
+   if (session->deleted)
+     {
+        eina_lock_release(&session->lock);
+        free(session);
+     }
+   else
+     {
+        session->deleted = 1;
+        eina_lock_release(&session->lock);
+     }
 }
 
 EAPI void
@@ -451,6 +464,7 @@ _session_create(int fd)
    if (!session) return NULL;
    session->dispatch_cb = eina_debug_dispatch;
    session->fd = fd;
+   eina_lock_new(&session->lock);
    eina_spinlock_take(&_thread_delete_lock);
    sessions = eina_list_append(sessions, session);
    eina_spinlock_release(&_thread_delete_lock);
@@ -586,12 +600,8 @@ _monitor(void *_data)
           }
         else
           {
-             close(session->fd);
              _opcodes_unregister_all(session);
-             eina_spinlock_take(&_thread_delete_lock);
-             sessions = eina_list_remove(sessions, session);
-             free(session);
-             eina_spinlock_release(&_thread_delete_lock);
+             eina_debug_session_terminate(session);
              break;
           }
      }
@@ -736,22 +746,13 @@ Eina_Bool
 eina_debug_shutdown(void)
 {
    Eina_Debug_Session *session;
-   Eina_List *l;
    pthread_t self = pthread_self();
 
    eina_spinlock_take(&_thread_delete_lock);
-   EINA_LIST_FOREACH(sessions, l, session)
+   EINA_LIST_FREE(sessions, session)
      eina_debug_session_terminate(session);
    eina_spinlock_release(&_thread_delete_lock);
 
-   while (1)
-     {
-        eina_spinlock_take(&_thread_delete_lock);
-        if (!sessions) break;
-        eina_spinlock_release(&_thread_delete_lock);
-     }
-   eina_spinlock_release(&_thread_delete_lock);
-
    _eina_debug_timer_shutdown();
    _eina_debug_bt_shutdown();
    _eina_debug_cpu_shutdown();

-- 


Reply via email to