diff options
Diffstat (limited to 'xlators/features')
-rw-r--r-- | xlators/features/changelog/src/changelog-helpers.c | 84 | ||||
-rw-r--r-- | xlators/features/changelog/src/changelog-helpers.h | 8 | ||||
-rw-r--r-- | xlators/features/changelog/src/changelog.c | 57 |
3 files changed, 69 insertions, 80 deletions
diff --git a/xlators/features/changelog/src/changelog-helpers.c b/xlators/features/changelog/src/changelog-helpers.c index 6d3b99c6cdc..0cb68587e57 100644 --- a/xlators/features/changelog/src/changelog-helpers.c +++ b/xlators/features/changelog/src/changelog-helpers.c @@ -1259,15 +1259,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; @@ -1275,48 +1270,42 @@ 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_msg (this->name, GF_LOG_ERROR, errno, - CHANGELOG_MSG_SELECT_FAILED, - "select failed"); - continue; - } else if (ret && FD_ISSET(priv->cr.rfd, &rset)) { + if (ret == 0) { gf_msg (this->name, GF_LOG_INFO, 0, CHANGELOG_MSG_BARRIER_INFO, - "Explicit wakeup of select on barrier notify"); - len = sys_read (priv->cr.rfd, buf, 1); - if (len == 0) { - gf_msg (this->name, GF_LOG_ERROR, errno, - CHANGELOG_MSG_READ_ERROR, "BUG: Got EOF" - " from reconfigure notification pipe"); - continue; - } - if (len < 0) { - gf_msg (this->name, GF_LOG_ERROR, 0, - CHANGELOG_MSG_READ_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_msg_debug (this->name, 0, - "select wokeup on timeout"); + } else if (ret && ret != ETIMEDOUT) { + gf_msg (this->name, GF_LOG_ERROR, errno, + CHANGELOG_MSG_SELECT_FAILED, + "pthread_cond_timedwait failed"); + continue; + } else if (ret && ret == ETIMEDOUT) { + gf_msg_debug (this->name, 0, "Wokeup on timeout"); } /* Reading curent_color without lock is fine here @@ -1783,9 +1772,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; } diff --git a/xlators/features/changelog/src/changelog-helpers.h b/xlators/features/changelog/src/changelog-helpers.h index 70e6f60f30c..4fdba244aa1 100644 --- a/xlators/features/changelog/src/changelog-helpers.h +++ b/xlators/features/changelog/src/changelog-helpers.h @@ -116,8 +116,9 @@ typedef struct changelog_rollover { xlator_t *this; - /* read end of pipe used as event from barrier on snapshot */ - int rfd; + pthread_mutex_t lock; + pthread_cond_t cond; + gf_boolean_t notify; } changelog_rollover_t; typedef struct changelog_fsync { @@ -265,9 +266,6 @@ struct changelog_priv { /* Represents the active color. Initially by default black */ chlog_fop_color_t current_color; - /* write end of pipe to do explicit rollover on barrier during snap */ - int cr_wfd; - /* flag to determine explicit rollover is triggered */ gf_boolean_t explicit_rollover; diff --git a/xlators/features/changelog/src/changelog.c b/xlators/features/changelog/src/changelog.c index cbfc307eb3c..f8f95cf0e81 100644 --- a/xlators/features/changelog/src/changelog.c +++ b/xlators/features/changelog/src/changelog.c @@ -2046,11 +2046,6 @@ changelog_cleanup_helper_threads (xlator_t *this, changelog_priv_t *priv) if (priv->cr.rollover_th) { (void) changelog_thread_cleanup (this, priv->cr.rollover_th); priv->cr.rollover_th = 0; - ret = sys_close (priv->cr_wfd); - if (ret) - gf_msg (this->name, GF_LOG_ERROR, errno, - CHANGELOG_MSG_CLOSE_ERROR, - "error closing write end of rollover pipe"); } if (priv->cf.fsync_th) { @@ -2065,7 +2060,6 @@ changelog_spawn_helper_threads (xlator_t *this, changelog_priv_t *priv) { int ret = 0; int flags = 0; - int pipe_fd[2] = {0, 0}; /* Geo-Rep snapshot dependency: * @@ -2079,29 +2073,7 @@ changelog_spawn_helper_threads (xlator_t *this, changelog_priv_t *priv) * the write end of the pipe in 'reconfigure'. */ - ret = pipe (pipe_fd); - if (ret == -1) { - gf_msg (this->name, GF_LOG_ERROR, - errno, CHANGELOG_MSG_PIPE_CREATION_ERROR, - "Cannot create pipe"); - goto out; - } - - /* writer is non-blocking */ - flags = fcntl (pipe_fd[1], F_GETFL); - flags |= O_NONBLOCK; - - ret = fcntl (pipe_fd[1], F_SETFL, flags); - if (ret) { - gf_msg (this->name, GF_LOG_ERROR, errno, - CHANGELOG_MSG_FCNTL_FAILED, - "failed to set O_NONBLOCK flag"); - goto out; - } - - priv->cr_wfd = pipe_fd[1]; - priv->cr.rfd = pipe_fd[0]; - + priv->cr.notify = _gf_false; priv->cr.this = this; ret = gf_thread_create (&priv->cr.rollover_th, NULL, changelog_rollover, priv); @@ -2419,6 +2391,8 @@ changelog_barrier_pthread_init (xlator_t *this, changelog_priv_t *priv) gf_boolean_t dm_cond_black_init = _gf_false; gf_boolean_t dm_mutex_white_init = _gf_false; gf_boolean_t dm_cond_white_init = _gf_false; + gf_boolean_t cr_mutex_init = _gf_false; + gf_boolean_t cr_cond_init = _gf_false; int ret = 0; if ((ret = pthread_mutex_init(&priv->bn.bnotify_mutex, NULL)) != 0) { @@ -2476,6 +2450,24 @@ changelog_barrier_pthread_init (xlator_t *this, changelog_priv_t *priv) goto out; } dm_cond_white_init = _gf_true; + + if ((pthread_mutex_init(&priv->cr.lock, NULL)) != 0) { + gf_msg (this->name, GF_LOG_ERROR, errno, + CHANGELOG_MSG_PTHREAD_MUTEX_INIT_FAILED, + "changelog_rollover lock init failed (%d)", ret); + ret = -1; + goto out; + } + cr_mutex_init = _gf_true; + + if ((pthread_cond_init(&priv->cr.cond, NULL)) != 0) { + gf_msg (this->name, GF_LOG_ERROR, errno, + CHANGELOG_MSG_PTHREAD_COND_INIT_FAILED, + "changelog_rollover cond init failed (%d)", ret); + ret = -1; + goto out; + } + cr_cond_init = _gf_true; out: if (ret) { if (bn_mutex_init) @@ -2490,6 +2482,10 @@ changelog_barrier_pthread_init (xlator_t *this, changelog_priv_t *priv) pthread_mutex_destroy(&priv->dm.drain_white_mutex); if (dm_cond_white_init) pthread_cond_destroy (&priv->dm.drain_white_cond); + if (cr_mutex_init) + pthread_mutex_destroy(&priv->cr.lock); + if (cr_cond_init) + pthread_cond_destroy (&priv->cr.cond); } return ret; } @@ -2504,6 +2500,8 @@ changelog_barrier_pthread_destroy (changelog_priv_t *priv) pthread_cond_destroy (&priv->dm.drain_black_cond); pthread_mutex_destroy (&priv->dm.drain_white_mutex); pthread_cond_destroy (&priv->dm.drain_white_cond); + pthread_mutex_destroy(&priv->cr.lock); + pthread_cond_destroy (&priv->cr.cond); LOCK_DESTROY (&priv->bflags.lock); } @@ -2834,6 +2832,7 @@ init (xlator_t *this) priv->current_color = FOP_COLOR_BLACK; priv->explicit_rollover = _gf_false; + priv->cr.notify = _gf_false; /* Mutex is not needed as threads are not spawned yet */ priv->bn.bnotify = _gf_false; priv->bn.bnotify_error = _gf_false; |