65 lines
2.4 KiB
Diff
65 lines
2.4 KiB
Diff
|
commit fed25d1f2f3fe43eb8f55f66e39b7f4dfdad2226
|
||
|
Author: Ingo Franzki <ifranzki@linux.ibm.com>
|
||
|
Date: Mon Feb 21 13:31:20 2022 +0100
|
||
|
|
||
|
API: Avoid deadlock when stopping event thread
|
||
|
|
||
|
Avoid that the event thread writes trace messages while it is
|
||
|
enabled for thread cancellation. This might leave the trace mutex in
|
||
|
the locked state and cause subsequent trace calls to lock forever
|
||
|
(e.g in stop_event_thread() right after canceling the thread).
|
||
|
|
||
|
Disable cancellation right at the beginning of the thread function,
|
||
|
and disable it before calling a trace function or leaving the loop.
|
||
|
|
||
|
Also make sure that the cleanup handler is registered and the
|
||
|
cancellation type is set before initially enabling cancellation.
|
||
|
|
||
|
Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
|
||
|
|
||
|
diff --git a/usr/lib/api/socket_client.c b/usr/lib/api/socket_client.c
|
||
|
index cbe55dce..62a8ec20 100644
|
||
|
--- a/usr/lib/api/socket_client.c
|
||
|
+++ b/usr/lib/api/socket_client.c
|
||
|
@@ -284,6 +284,8 @@ static void *event_thread(void *arg)
|
||
|
|
||
|
UNUSED(arg);
|
||
|
|
||
|
+ pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &oldstate);
|
||
|
+
|
||
|
TRACE_DEVEL("Event thread %lu running\n", pthread_self());
|
||
|
|
||
|
if (anchor->socketfd < 0) {
|
||
|
@@ -303,13 +305,13 @@ static void *event_thread(void *arg)
|
||
|
#endif
|
||
|
|
||
|
/* Enable cancellation */
|
||
|
- pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, &oldstate);
|
||
|
- pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, &oldtype);
|
||
|
cleanup.anchor = anchor;
|
||
|
#if OPENSSL_VERSION_PREREQ(3, 0)
|
||
|
cleanup.prev_libctx = prev_libctx;
|
||
|
#endif
|
||
|
pthread_cleanup_push(event_thread_cleanup, &cleanup);
|
||
|
+ pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, &oldtype);
|
||
|
+ pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, &oldstate);
|
||
|
|
||
|
pollfd.fd = anchor->socketfd;
|
||
|
pollfd.events = POLLIN | POLLHUP | POLLERR;
|
||
|
@@ -320,6 +322,7 @@ static void *event_thread(void *arg)
|
||
|
if (rc < 0) {
|
||
|
if (errno == EINTR)
|
||
|
continue;
|
||
|
+ pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &oldstate);
|
||
|
TRACE_ERROR("poll failed: %d\n", errno);
|
||
|
break;
|
||
|
}
|
||
|
@@ -328,6 +331,7 @@ static void *event_thread(void *arg)
|
||
|
continue;
|
||
|
|
||
|
if (pollfd.revents & (POLLHUP | POLLERR)) {
|
||
|
+ pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &oldstate);
|
||
|
TRACE_ERROR("Error on socket, possibly closed by slot daemon\n");
|
||
|
break;
|
||
|
}
|