From 4c0b149d8e7c574186a1ccefd9c74b79f8a06267 Mon Sep 17 00:00:00 2001 From: Krishnan Parthasarathi Date: Sat, 11 May 2013 14:36:38 +0530 Subject: syncop: Remove task from synclock's waitq before 'wake' Removing task from synclock's waitq after wake could result in a subsequent unlock, wake'ing up the already running task. This fix makes the removal from waitq and wake 'atomic'. Change-Id: Ie51ccf9d38f2cee84471097644aab95496f488b1 BUG: 948686 Signed-off-by: Krishnan Parthasarathi Reviewed-on: http://review.gluster.org/4987 Reviewed-by: Jeff Darcy Tested-by: Gluster Build System --- libglusterfs/src/syncop.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'libglusterfs/src') diff --git a/libglusterfs/src/syncop.c b/libglusterfs/src/syncop.c index 7dcdf3fe..98aee98d 100644 --- a/libglusterfs/src/syncop.c +++ b/libglusterfs/src/syncop.c @@ -529,12 +529,11 @@ __synclock_lock (struct synclock *lock) if (task) { /* called within a synctask */ list_add_tail (&task->waitq, &lock->waitq); - { - pthread_mutex_unlock (&lock->guard); - synctask_yield (task); - pthread_mutex_lock (&lock->guard); - } - list_del_init (&task->waitq); + pthread_mutex_unlock (&lock->guard); + synctask_yield (task); + /* task is removed from waitq in unlock, + * under lock->guard.*/ + pthread_mutex_lock (&lock->guard); } else { /* called by a non-synctask */ pthread_cond_wait (&lock->cond, &lock->guard); @@ -616,6 +615,7 @@ __synclock_unlock (synclock_t *lock) pthread_cond_signal (&lock->cond); if (!list_empty (&lock->waitq)) { task = list_entry (lock->waitq.next, struct synctask, waitq); + list_del_init (&task->waitq); synctask_wake (task); } -- cgit