[sheepdog] [PATCH V3 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 15:30:16 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. Now I drop client_incref/client_decref
and call ci->refcnt++/ci->refcnt-- in alloc_request/free_request directly.
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().
4) remove error message in unregister_event() when lookup_event() failed,
as this function may be called several times in new helper function which
named clear_client() before ci->refcnt reach zero.
Signed-off-by: Yunkai Zhang <qiushu.zyk at taobao.com>
---
lib/event.c | 4 +---
sheep/sdnet.c | 39 +++++++++++++++++++--------------------
2 files changed, 20 insertions(+), 23 deletions(-)
diff --git a/lib/event.c b/lib/event.c
index 8a69dc4..1557493 100644
--- a/lib/event.c
+++ b/lib/event.c
@@ -125,10 +125,8 @@ void unregister_event(int fd)
struct event_info *ei;
ei = lookup_event(fd);
- if (!ei) {
- eprintf("event info for fd %d not found\n", fd);
+ if (!ei)
return;
- }
ret = epoll_ctl(efd, EPOLL_CTL_DEL, fd, NULL);
if (ret)
diff --git a/sheep/sdnet.c b/sheep/sdnet.c
index c13cdb0..bde2526 100644
--- a/sheep/sdnet.c
+++ b/sheep/sdnet.c
@@ -368,8 +368,7 @@ static void requeue_request(struct request *req)
queue_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)
{
@@ -429,7 +428,7 @@ static struct request *alloc_request(struct client_info *ci, int data_length)
return NULL;
req->ci = ci;
- client_incref(ci);
+ ci->refcnt++;
if (data_length) {
req->data_length = data_length;
req->data = valloc(data_length);
@@ -453,6 +452,7 @@ static void free_request(struct request *req)
sys->nr_outstanding_reqs--;
sys->outstanding_data_size -= req->data_length;
+ req->ci->refcnt--;
put_vnode_info(req->vnodes);
free(req->data);
free(req);
@@ -473,11 +473,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,16 +652,21 @@ static void destroy_client(struct client_info *ci)
free(ci);
}
-static void client_incref(struct client_info *ci)
+static void clear_client(struct client_info *ci)
{
- if (ci)
- ci->refcnt++;
-}
+ if (!list_empty(&ci->conn.blocking_siblings))
+ list_del_init(&ci->conn.blocking_siblings);
-static void client_decref(struct client_info *ci)
-{
- if (ci && --ci->refcnt == 0)
- destroy_client(ci);
+ 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 struct client_info *create_client(int fd, struct cluster_info *cluster)
@@ -693,7 +697,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 +724,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