summaryrefslogtreecommitdiffstats
path: root/xlators/features/changelog/src/changelog-helpers.c
diff options
context:
space:
mode:
authorKotresh HR <khiremat@redhat.com>2016-05-09 16:54:00 +0530
committerJeff Darcy <jdarcy@redhat.com>2016-06-16 09:03:15 -0700
commit650459c4178eff6fba82351d044c995ab7d046b1 (patch)
treef8c1f3516fdb1c923ef8e8af29513f7287d7a860 /xlators/features/changelog/src/changelog-helpers.c
parentdca4de364cd948ec7dade4416425ea1353911066 (diff)
features/changelog: Change barrier notification mechanism
Backport of http://review.gluster.org/14272 The barrier notification mechanism was fd based and 'select' was being used. 'select' breaks when number of fds opened by brick process exceeds 1024. To avoid this and also the maintainance of pipe between notify and 'changelog_rollover', the pipe has been replaced with pthread condition signal and timed wait mechanism. Change-Id: I530ea90d9a06953f8b23b4e12d122872ee1925de BUG: 1341952 Signed-off-by: Kotresh HR <khiremat@redhat.com> Reviewed-on: http://review.gluster.org/14615 Smoke: Gluster Build System <jenkins@build.gluster.org> NetBSD-regression: NetBSD Build System <jenkins@build.gluster.org> CentOS-regression: Gluster Build System <jenkins@build.gluster.org> Reviewed-by: Raghavendra Bhat <raghavendra@redhat.com> Reviewed-by: Jeff Darcy <jdarcy@redhat.com>
Diffstat (limited to 'xlators/features/changelog/src/changelog-helpers.c')
-rw-r--r--xlators/features/changelog/src/changelog-helpers.c81
1 files changed, 38 insertions, 43 deletions
diff --git a/xlators/features/changelog/src/changelog-helpers.c b/xlators/features/changelog/src/changelog-helpers.c
index ba98021..dd7fbbe 100644
--- a/xlators/features/changelog/src/changelog-helpers.c
+++ b/xlators/features/changelog/src/changelog-helpers.c
@@ -1210,15 +1210,10 @@ changelog_rollover (void *data)
{
int ret = 0;
xlator_t *this = NULL;
- struct timeval tv = {0,};
+ struct timespec tv = {0,};
changelog_log_data_t cld = {0,};
changelog_time_slice_t *slice = NULL;
changelog_priv_t *priv = data;
- int max_fd = 0;
- char buf[1] = {0};
- int len = 0;
-
- fd_set rset;
this = priv->cr.this;
slice = &priv->slice;
@@ -1226,44 +1221,41 @@ changelog_rollover (void *data)
while (1) {
(void) pthread_testcancel();
- tv.tv_sec = priv->rollover_time;
- tv.tv_usec = 0;
- FD_ZERO(&rset);
- FD_SET(priv->cr.rfd, &rset);
- max_fd = priv->cr.rfd;
- max_fd = max_fd + 1;
-
- /* It seems there is a race between actual rollover and explicit
- * rollover. But it is handled. If actual rollover is being
- * done and the explicit rollover event comes, the event is
- * not missed. The next select will immediately wakeup to
- * handle explicit wakeup.
+ tv.tv_sec = time (NULL) + priv->rollover_time;
+ tv.tv_nsec = 0;
+ ret = 0; /* Reset ret to zero */
+
+ /* The race between actual rollover and explicit rollover is
+ * handled. If actual rollover is being done and the
+ * explicit rollover event comes, the event is not missed.
+ * Since explicit rollover sets 'cr.notify' to true, this
+ * thread doesn't wait on 'pthread_cond_timedwait'.
*/
+ pthread_cleanup_push (changelog_cleanup_free_mutex,
+ &priv->cr.lock);
+ pthread_mutex_lock (&priv->cr.lock);
+ {
+ while (ret == 0 && !priv->cr.notify)
+ ret = pthread_cond_timedwait (&priv->cr.cond,
+ &priv->cr.lock,
+ &tv);
+ if (ret == 0)
+ priv->cr.notify = _gf_false;
+ }
+ pthread_mutex_unlock (&priv->cr.lock);
+ pthread_cleanup_pop (0);
- ret = select (max_fd, &rset, NULL, NULL, &tv);
- if (ret == -1) {
- gf_log (this->name, GF_LOG_ERROR,
- "select failed: %s", strerror(errno));
- continue;
- } else if (ret && FD_ISSET(priv->cr.rfd, &rset)) {
+ if (ret == 0) {
gf_log (this->name, GF_LOG_INFO,
- "Explicit wakeup of select on barrier notify");
- len = read(priv->cr.rfd, buf, 1);
- if (len == 0) {
- gf_log (this->name, GF_LOG_ERROR, "BUG: Got EOF"
- " from reconfigure notification pipe");
- continue;
- }
- if (len < 0) {
- gf_log (this->name, GF_LOG_ERROR,
- "Failed to read wakeup data");
- continue;
- }
- /* Lock is not required as same thread is modifying.*/
+ "Explicit wakeup on barrier notify");
priv->explicit_rollover = _gf_true;
- } else {
- gf_log (this->name, GF_LOG_DEBUG,
- "select wokeup on timeout");
+ } else if (ret && ret != ETIMEDOUT) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "pthread_cond_timedwait failed: %s",
+ strerror (errno));
+ continue;
+ } else if (ret && ret == ETIMEDOUT) {
+ gf_log (this->name, GF_LOG_DEBUG, "Wokeup on timeout");
}
/* Reading curent_color without lock is fine here
@@ -1724,9 +1716,12 @@ changelog_barrier_notify (changelog_priv_t *priv, char *buf)
{
int ret = 0;
- LOCK(&priv->lock);
- ret = changelog_write (priv->cr_wfd, buf, 1);
- UNLOCK(&priv->lock);
+ pthread_mutex_lock (&priv->cr.lock);
+ {
+ ret = pthread_cond_signal (&priv->cr.cond);
+ priv->cr.notify = _gf_true;
+ }
+ pthread_mutex_unlock (&priv->cr.lock);
return ret;
}