"GOT", but the "O" is a cute, smiling pufferfish. Index | Thread | Search

From:
Stefan Sperling <stsp@stsp.name>
Subject:
make read_imsg() poll only if necessary
To:
gameoftrees@openbsd.org
Date:
Mon, 16 May 2022 10:23:00 +0200

Download raw body.

Thread
Our wrapper around imsg_read() always calls poll before reading data.

If there is still data left in the read buffer of struct imsgbuf then
calling poll is unnecessary overhead. This matters when the sender
batches up many small messages (such as tree entries) and the reader
keeps looping over messages with read_imsg().

I assume that we will be left with less than one imsg header worth of
bytes in case the read buffer has been drained. I could not find a
better way to tell whether we still have pending buffered data.

Before anyone asks: ibuf_size() looks at the message write buffer,
not at the message read buffer. There doesn't seem to be an equivalent
of ibuf_size() for the read buffer.

ok?

diff ff5c2684cac837a3de8ad64e56535dd0aa7ee36d a1478be81e81d253e3b4a3e7906089595c32077c
blob - 1fe975d678cb56f434aa5be0175de5eaef64f9ed
blob + 0dfcb1daa48f59a43453104f2e4950d2b21a8506
--- lib/privsep.c
+++ lib/privsep.c
@@ -94,9 +94,15 @@ read_imsg(struct imsgbuf *ibuf)
 	const struct got_error *err;
 	size_t n;
 
-	err = poll_fd(ibuf->fd, POLLIN, INFTIM);
-	if (err)
-		return err;
+	/*
+	 * There is no imsg API function to tell us whether the
+	 * read buffer still contains pending data :-(
+	 */
+	if (ibuf->r.wpos < IMSG_HEADER_SIZE) {
+		err = poll_fd(ibuf->fd, POLLIN, INFTIM);
+		if (err)
+			return err;
+	}
 
 	n = imsg_read(ibuf);
 	if (n == -1) {