diff options
| author | Krishnan Parthasarathi <kparthas@redhat.com> | 2013-05-11 14:36:38 +0530 | 
|---|---|---|
| committer | Vijay Bellur <vbellur@redhat.com> | 2013-05-15 22:21:41 -0700 | 
| commit | 4c0b149d8e7c574186a1ccefd9c74b79f8a06267 (patch) | |
| tree | c4b764cda3e67a08d48e4ecd2d5ea0e766db889d /libglusterfs | |
| parent | 845aeb709e0e7e037a5b5afc7bc084d58e7e97ee (diff) | |
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 <kparthas@redhat.com>
Reviewed-on: http://review.gluster.org/4987
Reviewed-by: Jeff Darcy <jdarcy@redhat.com>
Tested-by: Gluster Build System <jenkins@build.gluster.com>
Diffstat (limited to 'libglusterfs')
| -rw-r--r-- | libglusterfs/src/syncop.c | 12 | 
1 files changed, 6 insertions, 6 deletions
diff --git a/libglusterfs/src/syncop.c b/libglusterfs/src/syncop.c index 7dcdf3fef..98aee98dd 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);  	}  | 
