@@ -167,9 +167,13 @@ static void *connect_thread_func(void *opaque)
uint64_t timeout = 1;
uint64_t max_timeout = 16;
- while (true) {
+ qemu_mutex_lock(&conn->mutex);
+ while (!conn->detached) {
+ assert(!conn->sioc);
conn->sioc = qio_channel_socket_new();
+ qemu_mutex_unlock(&conn->mutex);
+
error_free(conn->err);
conn->err = NULL;
conn->updated_info = conn->initial_info;
@@ -187,14 +191,20 @@ static void *connect_thread_func(void *opaque)
conn->updated_info.x_dirty_bitmap = NULL;
conn->updated_info.name = NULL;
+ qemu_mutex_lock(&conn->mutex);
+
if (ret < 0) {
object_unref(OBJECT(conn->sioc));
conn->sioc = NULL;
- if (conn->do_retry) {
+ if (conn->do_retry && !conn->detached) {
+ qemu_mutex_unlock(&conn->mutex);
+
sleep(timeout);
if (timeout < max_timeout) {
timeout *= 2;
}
+
+ qemu_mutex_lock(&conn->mutex);
continue;
}
}
@@ -202,7 +212,7 @@ static void *connect_thread_func(void *opaque)
break;
}
- qemu_mutex_lock(&conn->mutex);
+ /* mutex is locked */
assert(conn->running);
conn->running = false;
@@ -236,6 +246,10 @@ void nbd_client_connection_release(NBDClientConnection *conn)
} else {
do_free = true;
}
+ if (conn->sioc) {
+ qio_channel_shutdown(QIO_CHANNEL(conn->sioc),
+ QIO_CHANNEL_SHUTDOWN_BOTH, NULL);
+ }
}
if (do_free) {
Now, when a thread can do negotiation and retry, it may run relatively long. We need a mechanism to stop it, when the user is not interested in a result any more. So, on nbd_client_connection_release() let's shutdown the socket, and do not retry connection if thread is detached. Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com> --- nbd/client-connection.c | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-)