From mboxrd@z Thu Jan 1 00:00:00 1970 From: lhh@sourceware.org Date: 16 Jun 2006 19:54:08 -0000 Subject: [Cluster-devel] cluster/magma/lib global.c magma.h Message-ID: <20060616195408.25437.qmail@sourceware.org> List-Id: To: cluster-devel.redhat.com MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit CVSROOT: /cvs/cluster Module name: cluster Branch: RHEL4 Changes by: lhh at sourceware.org 2006-06-16 19:54:07 Modified files: magma/lib : global.c magma.h Log message: Allow NULL locks to be taken and add convert operation; use this when possible in clu_lock Patches: http://sourceware.org/cgi-bin/cvsweb.cgi/cluster/magma/lib/global.c.diff?cvsroot=cluster&only_with_tag=RHEL4&r1=1.9.2.1&r2=1.9.2.2 http://sourceware.org/cgi-bin/cvsweb.cgi/cluster/magma/lib/magma.h.diff?cvsroot=cluster&only_with_tag=RHEL4&r1=1.9.2.3&r2=1.9.2.4 --- 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 19:54:07 1.9.2.2 @@ -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:04:08 1.9.2.3 +++ cluster/magma/lib/Attic/magma.h 2006/06/16 19:54:07 1.9.2.4 @@ -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 */