diff mbox series

[2/3] progress: add non-blocking progress_ipc_receive_nb

Message ID e2daf6db-385b-491d-a582-079879298a5c@witekio.com
State Changes Requested
Headers show
Series Fix CrapFileTest sometimes hangs | expand

Commit Message

fhoerni.opensource Oct. 8, 2024, 12:49 p.m. UTC
From: Frederic Hoerni <fhoerni@witekio.com>

The function progress_ipc_receive_nb is a non-blocking variant of
progress_ipc_receive.

Signed-off-by: Frederic Hoerni <fhoerni@witekio.com>
---
  include/progress_ipc.h |  3 ++-
  ipc/progress_ipc.c     | 32 ++++++++++++++++++++++++++++++++
  2 files changed, 34 insertions(+), 1 deletion(-)
diff mbox series

Patch

diff --git a/include/progress_ipc.h b/include/progress_ipc.h
index e79d476d..8d63d1ca 100644
--- a/include/progress_ipc.h
+++ b/include/progress_ipc.h
@@ -86,8 +86,9 @@  int progress_ipc_connect(bool reconnect);
   */
  int progress_ipc_connect_with_path(const char *socketpath, bool reconnect);
  
-/* Retrieve messages from progress interface (it blocks) */
+/* Retrieve messages from progress interface (blocking and non-blocking) */
  int progress_ipc_receive(int *connfd, struct progress_msg *msg);
+int progress_ipc_receive_nb(int *connfd, struct progress_msg *msg);
  
  #ifdef __cplusplus
  }   // extern "C"
diff --git a/ipc/progress_ipc.c b/ipc/progress_ipc.c
index 815e1601..e9b5218e 100644
--- a/ipc/progress_ipc.c
+++ b/ipc/progress_ipc.c
@@ -218,3 +218,35 @@  int progress_ipc_receive(int *connfd, struct progress_msg *msg) {
  
  	return ret;
  }
+
+int progress_ipc_receive_nb(int *connfd, struct progress_msg *msg) {
+	int ret = -1;
+	int err_poll;
+	struct pollfd pfds[1];
+	pfds[0].fd = *connfd;
+	pfds[0].events = POLLIN;
+	do {
+		err_poll = poll(pfds, 1, 0);
+	} while (err_poll == -1 && errno == EINTR);
+
+	if (err_poll == -1) {
+		fprintf(stderr, "progress_ipc_receive_nb: poll error\n");
+		ret = -1;
+	} else if (err_poll == 0) {
+		/* no pending message */
+		ret = 0;
+	} else if (pfds[0].revents & POLLIN) {
+		/* there is a message to read or the peer closed its end of the channel */
+		/* (some operating systems set POLLIN|POLLHUP on this later case) */
+		ret = progress_ipc_receive(connfd, msg);
+	} else if (pfds[0].revents & POLLHUP) {
+		/* the peer closed its end of the channel */
+		ret = -1;
+	} else {
+		/* unexpected error */
+		fprintf(stderr, "poll returned %d with revents=0x%x\n", ret, pfds[0].revents);
+		ret = -1;
+	}
+
+	return ret;
+}