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 |