summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Blumenkrantz <zmike@samsung.com>2018-07-02 14:14:32 -0400
committerMike Blumenkrantz <zmike@samsung.com>2018-07-03 09:48:15 -0400
commitba37744f61a91387a349498d34d422a99fd05067 (patch)
tree6b446c9b4afe768275c782bc73432d9ad4946a92
parent039818aec299ca1c58909cd5e5b5fcc759ed43b7 (diff)
downloadefl-ba37744f61a91387a349498d34d422a99fd05067.tar.gz
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
-rw-r--r--src/lib/eina/eina_debug.c31
1 files 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();