summaryrefslogtreecommitdiffstats
path: root/xlators/protocol
diff options
context:
space:
mode:
Diffstat (limited to 'xlators/protocol')
-rw-r--r--xlators/protocol/client/src/client-handshake.c15
-rw-r--r--xlators/protocol/client/src/client.c78
-rw-r--r--xlators/protocol/client/src/client.h2
3 files changed, 71 insertions, 24 deletions
diff --git a/xlators/protocol/client/src/client-handshake.c b/xlators/protocol/client/src/client-handshake.c
index 42b7ac0745e..531b38eaf83 100644
--- a/xlators/protocol/client/src/client-handshake.c
+++ b/xlators/protocol/client/src/client-handshake.c
@@ -131,12 +131,11 @@ client_notify_parents_child_up (xlator_t *this)
int ret = 0;
conf = this->private;
- ret = default_notify (this, GF_EVENT_CHILD_UP, NULL);
+ ret = client_notify_dispatch (this, GF_EVENT_CHILD_UP, NULL);
if (ret)
gf_log (this->name, GF_LOG_INFO,
"notify of CHILD_UP failed");
- conf->last_sent_event = GF_EVENT_CHILD_UP;
return 0;
}
@@ -1146,11 +1145,12 @@ client_setvolume_cbk (struct rpc_req *req, struct iovec *iov, int count, void *m
op_ret = 0;
}
if (op_errno == ESTALE) {
- ret = default_notify (this, GF_EVENT_VOLFILE_MODIFIED, NULL);
+ ret = client_notify_dispatch (this,
+ GF_EVENT_VOLFILE_MODIFIED,
+ NULL);
if (ret)
gf_log (this->name, GF_LOG_INFO,
"notify of VOLFILE_MODIFIED failed");
- conf->last_sent_event = GF_EVENT_VOLFILE_MODIFIED;
}
goto out;
}
@@ -1223,13 +1223,12 @@ client_setvolume_cbk (struct rpc_req *req, struct iovec *iov, int count, void *m
out:
if (auth_fail) {
gf_log (this->name, GF_LOG_INFO, "sending AUTH_FAILED event");
- ret = default_notify (this, GF_EVENT_AUTH_FAILED, NULL);
+ ret = client_notify_dispatch (this, GF_EVENT_AUTH_FAILED, NULL);
if (ret)
gf_log (this->name, GF_LOG_INFO,
"notify of AUTH_FAILED failed");
conf->connecting = 0;
conf->connected = 0;
- conf->last_sent_event = GF_EVENT_AUTH_FAILED;
ret = -1;
}
if (-1 == op_ret) {
@@ -1238,11 +1237,11 @@ out:
* tell the parents that i am all ok..
*/
gf_log (this->name, GF_LOG_INFO, "sending CHILD_CONNECTING event");
- ret = default_notify (this, GF_EVENT_CHILD_CONNECTING, NULL);
+ ret = client_notify_dispatch (this, GF_EVENT_CHILD_CONNECTING,
+ NULL);
if (ret)
gf_log (this->name, GF_LOG_INFO,
"notify of CHILD_CONNECTING failed");
- conf->last_sent_event = GF_EVENT_CHILD_CONNECTING;
conf->connecting= 1;
ret = 0;
}
diff --git a/xlators/protocol/client/src/client.c b/xlators/protocol/client/src/client.c
index 999a4a5c836..00d88d6e7a1 100644
--- a/xlators/protocol/client/src/client.c
+++ b/xlators/protocol/client/src/client.c
@@ -34,6 +34,55 @@ int client_init_rpc (xlator_t *this);
int client_destroy_rpc (xlator_t *this);
int client_mark_fd_bad (xlator_t *this);
+static int
+client_notify_dispatch_uniq (xlator_t *this, int32_t event, void *data, ...)
+{
+ clnt_conf_t *conf = this->private;
+
+ if (conf->last_sent_event == event)
+ return 0;
+
+ return client_notify_dispatch (this, event, data);
+}
+
+int
+client_notify_dispatch (xlator_t *this, int32_t event, void *data, ...)
+{
+ int ret = -1;
+ glusterfs_ctx_t *ctx = this->ctx;
+ clnt_conf_t *conf = this->private;
+
+ pthread_mutex_lock (&ctx->notify_lock);
+ {
+ while (ctx->notifying)
+ pthread_cond_wait (&ctx->notify_cond,
+ &ctx->notify_lock);
+ ctx->notifying = 1;
+ }
+ pthread_mutex_unlock (&ctx->notify_lock);
+
+ /* We assume that all translators in the graph handle notification
+ * events in sequence.
+ * */
+ ret = default_notify (this, event, data);
+
+ /* NB (Even) with MT-epoll and EPOLLET|EPOLLONESHOT we are guaranteed
+ * that there would be atmost one poller thread executing this
+ * notification function. This allows us to update last_sent_event
+ * without explicit synchronization. See epoll(7).
+ */
+ conf->last_sent_event = event;
+
+ pthread_mutex_lock (&ctx->notify_lock);
+ {
+ ctx->notifying = 0;
+ pthread_cond_signal (&ctx->notify_cond);
+ }
+ pthread_mutex_unlock (&ctx->notify_lock);
+
+ return ret;
+}
+
int32_t
client_type_to_gf_type (short l_type)
{
@@ -2169,14 +2218,12 @@ client_rpc_notify (struct rpc_clnt *rpc, void *mydata, rpc_clnt_event_t event,
"handshake msg returned %d", ret);
} else {
//conf->rpc->connected = 1;
- if (conf->last_sent_event != GF_EVENT_CHILD_UP) {
- ret = default_notify (this, GF_EVENT_CHILD_UP,
- NULL);
- if (ret)
- gf_log (this->name, GF_LOG_INFO,
- "CHILD_UP notify failed");
- conf->last_sent_event = GF_EVENT_CHILD_UP;
- }
+ ret = client_notify_dispatch_uniq (this,
+ GF_EVENT_CHILD_UP,
+ NULL);
+ if (ret)
+ gf_log (this->name, GF_LOG_INFO,
+ "CHILD_UP notify failed");
}
/* Cancel grace timer if set */
@@ -2224,14 +2271,13 @@ client_rpc_notify (struct rpc_clnt *rpc, void *mydata, rpc_clnt_event_t event,
may get screwed up.. (eg. CHILD_MODIFIED event in
replicate), hence make sure events which are passed
to parent are genuine */
- if (conf->last_sent_event != GF_EVENT_CHILD_DOWN) {
- ret = default_notify (this, GF_EVENT_CHILD_DOWN,
- NULL);
- if (ret)
- gf_log (this->name, GF_LOG_INFO,
- "CHILD_DOWN notify failed");
- conf->last_sent_event = GF_EVENT_CHILD_DOWN;
- }
+ ret = client_notify_dispatch_uniq (this,
+ GF_EVENT_CHILD_DOWN,
+ NULL);
+ if (ret)
+ gf_log (this->name, GF_LOG_INFO,
+ "CHILD_DOWN notify failed");
+
} else {
if (conf->connected)
gf_log (this->name, GF_LOG_DEBUG,
diff --git a/xlators/protocol/client/src/client.h b/xlators/protocol/client/src/client.h
index af70926b178..1aea1353727 100644
--- a/xlators/protocol/client/src/client.h
+++ b/xlators/protocol/client/src/client.h
@@ -262,4 +262,6 @@ int client_fd_fop_prepare_local (call_frame_t *frame, fd_t *fd,
int64_t remote_fd);
gf_boolean_t
__is_fd_reopen_in_progress (clnt_fd_ctx_t *fdctx);
+int
+client_notify_dispatch (xlator_t *this, int32_t event, void *data, ...);
#endif /* !_CLIENT_H */