[sheepdog] [PATCH V2 1/2] sheep: simplify client_decref() and move it into free_request() and add a helper function

Yunkai Zhang yunkai.me at gmail.com
Fri Jul 6 10:55:22 CEST 2012


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

1) In previous code, sheep calls client_incref() in alloc_request(), but
free_request() does not call client_desref() in it, as a result it's difficult
to keep ci->refcnt with correct value, so I simplify client_decref() and move
it into free_request().

2) A bug in put_request(): before calling client_decref(), we should do some
clear actions like client_handler().

3) ci->refcnt should only be increased by alloc_request(), let's initialize
   it with 0 in create_client().

Now I add a helper named clear_client() to do clear works and try to destroy
connection when ci->refcnt is 0.

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

diff --git a/sheep/sdnet.c b/sheep/sdnet.c
index c13cdb0..c9abc25 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)
 {
@@ -453,6 +454,7 @@ static void free_request(struct request *req)
 	sys->nr_outstanding_reqs--;
 	sys->outstanding_data_size -= req->data_length;
 
+	client_decref(req->ci);
 	put_vnode_info(req->vnodes);
 	free(req->data);
 	free(req);
@@ -473,11 +475,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 +654,23 @@ 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);
+
+	dprintf("refcnt:%d, fd:%d, %s:%d\n",
+		ci->refcnt, ci->conn.fd,
+		ci->conn.ipstr, ci->conn.port);
+
+	if (ci->refcnt)
+		return;
+
+	destroy_client(ci);
+}
+
 static void client_incref(struct client_info *ci)
 {
 	if (ci)
@@ -661,8 +679,8 @@ static void client_incref(struct client_info *ci)
 
 static void client_decref(struct client_info *ci)
 {
-	if (ci && --ci->refcnt == 0)
-		destroy_client(ci);
+	if (ci)
+		ci->refcnt--;
 }
 
 static struct client_info *create_client(int fd, struct cluster_info *cluster)
@@ -693,7 +711,7 @@ static struct client_info *create_client(int fd, struct cluster_info *cluster)
 
 	ci->conn.fd = fd;
 	ci->conn.events = EPOLLIN;
-	ci->refcnt = 1;
+	ci->refcnt = 0;
 
 	INIT_LIST_HEAD(&ci->done_reqs);
 	INIT_LIST_HEAD(&ci->conn.blocking_siblings);
@@ -720,12 +738,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