summaryrefslogtreecommitdiffstats
path: root/libglusterfs/src/syncop.h
diff options
context:
space:
mode:
authorKrishnan Parthasarathi <kparthas@redhat.com>2013-04-15 15:41:21 +0530
committerVijay Bellur <vbellur@redhat.com>2013-04-17 01:53:20 -0700
commit563b608126e812482a25464df7c70079fb0ba2c0 (patch)
tree0f85cd9accc5cb885ea587f5b75bb72340b536c7 /libglusterfs/src/syncop.h
parent4c8bb7c4b0471fe2a5095639f0fd44f50ba28dc8 (diff)
synctask: introduce synclocks for co-operative locking
This patch introduces a synclocks - co-operative locks for synctasks. Synctasks yield themselves when a lock cannot be acquired at the time of the lock call, and the unlocker will wake the yielded locker at the time of unlock. The implementation is safe in a multi-threaded syncenv framework. It is also safe for sharing the lock between non-synctasks. i.e, the same lock can be used for synchronization between a synctask and a regular thread. In such a situation, waiting synctasks will yield themselves while non-synctasks will sleep on a cond variable. The unlocker (which could be either a synctask or a regular thread) will wake up any type of lock waiter (synctask or regular). Usage: Declaration and Initialization ------------------------------ synclock_t lock; ret = synclock_init (&lock); if (ret) { /* lock could not be allocated */ } Locking and non-blocking lock attempt ------------------------------------- ret = synclock_trylock (&lock); if (ret && (errno == EBUSY)) { /* lock is held by someone else */ return; } synclock_lock (&lock); { /* critical section */ } synclock_unlock (&lock); BUG: 763820 Change-Id: I23066f7b66b41d3d9fb2311fdaca333e98dd7442 Signed-off-by: Krishnan Parthasarathi <kparthas@redhat.com> Original-author: Anand Avati <avati@redhat.com> Reviewed-on: http://review.gluster.org/4830 Tested-by: Gluster Build System <jenkins@build.gluster.com> Reviewed-by: Vijay Bellur <vbellur@redhat.com>
Diffstat (limited to 'libglusterfs/src/syncop.h')
-rw-r--r--libglusterfs/src/syncop.h18
1 files changed, 18 insertions, 0 deletions
diff --git a/libglusterfs/src/syncop.h b/libglusterfs/src/syncop.h
index 764f29605..b1a7229b3 100644
--- a/libglusterfs/src/syncop.h
+++ b/libglusterfs/src/syncop.h
@@ -69,6 +69,8 @@ struct synctask {
pthread_mutex_t mutex; /* for synchronous spawning of synctask */
pthread_cond_t cond;
int done;
+
+ struct list_head waitq; /* can wait only "once" at a time */
};
@@ -96,6 +98,15 @@ struct syncenv {
};
+struct synclock {
+ pthread_mutex_t guard; /* guard the remaining members, pair @cond */
+ pthread_cond_t cond; /* waiting non-synctasks */
+ struct list_head waitq; /* waiting synctasks */
+ gf_boolean_t lock; /* _gf_true or _gf_false, lock status */
+ struct synctask *owner; /* NULL if current owner is not a synctask */
+};
+typedef struct synclock synclock_t;
+
struct syncargs {
int op_ret;
int op_errno;
@@ -219,6 +230,13 @@ void synctask_waitfor (struct synctask *task, int count);
int synctask_setid (struct synctask *task, uid_t uid, gid_t gid);
#define SYNCTASK_SETID(uid, gid) synctask_setid (synctask_get(), uid, gid);
+
+int synclock_init (synclock_t *lock);
+int synclock_destory (synclock_t *lock);
+int synclock_lock (synclock_t *lock);
+int synclock_trylock (synclock_t *lock);
+int synclock_unlock (synclock_t *lock);
+
int syncop_lookup (xlator_t *subvol, loc_t *loc, dict_t *xattr_req,
/* out */
struct iatt *iatt, dict_t **xattr_rsp, struct iatt *parent);