[sheepdog] [PATCH V2] sheep: take truns to monitor EPOLLIN and EPOLLOUT events.

Yunkai Zhang yunkai.me at gmail.com
Mon Jun 25 07:20:45 CEST 2012


From: Yunkai Zhang <qiushu.zyk at taobao.com>

V2: only add more description in commit log
------------------------------------------------------ >8

When both EPOLLIN and EPOLLOUT events occur, client_hander() will always
process EPOLLIN event firstly, but this is not reasonable in some case. For
example:
     Client                                     Server
        |                                        |
        |                                   monitor(EPOLLIN)
        |                                        |
      write()  >- send request pkg ->            |
        |                                      read()
        |                                        |
        |                              [1]: monitor(EPOLLIN and EPOLLOUT)
        |                                        |
        |   <- send response pkg(1/2) -<      write()
        |                                        |
        |                                     EPOLLIN occur
                                       [2]:  read()
[1]:
After the server read the request pkg from a client, it will monitor both
EPOLLIN and EPOLLOUT events. Then the server is going to write response pkg to
the client, but only 1/2 data was send to the client for network busy.

[2]:
Before all of the response pkg was send to the client, EPOLLIN occur, then the
server will call read() to this fd. In this case, the respone pkg could not be
send to the client as soon as quickly. then the server has not chance to send
the response pkg completly, it may lead to dead lock.

The simplest way to fix this problem is that, let sheep take truns to
monitor EPOLLIN and EPOLLIUT events.

Signed-off-by: Yunkai Zhang <qiushu.zyk at taobao.com>
---
 sheep/sdnet.c |    2 ++
 1 file changed, 2 insertions(+)

diff --git a/sheep/sdnet.c b/sheep/sdnet.c
index 16c58bb..b75e52e 100644
--- a/sheep/sdnet.c
+++ b/sheep/sdnet.c
@@ -500,6 +500,7 @@ static void client_rx_handler(struct client_info *ci)
 		return;
 
 	/* now we have a complete command */
+	conn_rx_off(&ci->conn);
 
 	req = ci->rx_req;
 
@@ -549,6 +550,7 @@ again:
 	init_tx_hdr(ci);
 	if (!ci->tx_req) {
 		conn_tx_off(&ci->conn);
+		conn_rx_on(&ci->conn);
 		if (sys->outstanding_data_size < MAX_OUTSTANDING_DATA_SIZE) {
 			list_for_each_entry_safe(conn, n, &sys->blocking_conn_list,
 						 blocking_siblings) {
-- 
1.7.10.2




More information about the sheepdog mailing list