[sheepdog] [PATCH 3/3] sheep: free requests when connection is dead

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


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

It's important to free all requests when connection is dead(especially when
EPOLLERR occur, some requests might be not cleared correctly), or it will lead
to memory leak and sys->nr_outstanding_reqs would be always larger than 0 as a
result sheep could not be shutdown.

Conneciont's request is created by alloc_request() and will be kept in three
places:
	1) ci->rx_req
	2) ci->dones_reqs
	3) ci->tx_req
As long as we can promise that one request only be kept in one of these three
places, than we can free it correctly.

This patch do this clear work in clear_client().

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

diff --git a/sheep/sdnet.c b/sheep/sdnet.c
index f5272b3..30ed5d8 100644
--- a/sheep/sdnet.c
+++ b/sheep/sdnet.c
@@ -536,6 +536,7 @@ static void client_rx_handler(struct client_info *ci)
 
 	if (is_conn_dead(conn) && ci->rx_req) {
 		free_request(ci->rx_req);
+		ci->rx_req = NULL;
 		return;
 	}
 
@@ -633,6 +634,7 @@ again:
 
 	if (is_conn_dead(&ci->conn)) {
 		free_request(ci->tx_req);
+		ci->tx_req = NULL;
 		return;
 	}
 
@@ -652,6 +654,19 @@ static void destroy_client(struct client_info *ci)
 
 static void clear_client(struct client_info *ci)
 {
+	struct request *req;
+
+	if (ci->rx_req)
+		free_request(ci->tx_req);
+
+	if (ci->tx_req)
+		free_request(ci->tx_req);
+
+	list_for_each_entry(req, &ci->done_reqs, request_list) {
+		list_del(&req->request_list);
+		free_request(req);
+	}
+
 	if (!list_empty(&ci->conn.blocking_siblings))
 		list_del_init(&ci->conn.blocking_siblings);
 
-- 
1.7.10.4




More information about the sheepdog mailing list