hail-devel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Pete Zaitcev <zaitcev@redhat.com>
To: Project Hail List <hail-devel@vger.kernel.org>
Subject: RFC loop at EOF from client socket
Date: Mon, 10 May 2010 22:16:56 -0600	[thread overview]
Message-ID: <20100510221656.6464e8dd@redhat.com> (raw)

Just recently I hit a combination of clients, chunks, and possibly the
tabled server machine that reliably reproduces tabled looping on CPU
after the client quits. It enters a state when the read returns 0
(in cli_read), then it changes state to parse_req, fails fetching
anything meaningful, goes back to reading, and so it loops.

The problem seems too obvious: any network server should close
a client socket which returns EOF... except for one little question:
is it possible to receive zero bytes from an open socket that was
set to O_NONBLOCK? If it is, we must either rely on libevent properly
waiting and never calling the read callback unless some data is
still available, or use some kind of ioctl or other to verify
if the connection is still open. If it isn't then something like
the attached patch might work (it assumes that when an asynchronous
socket has no data, it returns -EAGAIN instead of 0 bytes).

Thoughts? The attached patch seems to work so far, but may fail
in a different environment.

-- Pete

diff --git a/server/server.c b/server/server.c
index a28965c..d6a193a 100644
--- a/server/server.c
+++ b/server/server.c
@@ -671,6 +671,12 @@ size_t cli_wqueued(struct client *cli)
 	return cli->write_cnt;
 }
 
+/*
+ * Return:
+ *   0: progress was NOT made (EOF)
+ *  >0: some data was gotten
+ *  <0: an error happened (equals to nevative of system error)
+ */
 static int cli_read(struct client *cli)
 {
 	ssize_t rc;
@@ -683,7 +689,7 @@ do_read:
 		if (errno == EINTR)
 			goto do_read;
 		if (errno == EAGAIN)
-			return 0;
+			return 1;
 		return -errno;
 	}
 
@@ -699,7 +705,7 @@ do_read:
 	if (cli->req_used == CLI_REQ_BUF_SZ)
 		return -ENOSPC;
 
-	return 0;
+	return rc != 0;
 }
 
 bool cli_cb_free(struct client *cli, void *cb_data, bool done)
@@ -1186,7 +1192,7 @@ static bool cli_evt_parse_hdr(struct client *cli, unsigned int events)
 static bool cli_evt_read_hdr(struct client *cli, unsigned int events)
 {
 	int rc = cli_read(cli);
-	if (rc < 0) {
+	if (rc <= 0) {
 		if (rc == -ENOSPC)
 			return cli_err(cli, InvalidArgument);
 
@@ -1268,7 +1274,7 @@ err_out:
 static bool cli_evt_read_req(struct client *cli, unsigned int events)
 {
 	int rc = cli_read(cli);
-	if (rc < 0) {
+	if (rc <= 0) {
 		if (rc == -ENOSPC)
 			return cli_err(cli, InvalidArgument);
 

             reply	other threads:[~2010-05-11  4:16 UTC|newest]

Thread overview: 3+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2010-05-11  4:16 Pete Zaitcev [this message]
2010-05-11  4:40 ` RFC loop at EOF from client socket Steven Dake
2010-05-11  4:49   ` Pete Zaitcev

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20100510221656.6464e8dd@redhat.com \
    --to=zaitcev@redhat.com \
    --cc=hail-devel@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).