From 13595495a16935a7b4a3206ea995501cabf6606f Mon Sep 17 00:00:00 2001 From: Shuhei Matsumoto Date: Mon, 10 Feb 2020 18:00:30 -0500 Subject: [PATCH] lib/thread: Stop new I/O channel after thread is marked as exited This is a preparation to support voluntary thread termination by calling spdk_thread_exit(). By the last patch, the asynchronous release of I/O channel will complete even after spdk_thread_exit() because pending messages will be reaped. Then this patch stops new allocation of I/O channel after spdk_thread_exit(). Hence we will be able to release all I/O channels for exiting thread within finite time. Signed-off-by: Shuhei Matsumoto Change-Id: I48a45bcba7c4b2c62d8c9d398ac35a584b533627 Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/821 Tested-by: SPDK CI Jenkins Reviewed-by: Ben Walker Reviewed-by: Aleksey Marchuk --- lib/thread/thread.c | 6 ++++++ test/unit/lib/thread/thread.c/thread_ut.c | 4 ++++ 2 files changed, 10 insertions(+) diff --git a/lib/thread/thread.c b/lib/thread/thread.c index b2ae25588..65ddd5bde 100644 --- a/lib/thread/thread.c +++ b/lib/thread/thread.c @@ -1140,6 +1140,12 @@ spdk_get_io_channel(void *io_device) return NULL; } + if (spdk_unlikely(thread->exit)) { + SPDK_ERRLOG("Thread %s is marked as exited\n", thread->name); + pthread_mutex_unlock(&g_devlist_mutex); + return NULL; + } + TAILQ_FOREACH(ch, &thread->io_channels, tailq) { if (ch->dev == dev) { ch->ref++; diff --git a/test/unit/lib/thread/thread.c/thread_ut.c b/test/unit/lib/thread/thread.c/thread_ut.c index 407bfc05d..c3b5d19d3 100644 --- a/test/unit/lib/thread/thread.c/thread_ut.c +++ b/test/unit/lib/thread/thread.c/thread_ut.c @@ -801,6 +801,10 @@ thread_exit(void) thread = spdk_get_thread(); spdk_thread_exit(thread); + /* Thread will not be able to get I/O channel after it is marked as exited. */ + ch = spdk_get_io_channel(&g_device1); + CU_ASSERT(ch == NULL); + poll_threads(); CU_ASSERT(g_destroy_cb_calls == 1);