opencryptoki/opencryptoki-3.17-avoid-deadlock-when-stopping-event-thread.patch

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;
}