[sheepdog] [PATCH 1/3] sheep: add helper function and clear connection directly when it is dead

Yunkai Zhang yunkai.me at gmail.com
Thu Jul 5 12:34:10 CEST 2012


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

When connection is dead, we should:
 1) do some clear actions about this connection.
 2) unregister it's fd from epoll.
 3) destroy this connection directly, since it's fd has been unregistered,
    sheep couldn't receive any new events of this fd.
    *Note*: If we use client_decref() instread of destroy_client(), this fd
    may not be destroyed when ci->refcnt is larger than 1, than this fd could
    not be closed in the future.

Now I add a helper named clear_client() to do these works.

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

diff --git a/sheep/sdnet.c b/sheep/sdnet.c
index c13cdb0..b493428 100644
--- a/sheep/sdnet.c
+++ b/sheep/sdnet.c
@@ -370,6 +370,7 @@ static void requeue_request(struct request *req)
 
 static void client_incref(struct client_info *ci);
 static void client_decref(struct client_info *ci);
+static void clear_client(struct client_info *ci);
 
 static struct request *alloc_local_request(void *data, int data_length)
 {
@@ -473,11 +474,10 @@ void put_request(struct request *req)
 		if (conn_tx_on(&ci->conn)) {
 			dprintf("connection seems to be dead\n");
 			free_request(req);
+			clear_client(ci);
 		} else {
 			list_add(&req->request_list, &ci->done_reqs);
 		}
-
-		client_decref(ci);
 	}
 }
 
@@ -653,6 +653,15 @@ static void destroy_client(struct client_info *ci)
 	free(ci);
 }
 
+static void clear_client(struct client_info *ci)
+{
+	if (!list_empty(&ci->conn.blocking_siblings))
+		list_del_init(&ci->conn.blocking_siblings);
+
+	unregister_event(ci->conn.fd);
+	destroy_client(ci);
+}
+
 static void client_incref(struct client_info *ci)
 {
 	if (ci)
@@ -720,12 +729,7 @@ static void client_handler(int fd, int events, void *data)
 err:
 		dprintf("closed connection %d, %s:%d\n", fd,
 			ci->conn.ipstr, ci->conn.port);
-
-		if (!list_empty(&ci->conn.blocking_siblings))
-			list_del_init(&ci->conn.blocking_siblings);
-
-		unregister_event(fd);
-		client_decref(ci);
+		clear_client(ci);
 	}
 }
 
-- 
1.7.10.4




More information about the sheepdog mailing list