Actually, the only bit of information we need is "is thread running or not". We don't need all these states. So, instead of thr->state add boolean variable thr->running and refactor the code.
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsement...@virtuozzo.com> --- block/nbd.c | 103 ++++++++++++++-------------------------------------- 1 file changed, 27 insertions(+), 76 deletions(-) diff --git a/block/nbd.c b/block/nbd.c index 4e28982e53..85c20e7810 100644 --- a/block/nbd.c +++ b/block/nbd.c @@ -66,18 +66,6 @@ typedef enum NBDClientState { NBD_CLIENT_QUIT } NBDClientState; -typedef enum NBDConnectThreadState { - /* No thread, no pending results */ - CONNECT_THREAD_NONE, - - /* Thread is running, no results for now */ - CONNECT_THREAD_RUNNING, - - /* Thread finished, results are stored in a state */ - CONNECT_THREAD_FAIL, - CONNECT_THREAD_SUCCESS -} NBDConnectThreadState; - typedef struct NBDConnectThread { /* Initialization constants */ SocketAddress *saddr; /* address to connect to */ @@ -93,7 +81,7 @@ typedef struct NBDConnectThread { QemuMutex mutex; /* All further fields are protected by mutex */ - NBDConnectThreadState state; /* current state of the thread */ + bool running; /* thread is running now */ Coroutine *wait_co; /* nbd_co_establish_connection() wait in yield() */ } NBDConnectThread; @@ -353,7 +341,6 @@ static void nbd_init_connect_thread(BDRVNBDState *s) *s->connect_thread = (NBDConnectThread) { .saddr = QAPI_CLONE(SocketAddress, s->saddr), - .state = CONNECT_THREAD_NONE, .refcnt = 1, }; @@ -389,16 +376,11 @@ static void *connect_thread_func(void *opaque) qemu_mutex_lock(&thr->mutex); - switch (thr->state) { - case CONNECT_THREAD_RUNNING: - thr->state = ret < 0 ? CONNECT_THREAD_FAIL : CONNECT_THREAD_SUCCESS; - if (thr->wait_co) { - aio_co_wake(thr->wait_co); - thr->wait_co = NULL; - } - break; - default: - abort(); + assert(thr->running); + thr->running = false; + if (thr->wait_co) { + aio_co_wake(thr->wait_co); + thr->wait_co = NULL; } qemu_mutex_unlock(&thr->mutex); @@ -411,37 +393,25 @@ static void *connect_thread_func(void *opaque) static int coroutine_fn nbd_co_establish_connection(BlockDriverState *bs, Error **errp) { - int ret; QemuThread thread; BDRVNBDState *s = bs->opaque; NBDConnectThread *thr = s->connect_thread; + assert(!s->sioc); + qemu_mutex_lock(&thr->mutex); - switch (thr->state) { - case CONNECT_THREAD_FAIL: - case CONNECT_THREAD_NONE: + if (!thr->running) { + if (thr->sioc) { + /* Previous attempt finally succeeded in background */ + goto out; + } + thr->running = true; error_free(thr->err); thr->err = NULL; - thr->state = CONNECT_THREAD_RUNNING; qatomic_inc(&thr->refcnt); /* for thread */ qemu_thread_create(&thread, "nbd-connect", connect_thread_func, thr, QEMU_THREAD_DETACHED); - break; - case CONNECT_THREAD_SUCCESS: - /* Previous attempt finally succeeded in background */ - thr->state = CONNECT_THREAD_NONE; - s->sioc = thr->sioc; - thr->sioc = NULL; - yank_register_function(BLOCKDEV_YANK_INSTANCE(bs->node_name), - nbd_yank, bs); - qemu_mutex_unlock(&thr->mutex); - return 0; - case CONNECT_THREAD_RUNNING: - /* Already running, will wait */ - break; - default: - abort(); } thr->wait_co = qemu_coroutine_self(); @@ -456,10 +426,15 @@ nbd_co_establish_connection(BlockDriverState *bs, Error **errp) qemu_mutex_lock(&thr->mutex); - switch (thr->state) { - case CONNECT_THREAD_SUCCESS: - case CONNECT_THREAD_FAIL: - thr->state = CONNECT_THREAD_NONE; +out: + if (thr->running) { + /* + * Obviously, drained section wants to start. Report the attempt as + * failed. Still connect thread is executing in background, and its + * result may be used for next connection attempt. + */ + error_setg(errp, "Connection attempt cancelled by other operation"); + } else { error_propagate(errp, thr->err); thr->err = NULL; s->sioc = thr->sioc; @@ -468,32 +443,11 @@ nbd_co_establish_connection(BlockDriverState *bs, Error **errp) yank_register_function(BLOCKDEV_YANK_INSTANCE(bs->node_name), nbd_yank, bs); } - ret = (s->sioc ? 0 : -1); - break; - case CONNECT_THREAD_RUNNING: - /* - * Obviously, drained section wants to start. Report the attempt as - * failed. Still connect thread is executing in background, and its - * result may be used for next connection attempt. - */ - ret = -1; - error_setg(errp, "Connection attempt cancelled by other operation"); - break; - - case CONNECT_THREAD_NONE: - /* - * Impossible. We've seen this thread running. So it should be - * running or at least give some results. - */ - abort(); - - default: - abort(); } qemu_mutex_unlock(&thr->mutex); - return ret; + return s->sioc ? 0 : -1; } /* @@ -508,12 +462,9 @@ static void nbd_co_establish_connection_cancel(BlockDriverState *bs) qemu_mutex_lock(&thr->mutex); - if (thr->state == CONNECT_THREAD_RUNNING) { - /* We can cancel only in running state, when bh is not yet scheduled */ - if (thr->wait_co) { - aio_co_wake(thr->wait_co); - thr->wait_co = NULL; - } + if (thr->wait_co) { + aio_co_wake(thr->wait_co); + thr->wait_co = NULL; } qemu_mutex_unlock(&thr->mutex); -- 2.29.2