From b9739cc07022454c05568fd46947481d81dfd95d Mon Sep 17 00:00:00 2001 From: Benjamin Menkuec Date: Tue, 5 Nov 2024 19:04:28 +0100 Subject: [PATCH 01/38] wip --- buffer.c | 7 +++++++ iiod-client.c | 4 ++++ iiod-responder.c | 15 +++++++++++++-- local.c | 1 + network-unix.c | 10 +++++++++- network.c | 11 +++++++++++ task.c | 14 +++++++++++++- 7 files changed, 58 insertions(+), 4 deletions(-) diff --git a/buffer.c b/buffer.c index 6fb407be7..526a9cf36 100644 --- a/buffer.c +++ b/buffer.c @@ -187,16 +187,23 @@ void iio_buffer_destroy(struct iio_buffer *buf) { const struct iio_backend_ops *ops = buf->dev->ctx->ops; + printf("iio_buffer_cancel...\n"); iio_buffer_cancel(buf); + printf("iio_buffer_cancel done\n"); + printf("free_buffer...\n"); if (ops->free_buffer) ops->free_buffer(buf->pdata); + printf("free_buffer done\n"); + printf("iio_task_destroy...\n"); iio_task_destroy(buf->worker); + printf("iio_task_destroy done\n"); iio_mutex_destroy(buf->lock); iio_channels_mask_destroy(buf->mask); free(buf->attrlist.attrs); free(buf); + printf("iio_buffer_destroy done\n"); } const struct iio_channels_mask * diff --git a/iiod-client.c b/iiod-client.c index 6dcbb92ad..e1e8d1d21 100644 --- a/iiod-client.c +++ b/iiod-client.c @@ -303,11 +303,15 @@ struct iiod_client * iiod_client_new(const struct iio_context_params *params, void iiod_client_destroy(struct iiod_client *client) { if (client->responder) { + printf("iiod_client_destroy1\n"); iiod_client_cancel(client); + printf("iiod_client_destroy2\n"); iiod_responder_destroy(client->responder); + printf("iiod_client_destroy3\n"); } iio_mutex_destroy(client->lock); + printf("iiod_client_destroy4\n"); free(client); } diff --git a/iiod-responder.c b/iiod-responder.c index d654602e6..bbd045f61 100644 --- a/iiod-responder.c +++ b/iiod-responder.c @@ -154,8 +154,11 @@ static ssize_t iiod_rw_all(struct iiod_responder *priv, nb = 1; } - if (is_read) + if (is_read) { + printf("read...\n"); ret = priv->ops->read(priv->d, curr, nb); + printf("read done\n"); + } else ret = priv->ops->write(priv->d, curr, nb); if (ret <= 0) @@ -705,12 +708,17 @@ void iiod_responder_stop(struct iiod_responder *priv) void iiod_responder_destroy(struct iiod_responder *priv) { + printf("iiod_responder_destroy1\n"); iiod_responder_stop(priv); + printf("iiod_responder_destroy2\n"); iiod_responder_wait_done(priv); + printf("iiod_responder_destroy3\n"); iio_task_destroy(priv->write_task); + printf("iiod_responder_destroy4\n"); iiod_io_unref(priv->default_io); + printf("iiod_responder_destroy5\n"); iio_mutex_destroy(priv->lock); free(priv); } @@ -718,8 +726,11 @@ void iiod_responder_destroy(struct iiod_responder *priv) void iiod_responder_wait_done(struct iiod_responder *priv) { if (!NO_THREADS) { - if (priv->read_thrd) + if (priv->read_thrd) { + printf("iio_thrd_join_and_destroy...\n "); iio_thrd_join_and_destroy(priv->read_thrd); + printf("iio_thrd_join_and_destroy done\n "); + } priv->read_thrd = NULL; } else if (!priv->thrd_stop) { iiod_responder_reader_worker(priv); diff --git a/local.c b/local.c index 9322c4b67..06295d8bf 100644 --- a/local.c +++ b/local.c @@ -1547,6 +1547,7 @@ local_create_buffer(const struct iio_device *dev, unsigned int idx, static void local_free_buffer(struct iio_buffer_pdata *pdata) { + printf("local_free_buffer\n"); free(pdata->pdata); local_close_fd(pdata->dev, pdata->fd); close(pdata->cancel_fd); diff --git a/network-unix.c b/network-unix.c index 9d26a84e6..294787d23 100644 --- a/network-unix.c +++ b/network-unix.c @@ -76,6 +76,7 @@ static int create_cancel_fd(struct iiod_client_pdata *io_ctx) void cleanup_cancel(struct iiod_client_pdata *io_ctx) { + printf("cleanup_cancel\n"); close(io_ctx->cancel_fd[0]); if (!WITH_NETWORK_EVENTFD) close(io_ctx->cancel_fd[1]); @@ -90,6 +91,7 @@ int setup_cancel(struct iiod_client_pdata *io_ctx) void do_cancel(struct iiod_client_pdata *io_ctx) { + printf("do cancel...\n"); uint64_t event = 1; int ret; @@ -98,7 +100,9 @@ void do_cancel(struct iiod_client_pdata *io_ctx) /* If this happens something went very seriously wrong */ prm_perror(io_ctx->params, -errno, "Unable to signal cancellation event"); + printf("do cancel error!\n"); } + printf("do cancel done\n"); } int wait_cancellable(struct iiod_client_pdata *io_ctx, @@ -116,18 +120,22 @@ int wait_cancellable(struct iiod_client_pdata *io_ctx, else pfd[0].events = POLLOUT; pfd[1].fd = io_ctx->cancel_fd[0]; - pfd[1].events = POLLIN; + pfd[1].events = POLLIN | POLLPRI | POLLHUP | POLLERR; do { do { ret = poll(pfd, 2, timeout); } while (ret == -1 && errno == EINTR); + printf("pfd[0].revents = %d, pfd[1].revents = %d, ret = %d\n",pfd[0].revents,pfd[1].revents, ret); if (ret == -1) return -errno; if (!ret) return -ETIMEDOUT; + if (pfd[0].revents & POLLHUP) + return -EBADF; + if (pfd[1].revents & POLLIN) return -EBADF; } while (!(pfd[0].revents & (pfd[0].events | POLLERR | POLLHUP))); diff --git a/network.c b/network.c index 9028bcba0..48f58bfa6 100644 --- a/network.c +++ b/network.c @@ -88,6 +88,7 @@ static const struct iiod_client_ops network_iiod_client_ops = { static ssize_t network_recv(struct iiod_client_pdata *io_ctx, void *data, size_t len, int flags, unsigned int timeout_ms) { + printf("network_recv...\n"); bool cancellable = true; ssize_t ret; int err; @@ -95,13 +96,16 @@ static ssize_t network_recv(struct iiod_client_pdata *io_ctx, void *data, #ifdef __linux__ cancellable &= !(flags & MSG_DONTWAIT); #endif + printf("cancellable = %d\n", cancellable); while (1) { + printf("wait_cancellable...\n"); if (cancellable) { ret = wait_cancellable(io_ctx, true, timeout_ms); if (ret < 0) return ret; } + printf("wait_cancellable done\n"); ret = recv(io_ctx->fd, data, (int) len, flags); if (ret == 0) @@ -119,6 +123,7 @@ static ssize_t network_recv(struct iiod_client_pdata *io_ctx, void *data, return (ssize_t) err; } } + printf("network_recv done\n"); return ret; } @@ -362,8 +367,11 @@ network_setup_iiod_client(const struct iio_device *dev, static void network_free_iiod_client(struct iiod_client *client, struct iiod_client_pdata *io_ctx) { + printf("network_free_iiod_client1\n"); iiod_client_destroy(client); + printf("network_free_iiod_client2\n"); cleanup_cancel(io_ctx); + printf("network_free_iiod_client3\n"); close(io_ctx->fd); io_ctx->fd = -1; } @@ -480,8 +488,11 @@ network_create_buffer(const struct iio_device *dev, unsigned int idx, void network_free_buffer(struct iio_buffer_pdata *pdata) { + printf("free1\n"); iiod_client_free_buffer(pdata->pdata); + printf("free2\n"); network_free_iiod_client(pdata->iiod_client, &pdata->io_ctx); + printf("free3\n"); free(pdata); } diff --git a/task.c b/task.c index b08a8eafb..7dfca4528 100644 --- a/task.c +++ b/task.c @@ -52,13 +52,17 @@ static void iio_task_process(struct iio_task *task) iio_cond_signal(task->cond); while (!task->stop && !(task->list && task->running)) { + printf("task stop: %d %d id: %d\n", task->stop, task->running, task->thrd); iio_cond_wait(task->cond, task->lock, 0); + printf("b ts: %d %d\n", task->stop, task->running); /* If iio_task_stop() was called while we were waiting * for clients, notify that we're idle. */ if (!task->running) iio_cond_signal(task->cond); + printf("c ts: %d %d\n", task->stop, task->running); } + printf("x1\n"); if (task->stop) return; @@ -79,6 +83,7 @@ static void iio_task_process(struct iio_task *task) iio_task_token_destroy(entry); iio_mutex_lock(task->lock); + printf("x2\n"); } static int iio_task_run(void *d) @@ -98,6 +103,7 @@ static int iio_task_run(void *d) struct iio_task * iio_task_create(int (*fn)(void *, void *), void *firstarg, const char *name) { + printf("iio_task_create\n"); struct iio_task *task; int err = -ENOMEM; @@ -253,6 +259,7 @@ void iio_task_flush(struct iio_task *task) int iio_task_destroy(struct iio_task *task) { + printf("iio_task_destroy\n"); int ret = 0; iio_mutex_lock(task->lock); @@ -260,8 +267,11 @@ int iio_task_destroy(struct iio_task *task) iio_cond_signal(task->cond); iio_mutex_unlock(task->lock); - if (!NO_THREADS) + if (!NO_THREADS) { + printf("waiting for join...\n"); ret = iio_thrd_join_and_destroy(task->thrd); + printf("joined\n"); + } iio_task_flush(task); @@ -326,8 +336,10 @@ void iio_task_start(struct iio_task *task) void iio_task_stop(struct iio_task *task) { + printf("task_stop\n"); iio_mutex_lock(task->lock); task->running = false; + // task->stop = true; iio_cond_signal(task->cond); iio_cond_wait(task->cond, task->lock, 0); iio_mutex_unlock(task->lock); From 557abdac90bb90664c4b8d897561eed8f4c0cce8 Mon Sep 17 00:00:00 2001 From: Benjamin Menkuec Date: Tue, 5 Nov 2024 20:06:40 +0100 Subject: [PATCH 02/38] wip with hack that seems to work --- buffer.c | 2 +- network-unix.c | 8 +++----- network.c | 4 ++-- 3 files changed, 6 insertions(+), 8 deletions(-) diff --git a/buffer.c b/buffer.c index 526a9cf36..c8bbcd63b 100644 --- a/buffer.c +++ b/buffer.c @@ -34,11 +34,11 @@ void iio_buffer_cancel(struct iio_buffer *buf) { const struct iio_backend_ops *ops = buf->dev->ctx->ops; - iio_task_stop(buf->worker); if (ops->cancel_buffer) ops->cancel_buffer(buf->pdata); + iio_task_stop(buf->worker); iio_task_flush(buf->worker); } diff --git a/network-unix.c b/network-unix.c index 294787d23..03d4e9896 100644 --- a/network-unix.c +++ b/network-unix.c @@ -42,6 +42,7 @@ static int create_cancel_fd(struct iiod_client_pdata *io_ctx) io_ctx->cancel_fd[0] = eventfd(0, EFD_CLOEXEC | EFD_NONBLOCK); if (io_ctx->cancel_fd[0] < 0) return -errno; + printf("created cancel_fd %d\n", io_ctx->cancel_fd[0]); return 0; } @@ -91,10 +92,9 @@ int setup_cancel(struct iiod_client_pdata *io_ctx) void do_cancel(struct iiod_client_pdata *io_ctx) { - printf("do cancel...\n"); + printf("do cancel... fd = %d\n", io_ctx->cancel_fd[0]); uint64_t event = 1; int ret; - ret = write(io_ctx->cancel_fd[CANCEL_WR_FD], &event, sizeof(event)); if (ret == -1) { /* If this happens something went very seriously wrong */ @@ -121,6 +121,7 @@ int wait_cancellable(struct iiod_client_pdata *io_ctx, pfd[0].events = POLLOUT; pfd[1].fd = io_ctx->cancel_fd[0]; pfd[1].events = POLLIN | POLLPRI | POLLHUP | POLLERR; + printf("poll cancel_fd %d\n", pfd[1].fd); do { do { @@ -133,9 +134,6 @@ int wait_cancellable(struct iiod_client_pdata *io_ctx, if (!ret) return -ETIMEDOUT; - if (pfd[0].revents & POLLHUP) - return -EBADF; - if (pfd[1].revents & POLLIN) return -EBADF; } while (!(pfd[0].revents & (pfd[0].events | POLLERR | POLLHUP))); diff --git a/network.c b/network.c index 48f58bfa6..98b112666 100644 --- a/network.c +++ b/network.c @@ -367,7 +367,7 @@ network_setup_iiod_client(const struct iio_device *dev, static void network_free_iiod_client(struct iiod_client *client, struct iiod_client_pdata *io_ctx) { - printf("network_free_iiod_client1\n"); + printf("network_free_iiod_client1 cancel_fd = %d\n", io_ctx->cancel_fd[0]); iiod_client_destroy(client); printf("network_free_iiod_client2\n"); cleanup_cancel(io_ctx); @@ -488,7 +488,7 @@ network_create_buffer(const struct iio_device *dev, unsigned int idx, void network_free_buffer(struct iio_buffer_pdata *pdata) { - printf("free1\n"); + printf("free1 fd = %d\n", pdata->io_ctx.cancel_fd[0]); iiod_client_free_buffer(pdata->pdata); printf("free2\n"); network_free_iiod_client(pdata->iiod_client, &pdata->io_ctx); From 6e790c2a52a67d8c6c83bfadb94eff8748dbde9a Mon Sep 17 00:00:00 2001 From: Benjamin Menkuec Date: Tue, 5 Nov 2024 20:11:02 +0100 Subject: [PATCH 03/38] revert hack, it does not work --- buffer.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/buffer.c b/buffer.c index c8bbcd63b..526a9cf36 100644 --- a/buffer.c +++ b/buffer.c @@ -34,11 +34,11 @@ void iio_buffer_cancel(struct iio_buffer *buf) { const struct iio_backend_ops *ops = buf->dev->ctx->ops; + iio_task_stop(buf->worker); if (ops->cancel_buffer) ops->cancel_buffer(buf->pdata); - iio_task_stop(buf->worker); iio_task_flush(buf->worker); } From 611e2d625d5c38e667f3e798aed37a4f33dc401d Mon Sep 17 00:00:00 2001 From: Benjamin Menkuec Date: Tue, 5 Nov 2024 21:14:39 +0100 Subject: [PATCH 04/38] wip --- network-unix.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/network-unix.c b/network-unix.c index 03d4e9896..8dbf51359 100644 --- a/network-unix.c +++ b/network-unix.c @@ -121,7 +121,7 @@ int wait_cancellable(struct iiod_client_pdata *io_ctx, pfd[0].events = POLLOUT; pfd[1].fd = io_ctx->cancel_fd[0]; pfd[1].events = POLLIN | POLLPRI | POLLHUP | POLLERR; - printf("poll cancel_fd %d\n", pfd[1].fd); + printf("poll cancel_fd %d thread = %u\n", pfd[1].fd, pthread_self()); do { do { From 76d551bdc2af8bf56e2573d3624c3be60cd6b233 Mon Sep 17 00:00:00 2001 From: Benjamin Menkuec Date: Wed, 6 Nov 2024 16:15:32 +0100 Subject: [PATCH 05/38] wip --- iiod-responder.c | 69 +++++++++++++++++++++++++++++++++++++++++------- network-unix.c | 4 +-- network.c | 15 +++++------ 3 files changed, 69 insertions(+), 19 deletions(-) diff --git a/iiod-responder.c b/iiod-responder.c index bbd045f61..95e3b839f 100644 --- a/iiod-responder.c +++ b/iiod-responder.c @@ -114,6 +114,16 @@ static void __iiod_io_cancel_unlocked(struct iiod_io *io) struct iiod_io *tmp; /* Discard the entry from the readers list */ + printf("thread = %u, discard reader %d\n", pthread_self(), io); + if (priv->readers) { + for (tmp = priv->readers; tmp->r_next; ) { + if (tmp == tmp->r_next) { + printf("loop detected!!! %d -> %d\n", tmp, tmp->r_next); + exit(1); + } + tmp = tmp->r_next; + } + } if (io == priv->readers) { priv->readers = io->r_next; } else if (priv->readers) { @@ -155,9 +165,9 @@ static ssize_t iiod_rw_all(struct iiod_responder *priv, } if (is_read) { - printf("read...\n"); + printf("thread = %u, read...\n", pthread_self()); ret = priv->ops->read(priv->d, curr, nb); - printf("read done\n"); + printf("thread = %u, read done\n", pthread_self()); } else ret = priv->ops->write(priv->d, curr, nb); @@ -253,6 +263,7 @@ static int iiod_responder_reader_worker(struct iiod_responder *priv) ok_buf.size = 3; iio_mutex_lock(priv->lock); + printf("thread = %u, start reader...\n", pthread_self()); while (!priv->thrd_stop) { iio_mutex_unlock(priv->lock); @@ -271,7 +282,9 @@ static int iiod_responder_reader_worker(struct iiod_responder *priv) continue; } + printf("thread = %u, try lock...\n", pthread_self()); iio_mutex_lock(priv->lock); + printf("thread = %u, locked\n", pthread_self()); if (ret <= 0) break; @@ -280,7 +293,10 @@ static int iiod_responder_reader_worker(struct iiod_responder *priv) ret = iiod_run_command(priv, &cmd); + printf("thread = %u, try lock...\n", pthread_self()); iio_mutex_lock(priv->lock); + printf("thread = %u, locked\n", pthread_self()); + if (ret < 0) break; @@ -298,7 +314,10 @@ static int iiod_responder_reader_worker(struct iiod_responder *priv) * for it, so drop it. */ iio_mutex_unlock(priv->lock); iiod_discard_data(priv, cmd.code); + printf("thread = %u, try lock...\n", pthread_self()); iio_mutex_lock(priv->lock); + printf("thread = %u, locked\n", pthread_self()); + continue; } @@ -331,6 +350,7 @@ static int iiod_responder_reader_worker(struct iiod_responder *priv) iiod_responder_signal_io(io, cmd.code); iiod_io_unref_unlocked(io); } + printf("thread = %u, stop reader...\n", pthread_self()); priv->thrd_err_code = priv->thrd_stop ? -EINTR : (int) ret; priv->thrd_stop = true; @@ -568,12 +588,37 @@ int iiod_io_get_response_async(struct iiod_io *io, io->r_io.start_time = read_counter_us(); /* Add it to the readers list */ - if (!priv->readers) { - priv->readers = io; - } else { - for (tmp = priv->readers; tmp->r_next; ) + printf("thread = %u, adding reader %d\n", pthread_self(), io); + bool found = false; + if (priv->readers) { + for (tmp = priv->readers; tmp->r_next; ) { + if (tmp == io) + { + printf("reader is already in list!!\n"); + found = true; + exit(1); + } + if (tmp == tmp->r_next) { + printf("loop detected!!!\n"); + exit(1); + } tmp = tmp->r_next; - tmp->r_next = io; + } + } + if (!found) { + if (!priv->readers) { + priv->readers = io; + } else { + unsigned int i = 0; + for (tmp = priv->readers; tmp->r_next; ) { + printf("list item %d = %d\n", i++,tmp); + tmp = tmp->r_next; + if (i > 100) exit(1); + } + tmp->r_next = io; + printf("io->r_next = %d\n", io->r_next); + io->r_next = NULL; + } } iio_mutex_unlock(priv->lock); @@ -708,7 +753,7 @@ void iiod_responder_stop(struct iiod_responder *priv) void iiod_responder_destroy(struct iiod_responder *priv) { - printf("iiod_responder_destroy1\n"); + printf("thread = %u, iiod_responder_destroy1\n", pthread_self()); iiod_responder_stop(priv); printf("iiod_responder_destroy2\n"); iiod_responder_wait_done(priv); @@ -723,11 +768,17 @@ void iiod_responder_destroy(struct iiod_responder *priv) free(priv); } +struct iio_thrd { + pthread_t thid; + void *d; + int (*func)(void *); +}; + void iiod_responder_wait_done(struct iiod_responder *priv) { if (!NO_THREADS) { if (priv->read_thrd) { - printf("iio_thrd_join_and_destroy...\n "); + printf("thread = %u, iio_thrd_join_and_destroy thread = %u...\n", pthread_self(), priv->read_thrd->thid); iio_thrd_join_and_destroy(priv->read_thrd); printf("iio_thrd_join_and_destroy done\n "); } diff --git a/network-unix.c b/network-unix.c index 8dbf51359..6c22d675e 100644 --- a/network-unix.c +++ b/network-unix.c @@ -121,13 +121,13 @@ int wait_cancellable(struct iiod_client_pdata *io_ctx, pfd[0].events = POLLOUT; pfd[1].fd = io_ctx->cancel_fd[0]; pfd[1].events = POLLIN | POLLPRI | POLLHUP | POLLERR; - printf("poll cancel_fd %d thread = %u\n", pfd[1].fd, pthread_self()); + printf("thread = %u, poll cancel_fd %d\n", pthread_self(), pfd[1].fd); do { do { ret = poll(pfd, 2, timeout); } while (ret == -1 && errno == EINTR); - printf("pfd[0].revents = %d, pfd[1].revents = %d, ret = %d\n",pfd[0].revents,pfd[1].revents, ret); + printf("thread = %u, pfd[0].revents = %d, pfd[1].revents = %d, ret = %d\n",pthread_self(), pfd[0].revents,pfd[1].revents, ret); if (ret == -1) return -errno; diff --git a/network.c b/network.c index 98b112666..869066878 100644 --- a/network.c +++ b/network.c @@ -88,7 +88,6 @@ static const struct iiod_client_ops network_iiod_client_ops = { static ssize_t network_recv(struct iiod_client_pdata *io_ctx, void *data, size_t len, int flags, unsigned int timeout_ms) { - printf("network_recv...\n"); bool cancellable = true; ssize_t ret; int err; @@ -96,16 +95,16 @@ static ssize_t network_recv(struct iiod_client_pdata *io_ctx, void *data, #ifdef __linux__ cancellable &= !(flags & MSG_DONTWAIT); #endif - printf("cancellable = %d\n", cancellable); + printf("thread = %u, network_recv cancellable = %d\n", pthread_self(), cancellable); while (1) { - printf("wait_cancellable...\n"); + printf("thread = %u, wait_cancellable...\n", pthread_self()); if (cancellable) { ret = wait_cancellable(io_ctx, true, timeout_ms); if (ret < 0) return ret; } - printf("wait_cancellable done\n"); + printf("thread = %u, wait_cancellable done\n", pthread_self()); ret = recv(io_ctx->fd, data, (int) len, flags); if (ret == 0) @@ -123,7 +122,7 @@ static ssize_t network_recv(struct iiod_client_pdata *io_ctx, void *data, return (ssize_t) err; } } - printf("network_recv done\n"); + printf("thread = %u, network_recv done\n", pthread_self()); return ret; } @@ -488,11 +487,11 @@ network_create_buffer(const struct iio_device *dev, unsigned int idx, void network_free_buffer(struct iio_buffer_pdata *pdata) { - printf("free1 fd = %d\n", pdata->io_ctx.cancel_fd[0]); + printf("thread = %u, free1 fd = %d\n", pthread_self(), pdata->io_ctx.cancel_fd[0]); iiod_client_free_buffer(pdata->pdata); - printf("free2\n"); + printf("thread = %u, free2\n", pthread_self()); network_free_iiod_client(pdata->iiod_client, &pdata->io_ctx); - printf("free3\n"); + printf("thread = %u, free3\n", pthread_self()); free(pdata); } From 7f4bfcb2a9bb599a8cf920a188989e15a57f558c Mon Sep 17 00:00:00 2001 From: Benjamin Menkuec Date: Wed, 6 Nov 2024 16:18:01 +0100 Subject: [PATCH 06/38] remove debug printfs --- buffer.c | 7 ----- iiod-client.c | 4 --- iiod-responder.c | 77 +++++------------------------------------------- local.c | 1 - network-unix.c | 10 ++----- network.c | 10 ------- task.c | 14 +-------- 7 files changed, 11 insertions(+), 112 deletions(-) diff --git a/buffer.c b/buffer.c index 526a9cf36..6fb407be7 100644 --- a/buffer.c +++ b/buffer.c @@ -187,23 +187,16 @@ void iio_buffer_destroy(struct iio_buffer *buf) { const struct iio_backend_ops *ops = buf->dev->ctx->ops; - printf("iio_buffer_cancel...\n"); iio_buffer_cancel(buf); - printf("iio_buffer_cancel done\n"); - printf("free_buffer...\n"); if (ops->free_buffer) ops->free_buffer(buf->pdata); - printf("free_buffer done\n"); - printf("iio_task_destroy...\n"); iio_task_destroy(buf->worker); - printf("iio_task_destroy done\n"); iio_mutex_destroy(buf->lock); iio_channels_mask_destroy(buf->mask); free(buf->attrlist.attrs); free(buf); - printf("iio_buffer_destroy done\n"); } const struct iio_channels_mask * diff --git a/iiod-client.c b/iiod-client.c index e1e8d1d21..6dcbb92ad 100644 --- a/iiod-client.c +++ b/iiod-client.c @@ -303,15 +303,11 @@ struct iiod_client * iiod_client_new(const struct iio_context_params *params, void iiod_client_destroy(struct iiod_client *client) { if (client->responder) { - printf("iiod_client_destroy1\n"); iiod_client_cancel(client); - printf("iiod_client_destroy2\n"); iiod_responder_destroy(client->responder); - printf("iiod_client_destroy3\n"); } iio_mutex_destroy(client->lock); - printf("iiod_client_destroy4\n"); free(client); } diff --git a/iiod-responder.c b/iiod-responder.c index 95e3b839f..e4f1dec93 100644 --- a/iiod-responder.c +++ b/iiod-responder.c @@ -114,16 +114,6 @@ static void __iiod_io_cancel_unlocked(struct iiod_io *io) struct iiod_io *tmp; /* Discard the entry from the readers list */ - printf("thread = %u, discard reader %d\n", pthread_self(), io); - if (priv->readers) { - for (tmp = priv->readers; tmp->r_next; ) { - if (tmp == tmp->r_next) { - printf("loop detected!!! %d -> %d\n", tmp, tmp->r_next); - exit(1); - } - tmp = tmp->r_next; - } - } if (io == priv->readers) { priv->readers = io->r_next; } else if (priv->readers) { @@ -164,11 +154,8 @@ static ssize_t iiod_rw_all(struct iiod_responder *priv, nb = 1; } - if (is_read) { - printf("thread = %u, read...\n", pthread_self()); + if (is_read) ret = priv->ops->read(priv->d, curr, nb); - printf("thread = %u, read done\n", pthread_self()); - } else ret = priv->ops->write(priv->d, curr, nb); if (ret <= 0) @@ -263,7 +250,6 @@ static int iiod_responder_reader_worker(struct iiod_responder *priv) ok_buf.size = 3; iio_mutex_lock(priv->lock); - printf("thread = %u, start reader...\n", pthread_self()); while (!priv->thrd_stop) { iio_mutex_unlock(priv->lock); @@ -282,9 +268,7 @@ static int iiod_responder_reader_worker(struct iiod_responder *priv) continue; } - printf("thread = %u, try lock...\n", pthread_self()); iio_mutex_lock(priv->lock); - printf("thread = %u, locked\n", pthread_self()); if (ret <= 0) break; @@ -293,10 +277,7 @@ static int iiod_responder_reader_worker(struct iiod_responder *priv) ret = iiod_run_command(priv, &cmd); - printf("thread = %u, try lock...\n", pthread_self()); iio_mutex_lock(priv->lock); - printf("thread = %u, locked\n", pthread_self()); - if (ret < 0) break; @@ -314,10 +295,7 @@ static int iiod_responder_reader_worker(struct iiod_responder *priv) * for it, so drop it. */ iio_mutex_unlock(priv->lock); iiod_discard_data(priv, cmd.code); - printf("thread = %u, try lock...\n", pthread_self()); iio_mutex_lock(priv->lock); - printf("thread = %u, locked\n", pthread_self()); - continue; } @@ -350,7 +328,6 @@ static int iiod_responder_reader_worker(struct iiod_responder *priv) iiod_responder_signal_io(io, cmd.code); iiod_io_unref_unlocked(io); } - printf("thread = %u, stop reader...\n", pthread_self()); priv->thrd_err_code = priv->thrd_stop ? -EINTR : (int) ret; priv->thrd_stop = true; @@ -588,37 +565,13 @@ int iiod_io_get_response_async(struct iiod_io *io, io->r_io.start_time = read_counter_us(); /* Add it to the readers list */ - printf("thread = %u, adding reader %d\n", pthread_self(), io); - bool found = false; - if (priv->readers) { - for (tmp = priv->readers; tmp->r_next; ) { - if (tmp == io) - { - printf("reader is already in list!!\n"); - found = true; - exit(1); - } - if (tmp == tmp->r_next) { - printf("loop detected!!!\n"); - exit(1); - } + if (!priv->readers) { + priv->readers = io; + } else { + for (tmp = priv->readers; tmp->r_next; ) tmp = tmp->r_next; - } - } - if (!found) { - if (!priv->readers) { - priv->readers = io; - } else { - unsigned int i = 0; - for (tmp = priv->readers; tmp->r_next; ) { - printf("list item %d = %d\n", i++,tmp); - tmp = tmp->r_next; - if (i > 100) exit(1); - } - tmp->r_next = io; - printf("io->r_next = %d\n", io->r_next); - io->r_next = NULL; - } + tmp->r_next = io; + io->r_next = NULL; } iio_mutex_unlock(priv->lock); @@ -753,35 +706,21 @@ void iiod_responder_stop(struct iiod_responder *priv) void iiod_responder_destroy(struct iiod_responder *priv) { - printf("thread = %u, iiod_responder_destroy1\n", pthread_self()); iiod_responder_stop(priv); - printf("iiod_responder_destroy2\n"); iiod_responder_wait_done(priv); - printf("iiod_responder_destroy3\n"); iio_task_destroy(priv->write_task); - printf("iiod_responder_destroy4\n"); iiod_io_unref(priv->default_io); - printf("iiod_responder_destroy5\n"); iio_mutex_destroy(priv->lock); free(priv); } -struct iio_thrd { - pthread_t thid; - void *d; - int (*func)(void *); -}; - void iiod_responder_wait_done(struct iiod_responder *priv) { if (!NO_THREADS) { - if (priv->read_thrd) { - printf("thread = %u, iio_thrd_join_and_destroy thread = %u...\n", pthread_self(), priv->read_thrd->thid); + if (priv->read_thrd) iio_thrd_join_and_destroy(priv->read_thrd); - printf("iio_thrd_join_and_destroy done\n "); - } priv->read_thrd = NULL; } else if (!priv->thrd_stop) { iiod_responder_reader_worker(priv); diff --git a/local.c b/local.c index 06295d8bf..9322c4b67 100644 --- a/local.c +++ b/local.c @@ -1547,7 +1547,6 @@ local_create_buffer(const struct iio_device *dev, unsigned int idx, static void local_free_buffer(struct iio_buffer_pdata *pdata) { - printf("local_free_buffer\n"); free(pdata->pdata); local_close_fd(pdata->dev, pdata->fd); close(pdata->cancel_fd); diff --git a/network-unix.c b/network-unix.c index 6c22d675e..9d26a84e6 100644 --- a/network-unix.c +++ b/network-unix.c @@ -42,7 +42,6 @@ static int create_cancel_fd(struct iiod_client_pdata *io_ctx) io_ctx->cancel_fd[0] = eventfd(0, EFD_CLOEXEC | EFD_NONBLOCK); if (io_ctx->cancel_fd[0] < 0) return -errno; - printf("created cancel_fd %d\n", io_ctx->cancel_fd[0]); return 0; } @@ -77,7 +76,6 @@ static int create_cancel_fd(struct iiod_client_pdata *io_ctx) void cleanup_cancel(struct iiod_client_pdata *io_ctx) { - printf("cleanup_cancel\n"); close(io_ctx->cancel_fd[0]); if (!WITH_NETWORK_EVENTFD) close(io_ctx->cancel_fd[1]); @@ -92,17 +90,15 @@ int setup_cancel(struct iiod_client_pdata *io_ctx) void do_cancel(struct iiod_client_pdata *io_ctx) { - printf("do cancel... fd = %d\n", io_ctx->cancel_fd[0]); uint64_t event = 1; int ret; + ret = write(io_ctx->cancel_fd[CANCEL_WR_FD], &event, sizeof(event)); if (ret == -1) { /* If this happens something went very seriously wrong */ prm_perror(io_ctx->params, -errno, "Unable to signal cancellation event"); - printf("do cancel error!\n"); } - printf("do cancel done\n"); } int wait_cancellable(struct iiod_client_pdata *io_ctx, @@ -120,14 +116,12 @@ int wait_cancellable(struct iiod_client_pdata *io_ctx, else pfd[0].events = POLLOUT; pfd[1].fd = io_ctx->cancel_fd[0]; - pfd[1].events = POLLIN | POLLPRI | POLLHUP | POLLERR; - printf("thread = %u, poll cancel_fd %d\n", pthread_self(), pfd[1].fd); + pfd[1].events = POLLIN; do { do { ret = poll(pfd, 2, timeout); } while (ret == -1 && errno == EINTR); - printf("thread = %u, pfd[0].revents = %d, pfd[1].revents = %d, ret = %d\n",pthread_self(), pfd[0].revents,pfd[1].revents, ret); if (ret == -1) return -errno; diff --git a/network.c b/network.c index 869066878..9028bcba0 100644 --- a/network.c +++ b/network.c @@ -95,16 +95,13 @@ static ssize_t network_recv(struct iiod_client_pdata *io_ctx, void *data, #ifdef __linux__ cancellable &= !(flags & MSG_DONTWAIT); #endif - printf("thread = %u, network_recv cancellable = %d\n", pthread_self(), cancellable); while (1) { - printf("thread = %u, wait_cancellable...\n", pthread_self()); if (cancellable) { ret = wait_cancellable(io_ctx, true, timeout_ms); if (ret < 0) return ret; } - printf("thread = %u, wait_cancellable done\n", pthread_self()); ret = recv(io_ctx->fd, data, (int) len, flags); if (ret == 0) @@ -122,7 +119,6 @@ static ssize_t network_recv(struct iiod_client_pdata *io_ctx, void *data, return (ssize_t) err; } } - printf("thread = %u, network_recv done\n", pthread_self()); return ret; } @@ -366,11 +362,8 @@ network_setup_iiod_client(const struct iio_device *dev, static void network_free_iiod_client(struct iiod_client *client, struct iiod_client_pdata *io_ctx) { - printf("network_free_iiod_client1 cancel_fd = %d\n", io_ctx->cancel_fd[0]); iiod_client_destroy(client); - printf("network_free_iiod_client2\n"); cleanup_cancel(io_ctx); - printf("network_free_iiod_client3\n"); close(io_ctx->fd); io_ctx->fd = -1; } @@ -487,11 +480,8 @@ network_create_buffer(const struct iio_device *dev, unsigned int idx, void network_free_buffer(struct iio_buffer_pdata *pdata) { - printf("thread = %u, free1 fd = %d\n", pthread_self(), pdata->io_ctx.cancel_fd[0]); iiod_client_free_buffer(pdata->pdata); - printf("thread = %u, free2\n", pthread_self()); network_free_iiod_client(pdata->iiod_client, &pdata->io_ctx); - printf("thread = %u, free3\n", pthread_self()); free(pdata); } diff --git a/task.c b/task.c index 7dfca4528..b08a8eafb 100644 --- a/task.c +++ b/task.c @@ -52,17 +52,13 @@ static void iio_task_process(struct iio_task *task) iio_cond_signal(task->cond); while (!task->stop && !(task->list && task->running)) { - printf("task stop: %d %d id: %d\n", task->stop, task->running, task->thrd); iio_cond_wait(task->cond, task->lock, 0); - printf("b ts: %d %d\n", task->stop, task->running); /* If iio_task_stop() was called while we were waiting * for clients, notify that we're idle. */ if (!task->running) iio_cond_signal(task->cond); - printf("c ts: %d %d\n", task->stop, task->running); } - printf("x1\n"); if (task->stop) return; @@ -83,7 +79,6 @@ static void iio_task_process(struct iio_task *task) iio_task_token_destroy(entry); iio_mutex_lock(task->lock); - printf("x2\n"); } static int iio_task_run(void *d) @@ -103,7 +98,6 @@ static int iio_task_run(void *d) struct iio_task * iio_task_create(int (*fn)(void *, void *), void *firstarg, const char *name) { - printf("iio_task_create\n"); struct iio_task *task; int err = -ENOMEM; @@ -259,7 +253,6 @@ void iio_task_flush(struct iio_task *task) int iio_task_destroy(struct iio_task *task) { - printf("iio_task_destroy\n"); int ret = 0; iio_mutex_lock(task->lock); @@ -267,11 +260,8 @@ int iio_task_destroy(struct iio_task *task) iio_cond_signal(task->cond); iio_mutex_unlock(task->lock); - if (!NO_THREADS) { - printf("waiting for join...\n"); + if (!NO_THREADS) ret = iio_thrd_join_and_destroy(task->thrd); - printf("joined\n"); - } iio_task_flush(task); @@ -336,10 +326,8 @@ void iio_task_start(struct iio_task *task) void iio_task_stop(struct iio_task *task) { - printf("task_stop\n"); iio_mutex_lock(task->lock); task->running = false; - // task->stop = true; iio_cond_signal(task->cond); iio_cond_wait(task->cond, task->lock, 0); iio_mutex_unlock(task->lock); From 68197767ba1633a9d051ee932afe8364178bc2c5 Mon Sep 17 00:00:00 2001 From: Benjamin Menkuec Date: Thu, 7 Nov 2024 11:51:45 +0100 Subject: [PATCH 07/38] new with with additional mutex --- buffer.c | 7 ++++ iiod-client.c | 5 +++ iiod-responder.c | 89 +++++++++++++++++++++++++++++++++++++++++++----- local.c | 1 + network-unix.c | 10 ++++-- network.c | 10 ++++++ task.c | 14 +++++++- 7 files changed, 124 insertions(+), 12 deletions(-) diff --git a/buffer.c b/buffer.c index 6fb407be7..526a9cf36 100644 --- a/buffer.c +++ b/buffer.c @@ -187,16 +187,23 @@ void iio_buffer_destroy(struct iio_buffer *buf) { const struct iio_backend_ops *ops = buf->dev->ctx->ops; + printf("iio_buffer_cancel...\n"); iio_buffer_cancel(buf); + printf("iio_buffer_cancel done\n"); + printf("free_buffer...\n"); if (ops->free_buffer) ops->free_buffer(buf->pdata); + printf("free_buffer done\n"); + printf("iio_task_destroy...\n"); iio_task_destroy(buf->worker); + printf("iio_task_destroy done\n"); iio_mutex_destroy(buf->lock); iio_channels_mask_destroy(buf->mask); free(buf->attrlist.attrs); free(buf); + printf("iio_buffer_destroy done\n"); } const struct iio_channels_mask * diff --git a/iiod-client.c b/iiod-client.c index 6dcbb92ad..8983f90be 100644 --- a/iiod-client.c +++ b/iiod-client.c @@ -303,11 +303,15 @@ struct iiod_client * iiod_client_new(const struct iio_context_params *params, void iiod_client_destroy(struct iiod_client *client) { if (client->responder) { + printf("iiod_client_destroy1\n"); iiod_client_cancel(client); + printf("iiod_client_destroy2\n"); iiod_responder_destroy(client->responder); + printf("iiod_client_destroy3\n"); } iio_mutex_destroy(client->lock); + printf("iiod_client_destroy4\n"); free(client); } @@ -510,6 +514,7 @@ static ssize_t iiod_client_read_attr_new(struct iiod_client *client, char *dest, size_t len) { struct iiod_io *io = iiod_responder_get_default_io(client->responder); + printf("* thread = %u, iiod_responder_get_default_io = %d\n", pthread_self(), io); const struct iio_channel *chn; const struct iio_device *dev; const struct iio_buffer *buf; diff --git a/iiod-responder.c b/iiod-responder.c index e4f1dec93..5688d3f91 100644 --- a/iiod-responder.c +++ b/iiod-responder.c @@ -49,6 +49,7 @@ struct iiod_io { /* Cond to sleep until I/O is done */ struct iio_cond *cond; struct iio_mutex *lock; + struct iio_mutex *inuse_lock; /* Set to true when the response has been read */ bool r_done; @@ -114,6 +115,16 @@ static void __iiod_io_cancel_unlocked(struct iiod_io *io) struct iiod_io *tmp; /* Discard the entry from the readers list */ + printf("thread = %u, discard reader %d\n", pthread_self(), io); + if (priv->readers) { + for (tmp = priv->readers; tmp; ) { + if (tmp == tmp->r_next) { + printf("loop detected!!! %d -> %d\n", tmp, tmp->r_next); + exit(1); + } + tmp = tmp->r_next; + } + } if (io == priv->readers) { priv->readers = io->r_next; } else if (priv->readers) { @@ -154,8 +165,11 @@ static ssize_t iiod_rw_all(struct iiod_responder *priv, nb = 1; } - if (is_read) + if (is_read) { + printf("thread = %u, read...\n", pthread_self()); ret = priv->ops->read(priv->d, curr, nb); + printf("thread = %u, read done\n", pthread_self()); + } else ret = priv->ops->write(priv->d, curr, nb); if (ret <= 0) @@ -224,6 +238,7 @@ static void iiod_responder_signal_io(struct iiod_io *io, int32_t code) io->r_done = true; iio_cond_signal(io->cond); iio_mutex_unlock(io->lock); + iio_mutex_unlock(io->inuse_lock); } static void iiod_responder_cancel_responses(struct iiod_responder *priv) @@ -250,6 +265,7 @@ static int iiod_responder_reader_worker(struct iiod_responder *priv) ok_buf.size = 3; iio_mutex_lock(priv->lock); + printf("thread = %u, start reader...\n", pthread_self()); while (!priv->thrd_stop) { iio_mutex_unlock(priv->lock); @@ -268,7 +284,9 @@ static int iiod_responder_reader_worker(struct iiod_responder *priv) continue; } + printf("thread = %u, try lock...\n", pthread_self()); iio_mutex_lock(priv->lock); + printf("thread = %u, locked\n", pthread_self()); if (ret <= 0) break; @@ -277,7 +295,10 @@ static int iiod_responder_reader_worker(struct iiod_responder *priv) ret = iiod_run_command(priv, &cmd); + printf("thread = %u, try lock...\n", pthread_self()); iio_mutex_lock(priv->lock); + printf("thread = %u, locked\n", pthread_self()); + if (ret < 0) break; @@ -286,8 +307,10 @@ static int iiod_responder_reader_worker(struct iiod_responder *priv) /* Find the client for the given ID in the readers list */ for (io = priv->readers; io; io = io->r_next) { - if (io->client_id == cmd.client_id) + if (io->client_id == cmd.client_id) { + printf("* thread = %u, selecting io %u with client_id %d\n", pthread_self(), io, io->client_id); break; + } } if (!io) { @@ -295,7 +318,10 @@ static int iiod_responder_reader_worker(struct iiod_responder *priv) * for it, so drop it. */ iio_mutex_unlock(priv->lock); iiod_discard_data(priv, cmd.code); + printf("thread = %u, try lock...\n", pthread_self()); iio_mutex_lock(priv->lock); + printf("thread = %u, locked\n", pthread_self()); + continue; } @@ -328,6 +354,7 @@ static int iiod_responder_reader_worker(struct iiod_responder *priv) iiod_responder_signal_io(io, cmd.code); iiod_io_unref_unlocked(io); } + printf("thread = %u, stop reader...\n", pthread_self()); priv->thrd_err_code = priv->thrd_stop ? -EINTR : (int) ret; priv->thrd_stop = true; @@ -488,6 +515,7 @@ int32_t iiod_io_wait_for_response(struct iiod_io *io) io->r_io.cmd.code = ret; io->r_done = true; + iio_mutex_unlock(io->inuse_lock); break; } } @@ -557,6 +585,7 @@ int iiod_io_get_response_async(struct iiod_io *io, return priv->thrd_err_code; } + iio_mutex_lock(io->inuse_lock); if (nb) memcpy(io->r_io.buf, buf, sizeof(*buf) * nb); io->r_io.nb_buf = nb; @@ -565,14 +594,37 @@ int iiod_io_get_response_async(struct iiod_io *io, io->r_io.start_time = read_counter_us(); /* Add it to the readers list */ - if (!priv->readers) { - priv->readers = io; - } else { - for (tmp = priv->readers; tmp->r_next; ) + printf("thread = %u, adding reader %d\n", pthread_self(), io); + bool found = false; + if (priv->readers) { + for (tmp = priv->readers; tmp; ) { + if (tmp == io) + { + printf("reader is already in list!!\n"); + found = true; + } + if (tmp == tmp->r_next) { + printf("loop detected!!!\n"); + } tmp = tmp->r_next; - tmp->r_next = io; - io->r_next = NULL; + } } + if (!found) { + if (!priv->readers) { + priv->readers = io; + } else { + unsigned int i = 0; + for (tmp = priv->readers; tmp->r_next; ) { + printf("list item %d = %d\n", i++,tmp); + tmp = tmp->r_next; + if (i > 100) exit(1); + } + tmp->r_next = io; + printf("io->r_next = %d\n", io->r_next); + // io->r_next = NULL; + } + } + else exit(1); iio_mutex_unlock(priv->lock); @@ -623,6 +675,11 @@ iiod_responder_create_io(struct iiod_responder *priv, uint16_t id) if (err) goto err_free_cond; + io->inuse_lock = iio_mutex_create(); + err = iio_err(io->inuse_lock); + if (err) + goto err_free_cond; + io->client_id = id; return io; @@ -706,21 +763,35 @@ void iiod_responder_stop(struct iiod_responder *priv) void iiod_responder_destroy(struct iiod_responder *priv) { + printf("thread = %u, iiod_responder_destroy1\n", pthread_self()); iiod_responder_stop(priv); + printf("iiod_responder_destroy2\n"); iiod_responder_wait_done(priv); + printf("iiod_responder_destroy3\n"); iio_task_destroy(priv->write_task); + printf("iiod_responder_destroy4\n"); iiod_io_unref(priv->default_io); + printf("iiod_responder_destroy5\n"); iio_mutex_destroy(priv->lock); free(priv); } +struct iio_thrd { + pthread_t thid; + void *d; + int (*func)(void *); +}; + void iiod_responder_wait_done(struct iiod_responder *priv) { if (!NO_THREADS) { - if (priv->read_thrd) + if (priv->read_thrd) { + printf("thread = %u, iio_thrd_join_and_destroy thread = %u...\n", pthread_self(), priv->read_thrd->thid); iio_thrd_join_and_destroy(priv->read_thrd); + printf("iio_thrd_join_and_destroy done\n "); + } priv->read_thrd = NULL; } else if (!priv->thrd_stop) { iiod_responder_reader_worker(priv); diff --git a/local.c b/local.c index 9322c4b67..06295d8bf 100644 --- a/local.c +++ b/local.c @@ -1547,6 +1547,7 @@ local_create_buffer(const struct iio_device *dev, unsigned int idx, static void local_free_buffer(struct iio_buffer_pdata *pdata) { + printf("local_free_buffer\n"); free(pdata->pdata); local_close_fd(pdata->dev, pdata->fd); close(pdata->cancel_fd); diff --git a/network-unix.c b/network-unix.c index 9d26a84e6..6c22d675e 100644 --- a/network-unix.c +++ b/network-unix.c @@ -42,6 +42,7 @@ static int create_cancel_fd(struct iiod_client_pdata *io_ctx) io_ctx->cancel_fd[0] = eventfd(0, EFD_CLOEXEC | EFD_NONBLOCK); if (io_ctx->cancel_fd[0] < 0) return -errno; + printf("created cancel_fd %d\n", io_ctx->cancel_fd[0]); return 0; } @@ -76,6 +77,7 @@ static int create_cancel_fd(struct iiod_client_pdata *io_ctx) void cleanup_cancel(struct iiod_client_pdata *io_ctx) { + printf("cleanup_cancel\n"); close(io_ctx->cancel_fd[0]); if (!WITH_NETWORK_EVENTFD) close(io_ctx->cancel_fd[1]); @@ -90,15 +92,17 @@ int setup_cancel(struct iiod_client_pdata *io_ctx) void do_cancel(struct iiod_client_pdata *io_ctx) { + printf("do cancel... fd = %d\n", io_ctx->cancel_fd[0]); uint64_t event = 1; int ret; - ret = write(io_ctx->cancel_fd[CANCEL_WR_FD], &event, sizeof(event)); if (ret == -1) { /* If this happens something went very seriously wrong */ prm_perror(io_ctx->params, -errno, "Unable to signal cancellation event"); + printf("do cancel error!\n"); } + printf("do cancel done\n"); } int wait_cancellable(struct iiod_client_pdata *io_ctx, @@ -116,12 +120,14 @@ int wait_cancellable(struct iiod_client_pdata *io_ctx, else pfd[0].events = POLLOUT; pfd[1].fd = io_ctx->cancel_fd[0]; - pfd[1].events = POLLIN; + pfd[1].events = POLLIN | POLLPRI | POLLHUP | POLLERR; + printf("thread = %u, poll cancel_fd %d\n", pthread_self(), pfd[1].fd); do { do { ret = poll(pfd, 2, timeout); } while (ret == -1 && errno == EINTR); + printf("thread = %u, pfd[0].revents = %d, pfd[1].revents = %d, ret = %d\n",pthread_self(), pfd[0].revents,pfd[1].revents, ret); if (ret == -1) return -errno; diff --git a/network.c b/network.c index 9028bcba0..869066878 100644 --- a/network.c +++ b/network.c @@ -95,13 +95,16 @@ static ssize_t network_recv(struct iiod_client_pdata *io_ctx, void *data, #ifdef __linux__ cancellable &= !(flags & MSG_DONTWAIT); #endif + printf("thread = %u, network_recv cancellable = %d\n", pthread_self(), cancellable); while (1) { + printf("thread = %u, wait_cancellable...\n", pthread_self()); if (cancellable) { ret = wait_cancellable(io_ctx, true, timeout_ms); if (ret < 0) return ret; } + printf("thread = %u, wait_cancellable done\n", pthread_self()); ret = recv(io_ctx->fd, data, (int) len, flags); if (ret == 0) @@ -119,6 +122,7 @@ static ssize_t network_recv(struct iiod_client_pdata *io_ctx, void *data, return (ssize_t) err; } } + printf("thread = %u, network_recv done\n", pthread_self()); return ret; } @@ -362,8 +366,11 @@ network_setup_iiod_client(const struct iio_device *dev, static void network_free_iiod_client(struct iiod_client *client, struct iiod_client_pdata *io_ctx) { + printf("network_free_iiod_client1 cancel_fd = %d\n", io_ctx->cancel_fd[0]); iiod_client_destroy(client); + printf("network_free_iiod_client2\n"); cleanup_cancel(io_ctx); + printf("network_free_iiod_client3\n"); close(io_ctx->fd); io_ctx->fd = -1; } @@ -480,8 +487,11 @@ network_create_buffer(const struct iio_device *dev, unsigned int idx, void network_free_buffer(struct iio_buffer_pdata *pdata) { + printf("thread = %u, free1 fd = %d\n", pthread_self(), pdata->io_ctx.cancel_fd[0]); iiod_client_free_buffer(pdata->pdata); + printf("thread = %u, free2\n", pthread_self()); network_free_iiod_client(pdata->iiod_client, &pdata->io_ctx); + printf("thread = %u, free3\n", pthread_self()); free(pdata); } diff --git a/task.c b/task.c index b08a8eafb..5ec203a38 100644 --- a/task.c +++ b/task.c @@ -52,13 +52,17 @@ static void iio_task_process(struct iio_task *task) iio_cond_signal(task->cond); while (!task->stop && !(task->list && task->running)) { + printf("task stop: %d %d id: %d\n", task->stop, task->running, task->thrd); iio_cond_wait(task->cond, task->lock, 0); + // printf("b ts: %d %d\n", task->stop, task->running); /* If iio_task_stop() was called while we were waiting * for clients, notify that we're idle. */ if (!task->running) iio_cond_signal(task->cond); + // printf("c ts: %d %d\n", task->stop, task->running); } + // printf("x1\n"); if (task->stop) return; @@ -79,6 +83,7 @@ static void iio_task_process(struct iio_task *task) iio_task_token_destroy(entry); iio_mutex_lock(task->lock); + // printf("x2\n"); } static int iio_task_run(void *d) @@ -98,6 +103,7 @@ static int iio_task_run(void *d) struct iio_task * iio_task_create(int (*fn)(void *, void *), void *firstarg, const char *name) { + printf("iio_task_create\n"); struct iio_task *task; int err = -ENOMEM; @@ -253,6 +259,7 @@ void iio_task_flush(struct iio_task *task) int iio_task_destroy(struct iio_task *task) { + printf("iio_task_destroy\n"); int ret = 0; iio_mutex_lock(task->lock); @@ -260,8 +267,11 @@ int iio_task_destroy(struct iio_task *task) iio_cond_signal(task->cond); iio_mutex_unlock(task->lock); - if (!NO_THREADS) + if (!NO_THREADS) { + printf("waiting for join...\n"); ret = iio_thrd_join_and_destroy(task->thrd); + printf("joined\n"); + } iio_task_flush(task); @@ -326,8 +336,10 @@ void iio_task_start(struct iio_task *task) void iio_task_stop(struct iio_task *task) { + printf("task_stop\n"); iio_mutex_lock(task->lock); task->running = false; + // task->stop = true; iio_cond_signal(task->cond); iio_cond_wait(task->cond, task->lock, 0); iio_mutex_unlock(task->lock); From 8bf4c54114cda3ff2074264df9b3362db6fa9cb8 Mon Sep 17 00:00:00 2001 From: Benjamin Menkuec Date: Thu, 7 Nov 2024 12:16:33 +0100 Subject: [PATCH 08/38] wip --- iiod-responder.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iiod-responder.c b/iiod-responder.c index 5688d3f91..735e0d3a8 100644 --- a/iiod-responder.c +++ b/iiod-responder.c @@ -135,6 +135,7 @@ static void __iiod_io_cancel_unlocked(struct iiod_io *io) } } } + iio_mutex_unlock(io->inuse_lock); } static ssize_t iiod_rw_all(struct iiod_responder *priv, @@ -515,7 +516,6 @@ int32_t iiod_io_wait_for_response(struct iiod_io *io) io->r_io.cmd.code = ret; io->r_done = true; - iio_mutex_unlock(io->inuse_lock); break; } } From 024a2518df596992600648ef6b9330602a810411 Mon Sep 17 00:00:00 2001 From: Benjamin Menkuec Date: Thu, 7 Nov 2024 12:18:21 +0100 Subject: [PATCH 09/38] remove some debug printfs --- buffer.c | 7 ------- iiod-client.c | 4 ---- 2 files changed, 11 deletions(-) diff --git a/buffer.c b/buffer.c index 526a9cf36..6fb407be7 100644 --- a/buffer.c +++ b/buffer.c @@ -187,23 +187,16 @@ void iio_buffer_destroy(struct iio_buffer *buf) { const struct iio_backend_ops *ops = buf->dev->ctx->ops; - printf("iio_buffer_cancel...\n"); iio_buffer_cancel(buf); - printf("iio_buffer_cancel done\n"); - printf("free_buffer...\n"); if (ops->free_buffer) ops->free_buffer(buf->pdata); - printf("free_buffer done\n"); - printf("iio_task_destroy...\n"); iio_task_destroy(buf->worker); - printf("iio_task_destroy done\n"); iio_mutex_destroy(buf->lock); iio_channels_mask_destroy(buf->mask); free(buf->attrlist.attrs); free(buf); - printf("iio_buffer_destroy done\n"); } const struct iio_channels_mask * diff --git a/iiod-client.c b/iiod-client.c index 8983f90be..4e687a1be 100644 --- a/iiod-client.c +++ b/iiod-client.c @@ -303,15 +303,11 @@ struct iiod_client * iiod_client_new(const struct iio_context_params *params, void iiod_client_destroy(struct iiod_client *client) { if (client->responder) { - printf("iiod_client_destroy1\n"); iiod_client_cancel(client); - printf("iiod_client_destroy2\n"); iiod_responder_destroy(client->responder); - printf("iiod_client_destroy3\n"); } iio_mutex_destroy(client->lock); - printf("iiod_client_destroy4\n"); free(client); } From 9a864497cb564a0fb60df8b82b850d6f52b5c682 Mon Sep 17 00:00:00 2001 From: Benjamin Menkuec Date: Thu, 7 Nov 2024 12:19:48 +0100 Subject: [PATCH 10/38] remove more printfs --- iiod-responder.c | 5 ----- local.c | 1 - 2 files changed, 6 deletions(-) diff --git a/iiod-responder.c b/iiod-responder.c index 735e0d3a8..2937081b5 100644 --- a/iiod-responder.c +++ b/iiod-responder.c @@ -763,17 +763,12 @@ void iiod_responder_stop(struct iiod_responder *priv) void iiod_responder_destroy(struct iiod_responder *priv) { - printf("thread = %u, iiod_responder_destroy1\n", pthread_self()); iiod_responder_stop(priv); - printf("iiod_responder_destroy2\n"); iiod_responder_wait_done(priv); - printf("iiod_responder_destroy3\n"); iio_task_destroy(priv->write_task); - printf("iiod_responder_destroy4\n"); iiod_io_unref(priv->default_io); - printf("iiod_responder_destroy5\n"); iio_mutex_destroy(priv->lock); free(priv); } diff --git a/local.c b/local.c index 06295d8bf..9322c4b67 100644 --- a/local.c +++ b/local.c @@ -1547,7 +1547,6 @@ local_create_buffer(const struct iio_device *dev, unsigned int idx, static void local_free_buffer(struct iio_buffer_pdata *pdata) { - printf("local_free_buffer\n"); free(pdata->pdata); local_close_fd(pdata->dev, pdata->fd); close(pdata->cancel_fd); From dcaf008cf596f41ec8e563d1c3bb8e7d095514d5 Mon Sep 17 00:00:00 2001 From: Benjamin Menkuec Date: Thu, 7 Nov 2024 12:20:44 +0100 Subject: [PATCH 11/38] remove more debug printfs --- network.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/network.c b/network.c index 869066878..f20deb83d 100644 --- a/network.c +++ b/network.c @@ -366,11 +366,8 @@ network_setup_iiod_client(const struct iio_device *dev, static void network_free_iiod_client(struct iiod_client *client, struct iiod_client_pdata *io_ctx) { - printf("network_free_iiod_client1 cancel_fd = %d\n", io_ctx->cancel_fd[0]); iiod_client_destroy(client); - printf("network_free_iiod_client2\n"); cleanup_cancel(io_ctx); - printf("network_free_iiod_client3\n"); close(io_ctx->fd); io_ctx->fd = -1; } From 3292d3a098eb959a3ba439c3aeaec7a07ee87d94 Mon Sep 17 00:00:00 2001 From: Benjamin Menkuec Date: Thu, 7 Nov 2024 12:22:18 +0100 Subject: [PATCH 12/38] cleanup --- task.c | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/task.c b/task.c index 5ec203a38..e8cc4ced7 100644 --- a/task.c +++ b/task.c @@ -52,17 +52,13 @@ static void iio_task_process(struct iio_task *task) iio_cond_signal(task->cond); while (!task->stop && !(task->list && task->running)) { - printf("task stop: %d %d id: %d\n", task->stop, task->running, task->thrd); iio_cond_wait(task->cond, task->lock, 0); - // printf("b ts: %d %d\n", task->stop, task->running); /* If iio_task_stop() was called while we were waiting * for clients, notify that we're idle. */ if (!task->running) iio_cond_signal(task->cond); - // printf("c ts: %d %d\n", task->stop, task->running); } - // printf("x1\n"); if (task->stop) return; @@ -83,7 +79,6 @@ static void iio_task_process(struct iio_task *task) iio_task_token_destroy(entry); iio_mutex_lock(task->lock); - // printf("x2\n"); } static int iio_task_run(void *d) @@ -103,7 +98,6 @@ static int iio_task_run(void *d) struct iio_task * iio_task_create(int (*fn)(void *, void *), void *firstarg, const char *name) { - printf("iio_task_create\n"); struct iio_task *task; int err = -ENOMEM; @@ -259,7 +253,6 @@ void iio_task_flush(struct iio_task *task) int iio_task_destroy(struct iio_task *task) { - printf("iio_task_destroy\n"); int ret = 0; iio_mutex_lock(task->lock); @@ -268,9 +261,7 @@ int iio_task_destroy(struct iio_task *task) iio_mutex_unlock(task->lock); if (!NO_THREADS) { - printf("waiting for join...\n"); ret = iio_thrd_join_and_destroy(task->thrd); - printf("joined\n"); } iio_task_flush(task); @@ -336,10 +327,8 @@ void iio_task_start(struct iio_task *task) void iio_task_stop(struct iio_task *task) { - printf("task_stop\n"); iio_mutex_lock(task->lock); task->running = false; - // task->stop = true; iio_cond_signal(task->cond); iio_cond_wait(task->cond, task->lock, 0); iio_mutex_unlock(task->lock); From dfa3e4f252e7c5badc4e66b346e89fb267d5e1d9 Mon Sep 17 00:00:00 2001 From: Benjamin Menkuec Date: Thu, 7 Nov 2024 12:23:17 +0100 Subject: [PATCH 13/38] wip --- network.c | 7 ------- 1 file changed, 7 deletions(-) diff --git a/network.c b/network.c index f20deb83d..9028bcba0 100644 --- a/network.c +++ b/network.c @@ -95,16 +95,13 @@ static ssize_t network_recv(struct iiod_client_pdata *io_ctx, void *data, #ifdef __linux__ cancellable &= !(flags & MSG_DONTWAIT); #endif - printf("thread = %u, network_recv cancellable = %d\n", pthread_self(), cancellable); while (1) { - printf("thread = %u, wait_cancellable...\n", pthread_self()); if (cancellable) { ret = wait_cancellable(io_ctx, true, timeout_ms); if (ret < 0) return ret; } - printf("thread = %u, wait_cancellable done\n", pthread_self()); ret = recv(io_ctx->fd, data, (int) len, flags); if (ret == 0) @@ -122,7 +119,6 @@ static ssize_t network_recv(struct iiod_client_pdata *io_ctx, void *data, return (ssize_t) err; } } - printf("thread = %u, network_recv done\n", pthread_self()); return ret; } @@ -484,11 +480,8 @@ network_create_buffer(const struct iio_device *dev, unsigned int idx, void network_free_buffer(struct iio_buffer_pdata *pdata) { - printf("thread = %u, free1 fd = %d\n", pthread_self(), pdata->io_ctx.cancel_fd[0]); iiod_client_free_buffer(pdata->pdata); - printf("thread = %u, free2\n", pthread_self()); network_free_iiod_client(pdata->iiod_client, &pdata->io_ctx); - printf("thread = %u, free3\n", pthread_self()); free(pdata); } From a53bd612430201a4ab13c5a1f7fdd1a48939b4ba Mon Sep 17 00:00:00 2001 From: Benjamin Menkuec Date: Thu, 7 Nov 2024 12:32:35 +0100 Subject: [PATCH 14/38] cleanup --- iiod-responder.c | 21 ++------------------- network-unix.c | 6 ------ 2 files changed, 2 insertions(+), 25 deletions(-) diff --git a/iiod-responder.c b/iiod-responder.c index 2937081b5..0bde7f53b 100644 --- a/iiod-responder.c +++ b/iiod-responder.c @@ -116,15 +116,6 @@ static void __iiod_io_cancel_unlocked(struct iiod_io *io) /* Discard the entry from the readers list */ printf("thread = %u, discard reader %d\n", pthread_self(), io); - if (priv->readers) { - for (tmp = priv->readers; tmp; ) { - if (tmp == tmp->r_next) { - printf("loop detected!!! %d -> %d\n", tmp, tmp->r_next); - exit(1); - } - tmp = tmp->r_next; - } - } if (io == priv->readers) { priv->readers = io->r_next; } else if (priv->readers) { @@ -167,9 +158,7 @@ static ssize_t iiod_rw_all(struct iiod_responder *priv, } if (is_read) { - printf("thread = %u, read...\n", pthread_self()); ret = priv->ops->read(priv->d, curr, nb); - printf("thread = %u, read done\n", pthread_self()); } else ret = priv->ops->write(priv->d, curr, nb); @@ -239,7 +228,6 @@ static void iiod_responder_signal_io(struct iiod_io *io, int32_t code) io->r_done = true; iio_cond_signal(io->cond); iio_mutex_unlock(io->lock); - iio_mutex_unlock(io->inuse_lock); } static void iiod_responder_cancel_responses(struct iiod_responder *priv) @@ -285,9 +273,7 @@ static int iiod_responder_reader_worker(struct iiod_responder *priv) continue; } - printf("thread = %u, try lock...\n", pthread_self()); iio_mutex_lock(priv->lock); - printf("thread = %u, locked\n", pthread_self()); if (ret <= 0) break; @@ -296,9 +282,7 @@ static int iiod_responder_reader_worker(struct iiod_responder *priv) ret = iiod_run_command(priv, &cmd); - printf("thread = %u, try lock...\n", pthread_self()); iio_mutex_lock(priv->lock); - printf("thread = %u, locked\n", pthread_self()); if (ret < 0) break; @@ -309,7 +293,7 @@ static int iiod_responder_reader_worker(struct iiod_responder *priv) /* Find the client for the given ID in the readers list */ for (io = priv->readers; io; io = io->r_next) { if (io->client_id == cmd.client_id) { - printf("* thread = %u, selecting io %u with client_id %d\n", pthread_self(), io, io->client_id); + printf("thread = %u, selecting io %u with client_id %d\n", pthread_self(), io, io->client_id); break; } } @@ -319,9 +303,7 @@ static int iiod_responder_reader_worker(struct iiod_responder *priv) * for it, so drop it. */ iio_mutex_unlock(priv->lock); iiod_discard_data(priv, cmd.code); - printf("thread = %u, try lock...\n", pthread_self()); iio_mutex_lock(priv->lock); - printf("thread = %u, locked\n", pthread_self()); continue; } @@ -820,6 +802,7 @@ void iiod_io_cancel(struct iiod_io *io) /* Cancel any pending response request */ iiod_io_cancel_response(io); + iio_mutex_unlock(io->inuse_lock); } static void iiod_io_destroy(struct iiod_io *io) diff --git a/network-unix.c b/network-unix.c index 6c22d675e..0e1d1f6d7 100644 --- a/network-unix.c +++ b/network-unix.c @@ -42,7 +42,6 @@ static int create_cancel_fd(struct iiod_client_pdata *io_ctx) io_ctx->cancel_fd[0] = eventfd(0, EFD_CLOEXEC | EFD_NONBLOCK); if (io_ctx->cancel_fd[0] < 0) return -errno; - printf("created cancel_fd %d\n", io_ctx->cancel_fd[0]); return 0; } @@ -77,7 +76,6 @@ static int create_cancel_fd(struct iiod_client_pdata *io_ctx) void cleanup_cancel(struct iiod_client_pdata *io_ctx) { - printf("cleanup_cancel\n"); close(io_ctx->cancel_fd[0]); if (!WITH_NETWORK_EVENTFD) close(io_ctx->cancel_fd[1]); @@ -92,7 +90,6 @@ int setup_cancel(struct iiod_client_pdata *io_ctx) void do_cancel(struct iiod_client_pdata *io_ctx) { - printf("do cancel... fd = %d\n", io_ctx->cancel_fd[0]); uint64_t event = 1; int ret; ret = write(io_ctx->cancel_fd[CANCEL_WR_FD], &event, sizeof(event)); @@ -102,7 +99,6 @@ void do_cancel(struct iiod_client_pdata *io_ctx) "Unable to signal cancellation event"); printf("do cancel error!\n"); } - printf("do cancel done\n"); } int wait_cancellable(struct iiod_client_pdata *io_ctx, @@ -121,13 +117,11 @@ int wait_cancellable(struct iiod_client_pdata *io_ctx, pfd[0].events = POLLOUT; pfd[1].fd = io_ctx->cancel_fd[0]; pfd[1].events = POLLIN | POLLPRI | POLLHUP | POLLERR; - printf("thread = %u, poll cancel_fd %d\n", pthread_self(), pfd[1].fd); do { do { ret = poll(pfd, 2, timeout); } while (ret == -1 && errno == EINTR); - printf("thread = %u, pfd[0].revents = %d, pfd[1].revents = %d, ret = %d\n",pthread_self(), pfd[0].revents,pfd[1].revents, ret); if (ret == -1) return -errno; From 1957abf5d090b0f0fbc5cd597a55bfa129c5d28f Mon Sep 17 00:00:00 2001 From: Benjamin Menkuec Date: Thu, 7 Nov 2024 12:33:06 +0100 Subject: [PATCH 15/38] cleanup --- network-unix.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/network-unix.c b/network-unix.c index 0e1d1f6d7..e52e73c97 100644 --- a/network-unix.c +++ b/network-unix.c @@ -97,7 +97,6 @@ void do_cancel(struct iiod_client_pdata *io_ctx) /* If this happens something went very seriously wrong */ prm_perror(io_ctx->params, -errno, "Unable to signal cancellation event"); - printf("do cancel error!\n"); } } @@ -116,7 +115,7 @@ int wait_cancellable(struct iiod_client_pdata *io_ctx, else pfd[0].events = POLLOUT; pfd[1].fd = io_ctx->cancel_fd[0]; - pfd[1].events = POLLIN | POLLPRI | POLLHUP | POLLERR; + pfd[1].events = POLLIN; do { do { From 3dbacd2fa86ad2f9e62a25ce1bef9ef776b66d2f Mon Sep 17 00:00:00 2001 From: Benjamin Menkuec Date: Thu, 7 Nov 2024 12:34:11 +0100 Subject: [PATCH 16/38] wip --- task.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/task.c b/task.c index e8cc4ced7..b08a8eafb 100644 --- a/task.c +++ b/task.c @@ -260,9 +260,8 @@ int iio_task_destroy(struct iio_task *task) iio_cond_signal(task->cond); iio_mutex_unlock(task->lock); - if (!NO_THREADS) { + if (!NO_THREADS) ret = iio_thrd_join_and_destroy(task->thrd); - } iio_task_flush(task); From dd907cf5e7443a430e2c2cccc324ba528215a38c Mon Sep 17 00:00:00 2001 From: Benjamin Menkuec Date: Thu, 7 Nov 2024 12:34:47 +0100 Subject: [PATCH 17/38] wip --- network-unix.c | 1 + 1 file changed, 1 insertion(+) diff --git a/network-unix.c b/network-unix.c index e52e73c97..9d26a84e6 100644 --- a/network-unix.c +++ b/network-unix.c @@ -92,6 +92,7 @@ void do_cancel(struct iiod_client_pdata *io_ctx) { uint64_t event = 1; int ret; + ret = write(io_ctx->cancel_fd[CANCEL_WR_FD], &event, sizeof(event)); if (ret == -1) { /* If this happens something went very seriously wrong */ From ebafb8ba7f2c388d777d0f2a529f47712875c6bd Mon Sep 17 00:00:00 2001 From: Benjamin Menkuec Date: Thu, 7 Nov 2024 12:39:49 +0100 Subject: [PATCH 18/38] cleanup --- iiod-responder.c | 1 - 1 file changed, 1 deletion(-) diff --git a/iiod-responder.c b/iiod-responder.c index 0bde7f53b..6db87ce13 100644 --- a/iiod-responder.c +++ b/iiod-responder.c @@ -603,7 +603,6 @@ int iiod_io_get_response_async(struct iiod_io *io, } tmp->r_next = io; printf("io->r_next = %d\n", io->r_next); - // io->r_next = NULL; } } else exit(1); From eea1f387886c645936c60e4e795a965c37ee9ebd Mon Sep 17 00:00:00 2001 From: Benjamin Menkuec Date: Thu, 7 Nov 2024 12:41:50 +0100 Subject: [PATCH 19/38] wip --- iiod-responder.c | 1 + 1 file changed, 1 insertion(+) diff --git a/iiod-responder.c b/iiod-responder.c index 6db87ce13..0e0f5ffc1 100644 --- a/iiod-responder.c +++ b/iiod-responder.c @@ -663,6 +663,7 @@ iiod_responder_create_io(struct iiod_responder *priv, uint16_t id) io->client_id = id; + printf("thread = %u, created io %d\n", pthread_self(), io); return io; err_free_cond: From e167ea6985ecb1d0f3aae3f85ebfe4d9d9edf112 Mon Sep 17 00:00:00 2001 From: Benjamin Menkuec Date: Thu, 7 Nov 2024 15:00:08 +0100 Subject: [PATCH 20/38] use thread pool und thread-id basis --- iiod-client.c | 2 ++ iiod-responder.c | 56 +++++++++++++++++++++++++++++++++--------------- network-unix.c | 5 ++++- network.c | 4 +++- 4 files changed, 48 insertions(+), 19 deletions(-) diff --git a/iiod-client.c b/iiod-client.c index 4e687a1be..7c72c39d1 100644 --- a/iiod-client.c +++ b/iiod-client.c @@ -1605,7 +1605,9 @@ void iiod_client_free_block(struct iio_block_pdata *block) /* Cancel any I/O going on. This means we must send the block free * command through the main I/O as the block's I/O stream is * disrupted. */ + printf("thread = %u, iiod_io_cancel...\n", pthread_self()); iiod_io_cancel(block->io); + printf("thread = %u, iiod_io_cancel ok\n", pthread_self()); iiod_io_unref(block->io); io = iiod_responder_get_default_io(client->responder); diff --git a/iiod-responder.c b/iiod-responder.c index 0e0f5ffc1..432ee947c 100644 --- a/iiod-responder.c +++ b/iiod-responder.c @@ -49,7 +49,6 @@ struct iiod_io { /* Cond to sleep until I/O is done */ struct iio_cond *cond; struct iio_mutex *lock; - struct iio_mutex *inuse_lock; /* Set to true when the response has been read */ bool r_done; @@ -71,6 +70,9 @@ struct iiod_responder { void *d; struct iiod_io *readers, *writers, *default_io; + struct iiod_io* default_io_pool[100]; + unsigned int default_io_pool_thread_ids[100]; + unsigned int default_io_pool_size; uint16_t next_client_id; struct iio_mutex *lock; @@ -114,6 +116,15 @@ static void __iiod_io_cancel_unlocked(struct iiod_io *io) struct iiod_responder *priv = io->responder; struct iiod_io *tmp; + if (priv->readers) { + for (tmp = priv->readers; tmp; ) { + if (tmp == tmp->r_next) { + printf("loop detected!!!\n"); + } + tmp = tmp->r_next; + } + } + /* Discard the entry from the readers list */ printf("thread = %u, discard reader %d\n", pthread_self(), io); if (io == priv->readers) { @@ -126,7 +137,6 @@ static void __iiod_io_cancel_unlocked(struct iiod_io *io) } } } - iio_mutex_unlock(io->inuse_lock); } static ssize_t iiod_rw_all(struct iiod_responder *priv, @@ -567,7 +577,6 @@ int iiod_io_get_response_async(struct iiod_io *io, return priv->thrd_err_code; } - iio_mutex_lock(io->inuse_lock); if (nb) memcpy(io->r_io.buf, buf, sizeof(*buf) * nb); io->r_io.nb_buf = nb; @@ -656,11 +665,6 @@ iiod_responder_create_io(struct iiod_responder *priv, uint16_t id) if (err) goto err_free_cond; - io->inuse_lock = iio_mutex_create(); - err = iio_err(io->inuse_lock); - if (err) - goto err_free_cond; - io->client_id = id; printf("thread = %u, created io %d\n", pthread_self(), io); @@ -676,8 +680,8 @@ iiod_responder_create_io(struct iiod_responder *priv, uint16_t id) void iiod_responder_set_timeout(struct iiod_responder *priv, unsigned int timeout_ms) { - priv->timeout_ms = timeout_ms; - priv->default_io->timeout_ms = timeout_ms; + // priv->timeout_ms = timeout_ms; + // priv->default_io->timeout_ms = timeout_ms; } void @@ -704,10 +708,7 @@ iiod_responder_create(const struct iiod_responder_ops *ops, void *d) if (err) goto err_free_priv; - priv->default_io = iiod_responder_create_io(priv, 0); - err = iio_err(priv->default_io); - if (err) - goto err_free_lock; + priv->default_io_pool_size = 0; priv->write_task = iio_task_create(iiod_responder_write, priv, "iiod-responder-writer-task"); @@ -780,7 +781,8 @@ struct iiod_io * iiod_command_create_io(const struct iiod_command *cmd, { struct iiod_responder *priv = (struct iiod_responder *) data; - return iiod_responder_create_io(priv, cmd->client_id); + struct iiod_io* io = iiod_responder_create_io(priv, cmd->client_id); + return io; } void iiod_io_cancel(struct iiod_io *io) @@ -802,11 +804,11 @@ void iiod_io_cancel(struct iiod_io *io) /* Cancel any pending response request */ iiod_io_cancel_response(io); - iio_mutex_unlock(io->inuse_lock); } static void iiod_io_destroy(struct iiod_io *io) { + printf("destroy %d\n", io); iio_mutex_destroy(io->lock); iio_cond_destroy(io->cond); free(io); @@ -846,7 +848,27 @@ void iiod_io_unref(struct iiod_io *io) struct iiod_io * iiod_responder_get_default_io(struct iiod_responder *priv) { - return priv->default_io; + int idx = -1; + for (unsigned int i = 0; i < priv->default_io_pool_size; i++) { + if (priv->default_io_pool_thread_ids[i] == pthread_self()) { + idx = i; + break; + } + } + struct iiod_io *io; + if (idx != -1) { + printf("using existing io element for thread %u\n", pthread_self()); + io = priv->default_io_pool[idx]; + } + else { + printf("creating new io element for thread %u\n", pthread_self()); + io = iiod_responder_create_io(priv, 0); + io->timeout_ms = priv->timeout_ms; + priv->default_io_pool_thread_ids[priv->default_io_pool_size] = pthread_self(); + priv->default_io_pool[priv->default_io_pool_size] = io; + priv->default_io_pool_size++; + } + return io; } struct iiod_io * diff --git a/network-unix.c b/network-unix.c index 9d26a84e6..5198a6229 100644 --- a/network-unix.c +++ b/network-unix.c @@ -92,12 +92,13 @@ void do_cancel(struct iiod_client_pdata *io_ctx) { uint64_t event = 1; int ret; - + printf("thread = %u, cancel... cancel_fd = %d\n", pthread_self(), io_ctx->cancel_fd[CANCEL_WR_FD]); ret = write(io_ctx->cancel_fd[CANCEL_WR_FD], &event, sizeof(event)); if (ret == -1) { /* If this happens something went very seriously wrong */ prm_perror(io_ctx->params, -errno, "Unable to signal cancellation event"); + printf("do cancel error!\n"); } } @@ -117,11 +118,13 @@ int wait_cancellable(struct iiod_client_pdata *io_ctx, pfd[0].events = POLLOUT; pfd[1].fd = io_ctx->cancel_fd[0]; pfd[1].events = POLLIN; + printf("thread = %u, wait cancellable... cancel_fd = %d\n", pthread_self(), pfd[1].fd); do { do { ret = poll(pfd, 2, timeout); } while (ret == -1 && errno == EINTR); + printf("thread = %u, pfd[0].revents = %d, pfd[1].revents = %d, ret = %d\n",pthread_self(), pfd[0].revents,pfd[1].revents, ret); if (ret == -1) return -errno; diff --git a/network.c b/network.c index 9028bcba0..bb6aa2f11 100644 --- a/network.c +++ b/network.c @@ -99,11 +99,13 @@ static ssize_t network_recv(struct iiod_client_pdata *io_ctx, void *data, while (1) { if (cancellable) { ret = wait_cancellable(io_ctx, true, timeout_ms); + printf("thread = %u, wait cancellable ret = %d\n", pthread_self(), ret); if (ret < 0) return ret; } - + printf("thread = %u, recv...\n", pthread_self()); ret = recv(io_ctx->fd, data, (int) len, flags); + printf("thread = %u, recv ret = %d\n", pthread_self(), ret); if (ret == 0) return -EPIPE; else if (ret > 0) From a8313dddd1827c2bccca5a8a5cd02364c209df5a Mon Sep 17 00:00:00 2001 From: Benjamin Menkuec Date: Thu, 7 Nov 2024 15:16:05 +0100 Subject: [PATCH 21/38] wip --- iiod-client.c | 2 +- iiod-responder.c | 30 ++++++++++++++++++------------ network-unix.c | 4 ---- network.c | 3 --- 4 files changed, 19 insertions(+), 20 deletions(-) diff --git a/iiod-client.c b/iiod-client.c index 7c72c39d1..ccf05093d 100644 --- a/iiod-client.c +++ b/iiod-client.c @@ -510,7 +510,7 @@ static ssize_t iiod_client_read_attr_new(struct iiod_client *client, char *dest, size_t len) { struct iiod_io *io = iiod_responder_get_default_io(client->responder); - printf("* thread = %u, iiod_responder_get_default_io = %d\n", pthread_self(), io); + // printf("* thread = %u, iiod_responder_get_default_io = %d\n", pthread_self(), io); const struct iio_channel *chn; const struct iio_device *dev; const struct iio_buffer *buf; diff --git a/iiod-responder.c b/iiod-responder.c index 432ee947c..a7df521c4 100644 --- a/iiod-responder.c +++ b/iiod-responder.c @@ -21,6 +21,7 @@ #endif #define NB_BUFS_MAX 2 +#define MAX_DEFAULT_IO_ELEMENTS 100 static void iiod_io_ref_unlocked(struct iiod_io *io); static void iiod_io_unref_unlocked(struct iiod_io *io); @@ -70,8 +71,8 @@ struct iiod_responder { void *d; struct iiod_io *readers, *writers, *default_io; - struct iiod_io* default_io_pool[100]; - unsigned int default_io_pool_thread_ids[100]; + struct iiod_io* default_io_pool[MAX_DEFAULT_IO_ELEMENTS]; + uint64_t default_io_pool_thread_ids[MAX_DEFAULT_IO_ELEMENTS]; unsigned int default_io_pool_size; uint16_t next_client_id; @@ -126,7 +127,7 @@ static void __iiod_io_cancel_unlocked(struct iiod_io *io) } /* Discard the entry from the readers list */ - printf("thread = %u, discard reader %d\n", pthread_self(), io); + // printf("thread = %u, discard reader %d\n", pthread_self(), io); if (io == priv->readers) { priv->readers = io->r_next; } else if (priv->readers) { @@ -303,7 +304,7 @@ static int iiod_responder_reader_worker(struct iiod_responder *priv) /* Find the client for the given ID in the readers list */ for (io = priv->readers; io; io = io->r_next) { if (io->client_id == cmd.client_id) { - printf("thread = %u, selecting io %u with client_id %d\n", pthread_self(), io, io->client_id); + // printf("thread = %u, selecting io %u with client_id %d\n", pthread_self(), io, io->client_id); break; } } @@ -585,7 +586,7 @@ int iiod_io_get_response_async(struct iiod_io *io, io->r_io.start_time = read_counter_us(); /* Add it to the readers list */ - printf("thread = %u, adding reader %d\n", pthread_self(), io); + // printf("thread = %u, adding reader %d\n", pthread_self(), io); bool found = false; if (priv->readers) { for (tmp = priv->readers; tmp; ) { @@ -606,12 +607,12 @@ int iiod_io_get_response_async(struct iiod_io *io, } else { unsigned int i = 0; for (tmp = priv->readers; tmp->r_next; ) { - printf("list item %d = %d\n", i++,tmp); + // printf("list item %d = %d\n", i++,tmp); tmp = tmp->r_next; if (i > 100) exit(1); } tmp->r_next = io; - printf("io->r_next = %d\n", io->r_next); + // printf("io->r_next = %d\n", io->r_next); } } else exit(1); @@ -731,7 +732,7 @@ iiod_responder_create(const struct iiod_responder_ops *ops, void *d) err_free_write_task: iio_task_destroy(priv->write_task); err_free_io: - iiod_io_unref(priv->default_io); + // iiod_io_unref(priv->default_io); err_free_lock: iio_mutex_destroy(priv->lock); err_free_priv: @@ -751,7 +752,7 @@ void iiod_responder_destroy(struct iiod_responder *priv) iio_task_destroy(priv->write_task); - iiod_io_unref(priv->default_io); + // iiod_io_unref(priv->default_io); iio_mutex_destroy(priv->lock); free(priv); } @@ -856,17 +857,22 @@ iiod_responder_get_default_io(struct iiod_responder *priv) } } struct iiod_io *io; - if (idx != -1) { - printf("using existing io element for thread %u\n", pthread_self()); + if (idx != -1 && priv->default_io_pool[idx] != NULL && priv->default_io_pool[idx]->refcnt != 0) { + // printf("using existing io element for thread %u\n", pthread_self()); io = priv->default_io_pool[idx]; } else { - printf("creating new io element for thread %u\n", pthread_self()); + // printf("creating new io element for thread %u\n", pthread_self()); io = iiod_responder_create_io(priv, 0); io->timeout_ms = priv->timeout_ms; priv->default_io_pool_thread_ids[priv->default_io_pool_size] = pthread_self(); priv->default_io_pool[priv->default_io_pool_size] = io; priv->default_io_pool_size++; + if (priv->default_io_pool_size > MAX_DEFAULT_IO_ELEMENTS) { + printf("default_io_pool overflow!!!\n"); + exit(1); + } + } return io; } diff --git a/network-unix.c b/network-unix.c index 5198a6229..e52e73c97 100644 --- a/network-unix.c +++ b/network-unix.c @@ -92,13 +92,11 @@ void do_cancel(struct iiod_client_pdata *io_ctx) { uint64_t event = 1; int ret; - printf("thread = %u, cancel... cancel_fd = %d\n", pthread_self(), io_ctx->cancel_fd[CANCEL_WR_FD]); ret = write(io_ctx->cancel_fd[CANCEL_WR_FD], &event, sizeof(event)); if (ret == -1) { /* If this happens something went very seriously wrong */ prm_perror(io_ctx->params, -errno, "Unable to signal cancellation event"); - printf("do cancel error!\n"); } } @@ -118,13 +116,11 @@ int wait_cancellable(struct iiod_client_pdata *io_ctx, pfd[0].events = POLLOUT; pfd[1].fd = io_ctx->cancel_fd[0]; pfd[1].events = POLLIN; - printf("thread = %u, wait cancellable... cancel_fd = %d\n", pthread_self(), pfd[1].fd); do { do { ret = poll(pfd, 2, timeout); } while (ret == -1 && errno == EINTR); - printf("thread = %u, pfd[0].revents = %d, pfd[1].revents = %d, ret = %d\n",pthread_self(), pfd[0].revents,pfd[1].revents, ret); if (ret == -1) return -errno; diff --git a/network.c b/network.c index bb6aa2f11..fce8acf1f 100644 --- a/network.c +++ b/network.c @@ -99,13 +99,10 @@ static ssize_t network_recv(struct iiod_client_pdata *io_ctx, void *data, while (1) { if (cancellable) { ret = wait_cancellable(io_ctx, true, timeout_ms); - printf("thread = %u, wait cancellable ret = %d\n", pthread_self(), ret); if (ret < 0) return ret; } - printf("thread = %u, recv...\n", pthread_self()); ret = recv(io_ctx->fd, data, (int) len, flags); - printf("thread = %u, recv ret = %d\n", pthread_self(), ret); if (ret == 0) return -EPIPE; else if (ret > 0) From e5efbea75eef3056fb44db5e0f523aa25b2a7047 Mon Sep 17 00:00:00 2001 From: Benjamin Menkuec Date: Thu, 7 Nov 2024 15:38:50 +0100 Subject: [PATCH 22/38] wip --- iiod-responder.c | 7 ++++--- include/iio/iio-lock.h | 2 ++ lock.c | 6 ++++++ 3 files changed, 12 insertions(+), 3 deletions(-) diff --git a/iiod-responder.c b/iiod-responder.c index a7df521c4..be1bfc791 100644 --- a/iiod-responder.c +++ b/iiod-responder.c @@ -850,8 +850,9 @@ struct iiod_io * iiod_responder_get_default_io(struct iiod_responder *priv) { int idx = -1; + const uint64_t thid = iio_curr_thid(); for (unsigned int i = 0; i < priv->default_io_pool_size; i++) { - if (priv->default_io_pool_thread_ids[i] == pthread_self()) { + if (priv->default_io_pool_thread_ids[i] == thid) { idx = i; break; } @@ -862,10 +863,10 @@ iiod_responder_get_default_io(struct iiod_responder *priv) io = priv->default_io_pool[idx]; } else { - // printf("creating new io element for thread %u\n", pthread_self()); + printf("creating new io element for thread %u\n", pthread_self()); io = iiod_responder_create_io(priv, 0); io->timeout_ms = priv->timeout_ms; - priv->default_io_pool_thread_ids[priv->default_io_pool_size] = pthread_self(); + priv->default_io_pool_thread_ids[priv->default_io_pool_size] = thid; priv->default_io_pool[priv->default_io_pool_size] = io; priv->default_io_pool_size++; if (priv->default_io_pool_size > MAX_DEFAULT_IO_ELEMENTS) { diff --git a/include/iio/iio-lock.h b/include/iio/iio-lock.h index 8fa2e2979..d293e1bef 100644 --- a/include/iio/iio-lock.h +++ b/include/iio/iio-lock.h @@ -51,6 +51,8 @@ __api _Bool iio_task_is_done(struct iio_task_token *token); __api int iio_task_sync(struct iio_task_token *token, unsigned int timeout_ms); __api void iio_task_cancel(struct iio_task_token *token); +__api uint64_t iio_curr_thid(void); + #undef __api #endif /* _IIO_LOCK_H */ diff --git a/lock.c b/lock.c index 87e29cb35..5d5213d93 100644 --- a/lock.c +++ b/lock.c @@ -152,3 +152,9 @@ int iio_thrd_join_and_destroy(struct iio_thrd *thrd) return (int)(intptr_t) retval; } + +uint64_t iio_curr_thid() +{ + // thread-id should always fit into 64-bit number + return pthread_self(); +} \ No newline at end of file From 3d007febf1b22c54f00aaf5c5774e674cc685c85 Mon Sep 17 00:00:00 2001 From: Benjamin Menkuec Date: Thu, 7 Nov 2024 15:41:40 +0100 Subject: [PATCH 23/38] wip --- iiod-client.c | 3 --- iiod-responder.c | 10 +++------- 2 files changed, 3 insertions(+), 10 deletions(-) diff --git a/iiod-client.c b/iiod-client.c index ccf05093d..6dcbb92ad 100644 --- a/iiod-client.c +++ b/iiod-client.c @@ -510,7 +510,6 @@ static ssize_t iiod_client_read_attr_new(struct iiod_client *client, char *dest, size_t len) { struct iiod_io *io = iiod_responder_get_default_io(client->responder); - // printf("* thread = %u, iiod_responder_get_default_io = %d\n", pthread_self(), io); const struct iio_channel *chn; const struct iio_device *dev; const struct iio_buffer *buf; @@ -1605,9 +1604,7 @@ void iiod_client_free_block(struct iio_block_pdata *block) /* Cancel any I/O going on. This means we must send the block free * command through the main I/O as the block's I/O stream is * disrupted. */ - printf("thread = %u, iiod_io_cancel...\n", pthread_self()); iiod_io_cancel(block->io); - printf("thread = %u, iiod_io_cancel ok\n", pthread_self()); iiod_io_unref(block->io); io = iiod_responder_get_default_io(client->responder); diff --git a/iiod-responder.c b/iiod-responder.c index be1bfc791..54772f11b 100644 --- a/iiod-responder.c +++ b/iiod-responder.c @@ -70,7 +70,7 @@ struct iiod_responder { const struct iiod_responder_ops *ops; void *d; - struct iiod_io *readers, *writers, *default_io; + struct iiod_io *readers, *writers; struct iiod_io* default_io_pool[MAX_DEFAULT_IO_ELEMENTS]; uint64_t default_io_pool_thread_ids[MAX_DEFAULT_IO_ELEMENTS]; unsigned int default_io_pool_size; @@ -168,9 +168,8 @@ static ssize_t iiod_rw_all(struct iiod_responder *priv, nb = 1; } - if (is_read) { + if (is_read) ret = priv->ops->read(priv->d, curr, nb); - } else ret = priv->ops->write(priv->d, curr, nb); if (ret <= 0) @@ -294,7 +293,6 @@ static int iiod_responder_reader_worker(struct iiod_responder *priv) ret = iiod_run_command(priv, &cmd); iio_mutex_lock(priv->lock); - if (ret < 0) break; @@ -315,7 +313,6 @@ static int iiod_responder_reader_worker(struct iiod_responder *priv) iio_mutex_unlock(priv->lock); iiod_discard_data(priv, cmd.code); iio_mutex_lock(priv->lock); - continue; } @@ -681,8 +678,7 @@ iiod_responder_create_io(struct iiod_responder *priv, uint16_t id) void iiod_responder_set_timeout(struct iiod_responder *priv, unsigned int timeout_ms) { - // priv->timeout_ms = timeout_ms; - // priv->default_io->timeout_ms = timeout_ms; + priv->timeout_ms = timeout_ms; } void From 1d53aff687de80cb3ad485eb4386cd7a8400352c Mon Sep 17 00:00:00 2001 From: Benjamin Menkuec Date: Thu, 7 Nov 2024 15:42:24 +0100 Subject: [PATCH 24/38] cleanup --- network-unix.c | 1 + network.c | 1 + 2 files changed, 2 insertions(+) diff --git a/network-unix.c b/network-unix.c index e52e73c97..9d26a84e6 100644 --- a/network-unix.c +++ b/network-unix.c @@ -92,6 +92,7 @@ void do_cancel(struct iiod_client_pdata *io_ctx) { uint64_t event = 1; int ret; + ret = write(io_ctx->cancel_fd[CANCEL_WR_FD], &event, sizeof(event)); if (ret == -1) { /* If this happens something went very seriously wrong */ diff --git a/network.c b/network.c index fce8acf1f..9028bcba0 100644 --- a/network.c +++ b/network.c @@ -102,6 +102,7 @@ static ssize_t network_recv(struct iiod_client_pdata *io_ctx, void *data, if (ret < 0) return ret; } + ret = recv(io_ctx->fd, data, (int) len, flags); if (ret == 0) return -EPIPE; From c6a80dfbeaeb10c9967b71fd4b9f3cc8e467f8b7 Mon Sep 17 00:00:00 2001 From: Benjamin Menkuec Date: Thu, 7 Nov 2024 15:45:45 +0100 Subject: [PATCH 25/38] add iio_curr_thid() for windows --- lock-windows.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/lock-windows.c b/lock-windows.c index eccf6ec59..cc95b5900 100644 --- a/lock-windows.c +++ b/lock-windows.c @@ -139,3 +139,9 @@ int iio_thrd_join_and_destroy(struct iio_thrd *thrd) return (int) ret; } + +uint64_t iio_curr_thid() +{ + // thread-id should always fit into 64-bit number + return GetCurrentThreadId(); +} \ No newline at end of file From 2860e043e0427ddb6f734c7daccac89d43cf75b9 Mon Sep 17 00:00:00 2001 From: Benjamin Menkuec Date: Thu, 7 Nov 2024 15:50:38 +0100 Subject: [PATCH 26/38] cleanup --- iiod-responder.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/iiod-responder.c b/iiod-responder.c index 54772f11b..a88be3a9c 100644 --- a/iiod-responder.c +++ b/iiod-responder.c @@ -665,7 +665,6 @@ iiod_responder_create_io(struct iiod_responder *priv, uint16_t id) io->client_id = id; - printf("thread = %u, created io %d\n", pthread_self(), io); return io; err_free_cond: @@ -763,9 +762,7 @@ void iiod_responder_wait_done(struct iiod_responder *priv) { if (!NO_THREADS) { if (priv->read_thrd) { - printf("thread = %u, iio_thrd_join_and_destroy thread = %u...\n", pthread_self(), priv->read_thrd->thid); iio_thrd_join_and_destroy(priv->read_thrd); - printf("iio_thrd_join_and_destroy done\n "); } priv->read_thrd = NULL; } else if (!priv->thrd_stop) { From 8a723f03487d8a0eb6c1ca8f9bf02f8cfdbc060e Mon Sep 17 00:00:00 2001 From: Benjamin Menkuec Date: Thu, 7 Nov 2024 15:52:53 +0100 Subject: [PATCH 27/38] cleanup --- iiod-responder.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/iiod-responder.c b/iiod-responder.c index a88be3a9c..cfa82c65d 100644 --- a/iiod-responder.c +++ b/iiod-responder.c @@ -264,7 +264,6 @@ static int iiod_responder_reader_worker(struct iiod_responder *priv) ok_buf.size = 3; iio_mutex_lock(priv->lock); - printf("thread = %u, start reader...\n", pthread_self()); while (!priv->thrd_stop) { iio_mutex_unlock(priv->lock); @@ -345,7 +344,6 @@ static int iiod_responder_reader_worker(struct iiod_responder *priv) iiod_responder_signal_io(io, cmd.code); iiod_io_unref_unlocked(io); } - printf("thread = %u, stop reader...\n", pthread_self()); priv->thrd_err_code = priv->thrd_stop ? -EINTR : (int) ret; priv->thrd_stop = true; @@ -802,7 +800,6 @@ void iiod_io_cancel(struct iiod_io *io) static void iiod_io_destroy(struct iiod_io *io) { - printf("destroy %d\n", io); iio_mutex_destroy(io->lock); iio_cond_destroy(io->cond); free(io); @@ -856,7 +853,7 @@ iiod_responder_get_default_io(struct iiod_responder *priv) io = priv->default_io_pool[idx]; } else { - printf("creating new io element for thread %u\n", pthread_self()); + printf("creating new io element for thread %lu\n", thid); io = iiod_responder_create_io(priv, 0); io->timeout_ms = priv->timeout_ms; priv->default_io_pool_thread_ids[priv->default_io_pool_size] = thid; From c17724fc944bcae6fb0cc51b8ef9efce6214dacf Mon Sep 17 00:00:00 2001 From: Benjamin Menkuec Date: Thu, 7 Nov 2024 15:58:08 +0100 Subject: [PATCH 28/38] free stuff properly --- iiod-responder.c | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/iiod-responder.c b/iiod-responder.c index cfa82c65d..045a11299 100644 --- a/iiod-responder.c +++ b/iiod-responder.c @@ -745,17 +745,14 @@ void iiod_responder_destroy(struct iiod_responder *priv) iio_task_destroy(priv->write_task); - // iiod_io_unref(priv->default_io); + for (unsigned int i = 0; i < priv->default_io_pool_size; i++) { + iiod_io_unref(priv->default_io_pool[i]); + } + iio_mutex_destroy(priv->lock); free(priv); } -struct iio_thrd { - pthread_t thid; - void *d; - int (*func)(void *); -}; - void iiod_responder_wait_done(struct iiod_responder *priv) { if (!NO_THREADS) { From 8bf7b930e1b37d8983dee1a9c13ed81f333c8eea Mon Sep 17 00:00:00 2001 From: Benjamin Menkuec Date: Thu, 7 Nov 2024 16:01:07 +0100 Subject: [PATCH 29/38] cleanup --- iiod-responder.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/iiod-responder.c b/iiod-responder.c index 045a11299..261ad6f5e 100644 --- a/iiod-responder.c +++ b/iiod-responder.c @@ -756,9 +756,8 @@ void iiod_responder_destroy(struct iiod_responder *priv) void iiod_responder_wait_done(struct iiod_responder *priv) { if (!NO_THREADS) { - if (priv->read_thrd) { + if (priv->read_thrd) iio_thrd_join_and_destroy(priv->read_thrd); - } priv->read_thrd = NULL; } else if (!priv->thrd_stop) { iiod_responder_reader_worker(priv); From 9fbbc5fdc8fa81a6eceb5903e1be55828f6f30a9 Mon Sep 17 00:00:00 2001 From: Benjamin Menkuec Date: Thu, 7 Nov 2024 16:02:16 +0100 Subject: [PATCH 30/38] cleanup --- iiod-responder.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/iiod-responder.c b/iiod-responder.c index 261ad6f5e..003afac09 100644 --- a/iiod-responder.c +++ b/iiod-responder.c @@ -708,7 +708,7 @@ iiod_responder_create(const struct iiod_responder_ops *ops, void *d) "iiod-responder-writer-task"); err = iio_err(priv->write_task); if (err) - goto err_free_io; + goto err_free_lock; if (!NO_THREADS) { priv->read_thrd = iio_thrd_create(iiod_responder_reader_thrd, priv, @@ -724,8 +724,6 @@ iiod_responder_create(const struct iiod_responder_ops *ops, void *d) err_free_write_task: iio_task_destroy(priv->write_task); -err_free_io: - // iiod_io_unref(priv->default_io); err_free_lock: iio_mutex_destroy(priv->lock); err_free_priv: From a66c3723c2885b91d1ce3940c61aa156af811fad Mon Sep 17 00:00:00 2001 From: Benjamin Menkuec Date: Thu, 7 Nov 2024 19:00:44 +0100 Subject: [PATCH 31/38] cleanup --- iiod-responder.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/iiod-responder.c b/iiod-responder.c index 003afac09..4a632a9a1 100644 --- a/iiod-responder.c +++ b/iiod-responder.c @@ -767,8 +767,7 @@ struct iiod_io * iiod_command_create_io(const struct iiod_command *cmd, { struct iiod_responder *priv = (struct iiod_responder *) data; - struct iiod_io* io = iiod_responder_create_io(priv, cmd->client_id); - return io; + return iiod_responder_create_io(priv, cmd->client_id); } void iiod_io_cancel(struct iiod_io *io) From a17c028ea67919d8a88e43bc9441857731ed0abd Mon Sep 17 00:00:00 2001 From: Benjamin Menkuec Date: Thu, 7 Nov 2024 19:06:35 +0100 Subject: [PATCH 32/38] cleanup --- iiod-responder.c | 54 ++++++++++-------------------------------------- 1 file changed, 11 insertions(+), 43 deletions(-) diff --git a/iiod-responder.c b/iiod-responder.c index 4a632a9a1..789f135cd 100644 --- a/iiod-responder.c +++ b/iiod-responder.c @@ -117,17 +117,7 @@ static void __iiod_io_cancel_unlocked(struct iiod_io *io) struct iiod_responder *priv = io->responder; struct iiod_io *tmp; - if (priv->readers) { - for (tmp = priv->readers; tmp; ) { - if (tmp == tmp->r_next) { - printf("loop detected!!!\n"); - } - tmp = tmp->r_next; - } - } - /* Discard the entry from the readers list */ - // printf("thread = %u, discard reader %d\n", pthread_self(), io); if (io == priv->readers) { priv->readers = io->r_next; } else if (priv->readers) { @@ -581,36 +571,16 @@ int iiod_io_get_response_async(struct iiod_io *io, io->r_io.start_time = read_counter_us(); /* Add it to the readers list */ - // printf("thread = %u, adding reader %d\n", pthread_self(), io); - bool found = false; - if (priv->readers) { - for (tmp = priv->readers; tmp; ) { - if (tmp == io) - { - printf("reader is already in list!!\n"); - found = true; - } - if (tmp == tmp->r_next) { - printf("loop detected!!!\n"); - } - tmp = tmp->r_next; - } - } - if (!found) { - if (!priv->readers) { - priv->readers = io; - } else { - unsigned int i = 0; - for (tmp = priv->readers; tmp->r_next; ) { - // printf("list item %d = %d\n", i++,tmp); - tmp = tmp->r_next; - if (i > 100) exit(1); - } - tmp->r_next = io; - // printf("io->r_next = %d\n", io->r_next); - } - } - else exit(1); + if (!priv->readers) { + priv->readers = io; + } else { + unsigned int i = 0; + for (tmp = priv->readers; tmp->r_next; ) { + tmp = tmp->r_next; + if (i > 100) exit(1); + } + tmp->r_next = io; + } iio_mutex_unlock(priv->lock); @@ -842,11 +812,9 @@ iiod_responder_get_default_io(struct iiod_responder *priv) } struct iiod_io *io; if (idx != -1 && priv->default_io_pool[idx] != NULL && priv->default_io_pool[idx]->refcnt != 0) { - // printf("using existing io element for thread %u\n", pthread_self()); io = priv->default_io_pool[idx]; } else { - printf("creating new io element for thread %lu\n", thid); io = iiod_responder_create_io(priv, 0); io->timeout_ms = priv->timeout_ms; priv->default_io_pool_thread_ids[priv->default_io_pool_size] = thid; @@ -854,7 +822,7 @@ iiod_responder_get_default_io(struct iiod_responder *priv) priv->default_io_pool_size++; if (priv->default_io_pool_size > MAX_DEFAULT_IO_ELEMENTS) { printf("default_io_pool overflow!!!\n"); - exit(1); + return iio_ptr(-ENOMEM); } } From 630fdddde4ddd89e5cf44bcbff6bebf2c8dfbda4 Mon Sep 17 00:00:00 2001 From: Benjamin Menkuec Date: Thu, 7 Nov 2024 19:09:51 +0100 Subject: [PATCH 33/38] cleanup --- iiod-responder.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/iiod-responder.c b/iiod-responder.c index 789f135cd..56c02ac11 100644 --- a/iiod-responder.c +++ b/iiod-responder.c @@ -574,10 +574,8 @@ int iiod_io_get_response_async(struct iiod_io *io, if (!priv->readers) { priv->readers = io; } else { - unsigned int i = 0; for (tmp = priv->readers; tmp->r_next; ) { tmp = tmp->r_next; - if (i > 100) exit(1); } tmp->r_next = io; } From a04ea0e201f7e7255660b65e9a959388722440e9 Mon Sep 17 00:00:00 2001 From: Benjamin Menkuec Date: Thu, 7 Nov 2024 19:10:57 +0100 Subject: [PATCH 34/38] cleanup --- iiod-responder.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/iiod-responder.c b/iiod-responder.c index 56c02ac11..25d427d53 100644 --- a/iiod-responder.c +++ b/iiod-responder.c @@ -571,14 +571,14 @@ int iiod_io_get_response_async(struct iiod_io *io, io->r_io.start_time = read_counter_us(); /* Add it to the readers list */ - if (!priv->readers) { - priv->readers = io; - } else { - for (tmp = priv->readers; tmp->r_next; ) { - tmp = tmp->r_next; - } - tmp->r_next = io; - } + if (!priv->readers) { + priv->readers = io; + } else { + for (tmp = priv->readers; tmp->r_next; ) { + tmp = tmp->r_next; + } + tmp->r_next = io; + } iio_mutex_unlock(priv->lock); From d475c6726dd838800c33fe3d16ad44d273acda2b Mon Sep 17 00:00:00 2001 From: Benjamin Menkuec Date: Thu, 7 Nov 2024 19:11:36 +0100 Subject: [PATCH 35/38] cleanup --- iiod-responder.c | 1 - 1 file changed, 1 deletion(-) diff --git a/iiod-responder.c b/iiod-responder.c index 25d427d53..d2537f7a5 100644 --- a/iiod-responder.c +++ b/iiod-responder.c @@ -291,7 +291,6 @@ static int iiod_responder_reader_worker(struct iiod_responder *priv) /* Find the client for the given ID in the readers list */ for (io = priv->readers; io; io = io->r_next) { if (io->client_id == cmd.client_id) { - // printf("thread = %u, selecting io %u with client_id %d\n", pthread_self(), io, io->client_id); break; } } From 6b35a65c20387aaafcf57e54eba1c1a45a9c594d Mon Sep 17 00:00:00 2001 From: Benjamin Menkuec Date: Thu, 7 Nov 2024 19:16:15 +0100 Subject: [PATCH 36/38] cleanup --- iiod-responder.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/iiod-responder.c b/iiod-responder.c index d2537f7a5..9afd32248 100644 --- a/iiod-responder.c +++ b/iiod-responder.c @@ -290,9 +290,8 @@ static int iiod_responder_reader_worker(struct iiod_responder *priv) /* Find the client for the given ID in the readers list */ for (io = priv->readers; io; io = io->r_next) { - if (io->client_id == cmd.client_id) { + if (io->client_id == cmd.client_id) break; - } } if (!io) { @@ -573,9 +572,8 @@ int iiod_io_get_response_async(struct iiod_io *io, if (!priv->readers) { priv->readers = io; } else { - for (tmp = priv->readers; tmp->r_next; ) { + for (tmp = priv->readers; tmp->r_next; ) tmp = tmp->r_next; - } tmp->r_next = io; } From 0ee5b2161336e9bf6b98d4dc20c602121e1d547a Mon Sep 17 00:00:00 2001 From: Benjamin Menkuec Date: Thu, 7 Nov 2024 19:22:32 +0100 Subject: [PATCH 37/38] make it pre C99 compatible --- iiod-responder.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/iiod-responder.c b/iiod-responder.c index 9afd32248..7b82bbee1 100644 --- a/iiod-responder.c +++ b/iiod-responder.c @@ -708,7 +708,8 @@ void iiod_responder_destroy(struct iiod_responder *priv) iio_task_destroy(priv->write_task); - for (unsigned int i = 0; i < priv->default_io_pool_size; i++) { + unsigned int i; + for (i = 0; i < priv->default_io_pool_size; i++) { iiod_io_unref(priv->default_io_pool[i]); } @@ -799,7 +800,8 @@ iiod_responder_get_default_io(struct iiod_responder *priv) { int idx = -1; const uint64_t thid = iio_curr_thid(); - for (unsigned int i = 0; i < priv->default_io_pool_size; i++) { + unsigned int i; + for (i = 0; i < priv->default_io_pool_size; i++) { if (priv->default_io_pool_thread_ids[i] == thid) { idx = i; break; From 0fd7cc502ec0890316bddd9471ae2956e642bf0a Mon Sep 17 00:00:00 2001 From: Benjamin Menkuec Date: Fri, 8 Nov 2024 12:14:13 +0100 Subject: [PATCH 38/38] This fixes a dead-loop that can occur when the same io element is inserted twice into the readers list. This is only a temporary solution until the underlying issue is solved. --- iiod-responder.c | 50 ++++++++++-------------------------------- include/iio/iio-lock.h | 2 -- lock-windows.c | 6 ----- lock.c | 6 ----- 4 files changed, 12 insertions(+), 52 deletions(-) diff --git a/iiod-responder.c b/iiod-responder.c index 7b82bbee1..e4f1dec93 100644 --- a/iiod-responder.c +++ b/iiod-responder.c @@ -21,7 +21,6 @@ #endif #define NB_BUFS_MAX 2 -#define MAX_DEFAULT_IO_ELEMENTS 100 static void iiod_io_ref_unlocked(struct iiod_io *io); static void iiod_io_unref_unlocked(struct iiod_io *io); @@ -70,10 +69,7 @@ struct iiod_responder { const struct iiod_responder_ops *ops; void *d; - struct iiod_io *readers, *writers; - struct iiod_io* default_io_pool[MAX_DEFAULT_IO_ELEMENTS]; - uint64_t default_io_pool_thread_ids[MAX_DEFAULT_IO_ELEMENTS]; - unsigned int default_io_pool_size; + struct iiod_io *readers, *writers, *default_io; uint16_t next_client_id; struct iio_mutex *lock; @@ -575,6 +571,7 @@ int iiod_io_get_response_async(struct iiod_io *io, for (tmp = priv->readers; tmp->r_next; ) tmp = tmp->r_next; tmp->r_next = io; + io->r_next = NULL; } iio_mutex_unlock(priv->lock); @@ -641,6 +638,7 @@ void iiod_responder_set_timeout(struct iiod_responder *priv, unsigned int timeout_ms) { priv->timeout_ms = timeout_ms; + priv->default_io->timeout_ms = timeout_ms; } void @@ -667,13 +665,16 @@ iiod_responder_create(const struct iiod_responder_ops *ops, void *d) if (err) goto err_free_priv; - priv->default_io_pool_size = 0; + priv->default_io = iiod_responder_create_io(priv, 0); + err = iio_err(priv->default_io); + if (err) + goto err_free_lock; priv->write_task = iio_task_create(iiod_responder_write, priv, "iiod-responder-writer-task"); err = iio_err(priv->write_task); if (err) - goto err_free_lock; + goto err_free_io; if (!NO_THREADS) { priv->read_thrd = iio_thrd_create(iiod_responder_reader_thrd, priv, @@ -689,6 +690,8 @@ iiod_responder_create(const struct iiod_responder_ops *ops, void *d) err_free_write_task: iio_task_destroy(priv->write_task); +err_free_io: + iiod_io_unref(priv->default_io); err_free_lock: iio_mutex_destroy(priv->lock); err_free_priv: @@ -708,11 +711,7 @@ void iiod_responder_destroy(struct iiod_responder *priv) iio_task_destroy(priv->write_task); - unsigned int i; - for (i = 0; i < priv->default_io_pool_size; i++) { - iiod_io_unref(priv->default_io_pool[i]); - } - + iiod_io_unref(priv->default_io); iio_mutex_destroy(priv->lock); free(priv); } @@ -798,32 +797,7 @@ void iiod_io_unref(struct iiod_io *io) struct iiod_io * iiod_responder_get_default_io(struct iiod_responder *priv) { - int idx = -1; - const uint64_t thid = iio_curr_thid(); - unsigned int i; - for (i = 0; i < priv->default_io_pool_size; i++) { - if (priv->default_io_pool_thread_ids[i] == thid) { - idx = i; - break; - } - } - struct iiod_io *io; - if (idx != -1 && priv->default_io_pool[idx] != NULL && priv->default_io_pool[idx]->refcnt != 0) { - io = priv->default_io_pool[idx]; - } - else { - io = iiod_responder_create_io(priv, 0); - io->timeout_ms = priv->timeout_ms; - priv->default_io_pool_thread_ids[priv->default_io_pool_size] = thid; - priv->default_io_pool[priv->default_io_pool_size] = io; - priv->default_io_pool_size++; - if (priv->default_io_pool_size > MAX_DEFAULT_IO_ELEMENTS) { - printf("default_io_pool overflow!!!\n"); - return iio_ptr(-ENOMEM); - } - - } - return io; + return priv->default_io; } struct iiod_io * diff --git a/include/iio/iio-lock.h b/include/iio/iio-lock.h index d293e1bef..8fa2e2979 100644 --- a/include/iio/iio-lock.h +++ b/include/iio/iio-lock.h @@ -51,8 +51,6 @@ __api _Bool iio_task_is_done(struct iio_task_token *token); __api int iio_task_sync(struct iio_task_token *token, unsigned int timeout_ms); __api void iio_task_cancel(struct iio_task_token *token); -__api uint64_t iio_curr_thid(void); - #undef __api #endif /* _IIO_LOCK_H */ diff --git a/lock-windows.c b/lock-windows.c index cc95b5900..eccf6ec59 100644 --- a/lock-windows.c +++ b/lock-windows.c @@ -139,9 +139,3 @@ int iio_thrd_join_and_destroy(struct iio_thrd *thrd) return (int) ret; } - -uint64_t iio_curr_thid() -{ - // thread-id should always fit into 64-bit number - return GetCurrentThreadId(); -} \ No newline at end of file diff --git a/lock.c b/lock.c index 5d5213d93..87e29cb35 100644 --- a/lock.c +++ b/lock.c @@ -152,9 +152,3 @@ int iio_thrd_join_and_destroy(struct iio_thrd *thrd) return (int)(intptr_t) retval; } - -uint64_t iio_curr_thid() -{ - // thread-id should always fit into 64-bit number - return pthread_self(); -} \ No newline at end of file