[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