From: levin li <xingke.lwp at taobao.com> add a flag SD_FLAG_CMD_WORKER to vdi_req, when a node receives a notified request with this flag, it will force process_main() running in the __sd_notify() which is running in worker thread, sometimes we need to notify a request to all the node, but we need it to run in worker thread, in this case it's useful. Signed-off-by: levin li <xingke.lwp at taobao.com> --- include/sheep.h | 1 + sheep/group.c | 14 +++++++++++++- sheep/ops.c | 3 ++- 3 files changed, 16 insertions(+), 2 deletions(-) diff --git a/include/sheep.h b/include/sheep.h index 7e287c4..f72460d 100644 --- a/include/sheep.h +++ b/include/sheep.h @@ -60,6 +60,7 @@ #define SD_FLAG_CMD_CREAT 0x0100 #define SD_FLAG_CMD_EXCL 0x0200 #define SD_FLAG_CMD_DEL 0x0400 +#define SD_FLAG_CMD_WORKER 0x0800 #define SD_RES_OLD_NODE_VER 0x41 /* Remote node has an old epoch */ #define SD_RES_NEW_NODE_VER 0x42 /* Remote node has a new epoch */ diff --git a/sheep/group.c b/sheep/group.c index d55ec7c..75bd61c 100644 --- a/sheep/group.c +++ b/sheep/group.c @@ -613,6 +613,17 @@ static void update_cluster_info(struct join_message *msg, static void __sd_notify(struct event_struct *cevent) { + struct work_notify *w = container_of(cevent, struct work_notify, cev); + struct vdi_op_message *msg = w->msg; + const struct sd_req *req = (const struct sd_req *)&msg->req; + int ret = msg->rsp.result; + struct sd_op_template *op = get_sd_op(req->opcode); + + if (ret == SD_RES_SUCCESS && has_process_bottom(op) && + req->flags & SD_FLAG_CMD_WORKER) { + ret = do_process_bottom(op, req, (struct sd_rsp *)&msg->rsp, msg->data); + msg->rsp.result = ret; + } } static void __sd_notify_done(struct event_struct *cevent) @@ -623,7 +634,8 @@ static void __sd_notify_done(struct event_struct *cevent) int ret = msg->rsp.result; struct sd_op_template *op = get_sd_op(msg->req.opcode); - if (ret == SD_RES_SUCCESS && has_process_bottom(op)) + if (ret == SD_RES_SUCCESS && has_process_bottom(op) && + !(msg->req.flags & SD_FLAG_CMD_WORKER)) ret = do_process_bottom(op, (const struct sd_req *)&msg->req, (struct sd_rsp *)&msg->rsp, msg->data); diff --git a/sheep/ops.c b/sheep/ops.c index ea35d43..f2e6180 100644 --- a/sheep/ops.c +++ b/sheep/ops.c @@ -40,7 +40,8 @@ struct sd_op_template { /* * process_top() will be called in the worker thread, and - * process_bottom() will be called in the main thread. + * process_bottom() will be called in the main thread, except the + * case that SD_FLAG_CMD_WORKER is set for the cluster request. * * If type is SD_OP_TYPE_CLUSTER, it is guaranteed that only * one node processes a cluster operation at the same time. -- 1.7.10 |