/*
* Copyright 2000, International Business Machines Corporation and others.
* All Rights Reserved.
- *
+ *
* This software has been released under the terms of the IBM Public
* License. For details, see the LICENSE file in the top-level source
* directory or online at http://www.openafs.org/dl/license10.html
#include <afsconfig.h>
#include <afs/param.h>
+#include <roken.h>
#include <sys/types.h>
#include <stdarg.h>
* as it requires ulock_getLock to be called with await = 0. And ulock_SetLock
* isn't even used in this code base. Since NT doesn't have a native
* #EAGAIN, we are replacing all instances of #EWOULDBLOCK with #EAGAIN.
- *
+ *
*/
#define WouldReadBlock(lock)\
if (atrans->flags & TRDONE)
return UDONE;
+ if (atype != LOCKREAD && (atrans->flags & TRREADWRITE)) {
+ return EINVAL;
+ }
+
if (atrans->locktype != 0) {
ubik_print("Ubik: Internal Error: attempted to take lock twice\n");
abort();
*/
/* Check if the lock would would block */
- if (!await) {
+ if (!await && !(atrans->flags & TRREADWRITE)) {
if (atype == LOCKREAD) {
if (WouldReadBlock(&rwlock))
return EAGAIN;
}
/* Create new lock record and add to spec'd transaction:
- * #if defined(UBIK_PAUSE)
- * * locktype. Before doing that, set TRSETLOCK,
- * * to tell udisk_end that another thread (us) is waiting.
- * #else
- * * locktype. This field also tells us if the thread is
- * * waiting for a lock: It will be equal to LOCKWAIT.
- * #endif
+ * locktype. This field also tells us if the thread is
+ * waiting for a lock: It will be equal to LOCKWAIT.
*/
-#if defined(UBIK_PAUSE)
- if (atrans->flags & TRSETLOCK) {
- printf("Ubik: Internal Error: TRSETLOCK already set?\n");
- return EBUSY;
- }
- atrans->flags |= TRSETLOCK;
-#else
atrans->locktype = LOCKWAIT;
-#endif /* UBIK_PAUSE */
DBRELE(dbase);
- if (atype == LOCKREAD) {
+ if (atrans->flags & TRREADWRITE) {
+ /* noop; don't actually lock anything for TRREADWRITE */
+ } else if (atype == LOCKREAD) {
ObtainReadLock(&rwlock);
} else {
ObtainWriteLock(&rwlock);
}
DBHOLD(dbase);
atrans->locktype = atype;
-#if defined(UBIK_PAUSE)
- atrans->flags &= ~TRSETLOCK;
-#if 0
- /* We don't do this here, because this can only happen in SDISK_Lock,
- * and there's already code there to catch this condition.
- */
- if (atrans->flags & TRSTALE) {
- udisk_end(atrans);
- return UINTERNAL;
- }
-#endif
-#endif /* UBIK_PAUSE */
/*
*ubik_print("Ubik: DEBUG: Thread 0x%x took %s lock\n", lwp_cpptr,
if (rwlockinit)
return;
- if (atrans->locktype == LOCKREAD) {
+ if (atrans->locktype == LOCKWRITE && (atrans->flags & TRREADWRITE)) {
+ ubik_print("Ubik: Internal Error: unlocking write lock with "
+ "TRREADWRITE?\n");
+ abort();
+ }
+
+ if (atrans->flags & TRREADWRITE) {
+ /* noop, TRREADWRITE means we don't actually lock anything */
+ } else if (atrans->locktype == LOCKREAD) {
ReleaseReadLock(&rwlock);
} else if (atrans->locktype == LOCKWRITE) {
ReleaseWriteLock(&rwlock);