[Cluster-devel] cluster/magma/lib global.c magma.h
lhh at sourceware.org
lhh at sourceware.org
Fri Jun 16 20:02:25 UTC 2006
CVSROOT: /cvs/cluster
Module name: cluster
Branch: STABLE
Changes by: lhh at sourceware.org 2006-06-16 20:02:25
Modified files:
magma/lib : global.c magma.h
Log message:
Merge from RHEL4 branch - fix #193128, part 1
Patches:
http://sourceware.org/cgi-bin/cvsweb.cgi/cluster/magma/lib/global.c.diff?cvsroot=cluster&only_with_tag=STABLE&r1=1.9.2.1&r2=1.9.2.1.6.1
http://sourceware.org/cgi-bin/cvsweb.cgi/cluster/magma/lib/magma.h.diff?cvsroot=cluster&only_with_tag=STABLE&r1=1.9.2.2.6.1&r2=1.9.2.2.6.2
--- cluster/magma/lib/Attic/global.c 2005/01/17 18:40:05 1.9.2.1
+++ cluster/magma/lib/Attic/global.c 2006/06/16 20:02:25 1.9.2.1.6.1
@@ -390,13 +390,66 @@
int
clu_lock(char *resource, int flags, void **lockpp)
{
- int ret, block = 0, err;
+ int ret = 0, block = 0, conv = 0, err;
block = !(flags & CLK_NOWAIT);
+ /*
+ Bug 193128
+
+ Try to use a conversion lock mechanism when possible
+ If the caller calls explicitly with a NULL lock, then
+ assume the caller knows what it is doing.
+
+ Only take the NULL lock if:
+ (a) the user isn't specifying CONVERT; if they are, they
+ know what they are doing.
+
+ ...and one of...
+
+ (b) This is a blocking call, or
+ (c) The user requested a NULL lock explicitly. In this case,
+ short-out early; there's no reason to convert a NULL lock
+ to a NULL lock.
+ */
+ if (!(flags & CLK_CONVERT) &&
+ (block || ((flags & CLK_EX) == 0))) {
+ /* Acquire NULL lock */
+ pthread_rwlock_wrlock(&dflt_lock);
+ ret = cp_lock(_cpp, resource, CLK_NULL, lockpp);
+ err = errno;
+ pthread_rwlock_unlock(&dflt_lock);
+ if (ret == 0) {
+ if ((flags & CLK_EX) == 0) {
+ /* User only wanted a NULL lock... */
+ return 0;
+ }
+ /*
+ Ok, NULL lock was taken, rest of blocking
+ call should be done using lock conversions.
+ */
+ flags |= CLK_CONVERT;
+ conv = 1;
+ } else {
+ switch(err) {
+ case EINVAL:
+ /* Oops, null locks don't work on this
+ plugin; use normal spam mode */
+ break;
+ default:
+ errno = err;
+ return -1;
+ }
+ }
+ }
+
while (1) {
+ /*
+ printf("upgrading to requested lock %04x...\n", flags);
+ */
pthread_rwlock_wrlock(&dflt_lock);
- ret = cp_lock(_cpp, resource, flags | CLK_NOWAIT, lockpp);
+ ret = cp_lock(_cpp, resource,
+ flags | CLK_NOWAIT, lockpp);
err = errno;
pthread_rwlock_unlock(&dflt_lock);
@@ -407,7 +460,16 @@
break;
}
-
+
+ if (ret != 0 && conv) {
+ /* If we get some other error, release the NL lock we
+ took so we don't leak locks*/
+ pthread_rwlock_wrlock(&dflt_lock);
+ cp_unlock(_cpp, resource, lockpp);
+ pthread_rwlock_unlock(&dflt_lock);
+ errno = err;
+ }
+
return ret;
}
--- cluster/magma/lib/Attic/magma.h 2006/01/20 16:10:12 1.9.2.2.6.1
+++ cluster/magma/lib/Attic/magma.h 2006/06/16 20:02:25 1.9.2.2.6.2
@@ -110,7 +110,11 @@
#define CLK_WRITE (1<<1) /** Write lock */
#define CLK_READ (1<<2) /** Read lock */
#define CLK_HOLDER (1<<3) /** Return the holder node ID if lock is held*/
-#define CLK_EX (CLK_READ|CLK_WRITE)
+#define CLK_CONVERT (1<<4) /** Convert this lock to a new type (may not
+ be supported on all plugins; caller
+ must be aware of this fact */
+#define CLK_EX (CLK_READ|CLK_WRITE) /** Exclusive lock */
+#define CLK_NULL (0) /** No bits set */
#define NODE_ID_NONE ((uint64_t)-1) /** The nonexistent cluster member */
More information about the Cluster-devel
mailing list