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

From:
Stefan Sperling <stsp@stsp.name>
Subject:
Re: -portable gotd progress
To:
gameoftrees@openbsd.org
Date:
Sun, 20 Aug 2023 16:35:35 +0200

Download raw body.

Thread
On Sun, Aug 20, 2023 at 02:28:55PM +0200, Stefan Sperling wrote:
> A blocking issue I found during testing is that 'got send' never
> exits after uploading the pack file. On the server side I see gotsh
> hanging in poll on stdin, still waiting for more pack file data to
> arrive. Any ideas how that can be fixed? We seem to be relying on
> some OpenBSD-specific behaviour on the server side?

gotsh was not in fact hanging forever but kept looping forever doing
1 second long polls of infd and packfd.

gotsh was indeed relying on OpenBSD-specific poll behaviour, assuming
that POLLOUT and POLLHUP were mutually exclusive. Which is not the
case on Linux where POLLOUT and POLLHUP can appear together.
The order of relevant "revent" checks in our pollfd.c code would result
in an endless polling loop, because we are checking the POLLOUT bit
before checking the POLLHUP bit.

I have fixed this issue on the main branch of got.git.
The patch is trivial, see below.

The next problem to solve for gotd on Linux is an "unexpected end of file"
error printed by gotsh after a successful send operation.

-----------------------------------------------
 gotsh: do not set POLLOUT flag when there is no data to send
 
 Prevent an endless polling loop on Linux where POLLOUT and POLLHUP
 can both be reported via pollfd revents.
 
diff 80d26ca3d93a5d28ab622f6cb5d91ac973062bcb beb5455b68cf2c6513db813b7e36635a5685f95e
commit - 80d26ca3d93a5d28ab622f6cb5d91ac973062bcb
commit + beb5455b68cf2c6513db813b7e36635a5685f95e
blob - b811009e08d9088194ccc086a17fcecac0da7fde
blob + 7dd5a1417fcdb549a4424a71d36c5b74480ac8bb
--- lib/serve.c
+++ lib/serve.c
@@ -1103,7 +1103,7 @@ recv_packfile(struct imsg *imsg, int infd)
 
 		if (r == 0) {
 			/* Detect gotd(8) closing the pack pipe when done. */
-			err = got_poll_fd(packfd, POLLOUT, 1);
+			err = got_poll_fd(packfd, 0, 1);
 			if (err) {
 				if (err->code != GOT_ERR_EOF)
 					break;