On 2012年04月25日 09:05, Huxinwei wrote: >> -----Original Message----- >> From: MORITA Kazutaka [mailto:morita.kazutaka at gmail.com] >> Sent: Tuesday, April 24, 2012 5:21 PM >> To: Huxinwei >> Cc: Li Wenpeng; sheepdog at lists.wpkg.org >> Subject: Re: [Sheepdog] [PATCH] fix a bug in rx() when read() returns 0 but >> connection is not marked as closed. >> >> On Tue, Apr 24, 2012 at 5:40 PM, Huxinwei<huxinwei at huawei.com> wrote: >>> I proposed something similar a while ago. >>> The connection is actually staying in CLOSE_WAIT status while this happens. >> I'd suggest you consider something more reliable. >> >> Is there any case that read() returns zero but the connection is not closed? > What if reading is interrupted by a signal ? > Read() returns 0 while errno is EINTR then ? Thanks for pointing it out, I learned from the manual for read(), The manual says "zero indicates end of file", so I thought when read() returns zero on a blocking socket means connection closed, maybe I am wrong. But can we just check EINTR when read() return zero instead of calling getsockopt() ? thanks, levin >> Thanks, >> >> Kazutaka >> >>> + else if (!ret) { //FIXME: is this the best place to check? >>> + int r; >>> + struct tcp_info ti; >>> + socklen_t l = sizeof(struct tcp_info); >>> + r = getsockopt(conn->fd, SOL_TCP, TCP_INFO, >> (void*)&ti,&l); >>> + if (r< 0) panic("this is really wired"); >>> + if (ti.tcpi_state == TCP_CLOSE_WAIT) { >>> + conn->c_rx_state = C_IO_CLOSED; >>> + conn->c_tx_state = C_IO_CLOSED; >>> + } >>> + } >>> >>> FYI. >>> >>>> -----Original Message----- >>>> From: sheepdog-bounces at lists.wpkg.org >>>> [mailto:sheepdog-bounces at lists.wpkg.org] On Behalf Of Li Wenpeng >>>> Sent: Tuesday, April 24, 2012 4:00 PM >>>> To: sheepdog at lists.wpkg.org >>>> Subject: [Sheepdog] [PATCH] fix a bug in rx() when read() returns 0 but >>>> connection is not marked as closed. >>>> >>>> From: levin li<xingke.lwp at taobao.com> >>>> >>>> if read() returns 0,it means connection closed, but previous >>>> read() may set errno to EAGAIN, in which case rx() would just >>>> return 0 without set connection state as C_IO_CLOSED >>>> >>>> Signed-off-by: levin li<xingke.lwp at taobao.com> >>>> --- >>>> lib/net.c | 7 ++++++- >>>> 1 files changed, 6 insertions(+), 1 deletions(-) >>>> >>>> diff --git a/lib/net.c b/lib/net.c >>>> index 260ae38..8ac7c9e 100644 >>>> --- a/lib/net.c >>>> +++ b/lib/net.c >>>> @@ -70,7 +70,12 @@ int rx(struct connection *conn, enum conn_state >>>> next_state) >>>> int ret; >>>> >>>> ret = read(conn->fd, conn->rx_buf, conn->rx_length); >>>> - if (!ret || ret< 0) { >>>> + if (!ret) { >>>> + conn->c_rx_state = C_IO_CLOSED; >>>> + return 0; >>>> + } >>>> + >>>> + if (ret< 0) { >>>> if (errno != EAGAIN) >>>> conn->c_rx_state = C_IO_CLOSED; >>>> return 0; >>>> -- >>>> 1.7.1 >>>> >>>> -- >>>> sheepdog mailing list >>>> sheepdog at lists.wpkg.org >>>> http://lists.wpkg.org/mailman/listinfo/sheepdog >>> -- >>> sheepdog mailing list >>> sheepdog at lists.wpkg.org >>> http://lists.wpkg.org/mailman/listinfo/sheepdog |