Files
mars-nwe/include/nwnss/comnSA/comnLock.h

321 lines
8.1 KiB
C

/****************************************************************************
|
| (C) Copyright 1985, 1991, 1993, 1996 Novell, Inc.
| All Rights Reserved.
|
| This program is free software; you can redistribute it and/or
| modify it under the terms of version 2 of the GNU General Public
| License as published by the Free Software Foundation.
|
| This program is distributed in the hope that it will be useful,
| but WITHOUT ANY WARRANTY; without even the implied warranty of
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
| GNU General Public License for more details.
|
| You should have received a copy of the GNU General Public License
| along with this program; if not, contact Novell, Inc.
|
| To contact Novell about this file by physical or electronic mail,
| you may find current contact information at www.novell.com
|
|***************************************************************************
|
| NetWare Advance File Services (NSS) Initialization module
|
|---------------------------------------------------------------------------
|
| $Author: taysom $
| $Date: 2004-12-31 01:10:58 +0530 (Fri, 31 Dec 2004) $
|
| $RCSfile$
| $Revision: 465 $
|
|---------------------------------------------------------------------------
| This module is used to:
| Common lock definitions needed by byte range locks, logical or record
| locks, and file name locks.
|
| WARNING! WARNING! WARNING! WARNING! WARNING! WARNING! WARNING! WARNING!
|
| This header file should ONLY be used for NSS internal development.
| This includes Semantic Agents (SA) and Loadable Storage Services (LSS).
| Any other use may cause conflicts which NSS will NOT fix.
+-------------------------------------------------------------------------*/
#ifndef _COMNLOCK_H_
#define _COMNLOCK_H_
#ifndef _OMNI_H
#include <omni.h>
#endif
#ifndef _RBPTREE_H_
#include <rbpTree.h>
#endif
#ifndef _COMNBEASTS_H_
#include <comnBeasts.h>
#endif
#ifndef _PSSCONNECTION_H_
#include <pssConnection.h>
#endif
#ifdef __cplusplus
extern "C" {
#endif
/* Pre-define struct(s) so Linux compiler doesn't complain */
struct LockByteRangeMsg_s;
struct LockSetMsg_s;
struct UnlockByteRangeMsg_s;
typedef enum LockType_t
{
LK_BYTERANGE,
LK_LOGICAL,
LK_FILENAME
} LockType_t;
typedef enum LockState_t
{
LK_IDLE,
LK_WAITING,
LK_LOCKED
} LockState_t;
typedef struct Reply_s Reply_s;
struct Reply_s
{
FsmLite_s fsm; /* Fsm for callbacks */
OneShot_s alarm; /* Limits how long we wait for locks*/
voidfunc_t saCallBack; /* Semantic Agent specific call back*/
voidfunc_t userCallBack; /* Call back function */
ADDR userData; /* What we pass back to the user */
};
typedef struct LockSet_s
{
Reply_s reply; /* Reply for lock set requests */
RBP_Node_s *setRoot; /* Locks in this lock set */
NINT waiting; /* Num locks we are waiting for */
STATUS saStatus; /* Status from the Semantic Agent */
NINT otherSAs; /* Other SAs we are waiting for */
} LockSet_s;
typedef struct LockHeader_s
{
Reply_s reply; /* Reply for single lock requests */
LockSet_s *lockSet; /* Lock is a member of this set */
RBP_Node_s sibling; /* Other byte range locks for task */
DQhead_t waiters; /* Those waiting for the lock */
DQlink_t waiting; /* Waiting for lock (could use waiters) */
BOOL waitForever; /* How long to wait if blocked */
BYTE mode; /* Mode of the lock (S, X, N) */
BYTE state; /* Lock state (LockState_t) */
BYTE reserved[2];
} LockHeader_s;
typedef struct ByteRangeLock_s
{
LockHeader_s head;
RBP_Node_s startHeld; /* Starting offset tree for held locks */
RBP_Node_s endHeld; /* Ending offset tree for held locks */
QUAD start; /* Starting address for byte range lock */
QUAD end; /* Ending address for byte range lock */
ADDR lockData; /* compared when finding a lock */
NamedBeast_s *beast; /* Beast for byte range lock */
FileHandle_s *fh; /* File handle that owns the lock */
} ByteRangeLock_s;
#if NSS_DEBUG IS_ENABLED
#define INIT_REPLY(_reply) \
{ \
static NINT instance = 0; \
\
FSMLITE_INIT( &(_reply)->fsm, WHERE, instance); \
++instance; \
INIT_ONESHOT((_reply)->alarm); \
(_reply)->saCallBack = NULL; \
}
#else
#define INIT_REPLY(_reply) \
{ \
FSMLITE_INIT( &(_reply)->fsm, NULL, 0); \
INIT_ONESHOT((_reply)->alarm); \
(_reply)->saCallBack = NULL; \
}
#endif
#define COPY_CALLBACKS(_reply, _msg) \
{ \
(_reply)->saCallBack = (_msg)->saCallBack; \
(_reply)->userCallBack = (_msg)->userCallBack; \
(_reply)->userData = (_msg)->userData; \
}
/*
* INIT_LOCKHEAD initializes the lock header and
* sets its initialize state to FREE. Assumes fields
* are all already set to 0.
*/
#define INIT_LOCKHEAD(_head, _lockSet, _mode, _waitForever) \
{ \
INIT_REPLY( &((_head)->reply)); \
DQ_INIT( &(_head)->waiters); \
(_head)->lockSet = (_lockSet); \
(_head)->mode = (_mode); \
(_head)->state = LK_IDLE; \
(_head)->waitForever = (_waitForever); \
}
#define HAS_BYTE_RANGE_LOCKS(_beast) \
(((NamedBeast_s *)(_beast))->startLocks != NULL)
/*
* Function prototypes
*/
struct UserXaction_s *COMN_FindDefaultXaction (
struct GeneralMsg_s *genMsg);
void COMN_ConnectionUnlockByteRange(
struct NSSConnection_s *nssConn);
void COMN_TaskUnlockByteRange(
struct GeneralMsg_s *genMsg);
void COMN_BeastUnlockByteRange(
struct GeneralMsg_s *genMsg,
struct NamedBeast_s *beast,
struct FileHandle_s *fileHandle);
STATUS COMN_LockByteRange(
struct GeneralMsg_s *genMsg,
struct LockByteRangeMsg_s *lockMsg);
STATUS COMN_LockByteRangeSet(
struct GeneralMsg_s *genMsg,
struct LockSetMsg_s *setMsg);
STATUS COMN_UnlockByteRange(
struct GeneralMsg_s *genMsg,
struct UnlockByteRangeMsg_s *unlockMsg);
ByteRangeLock_s *COMN_FindByteRangeLock(
struct GeneralMsg_s *genMsg,
struct LockByteRangeMsg_s *lockMsg);
STATUS COMN_UnlockByteRangeSet(
struct GeneralMsg_s *genMsg,
BOOL clear);
BOOL LOCK_IsSharedByteRange (
struct FileHandle_s *fh,
Xid_t userXid,
QUAD start,
QUAD length);
BOOL LOCK_IsExclusiveByteRange (
struct FileHandle_s *fh,
Xid_t userXid,
QUAD start,
QUAD length);
BOOL LOCK_IsExclusiveByteRangeMandatory (
NamedBeast_s *beast,
QUAD start,
QUAD length);
ByteRangeLock_s *findByteRangeLock(
struct UnlockByteRangeMsg_s *unlockMsg);
void unlockByteRangeSet(
struct LockSet_s *lockSet,
BOOL clear);
ByteRangeLock_s *testLock(
NamedBeast_s *beast,
QUAD start,
QUAD end,
NINT mode,
LockSet_s *lockSet,
NINT semanticAgentID);
void lockChangeStart(ByteRangeLock_s *lock, QUAD start);
void lockChangeEnd(ByteRangeLock_s *lock, QUAD end);
void lockForceLock(ByteRangeLock_s *lock);
void unlockByteRange (
ByteRangeLock_s *lock,
BOOL clear);
void unlockXaction(struct UserXaction_s *userXaction);
void initLockSet(struct LockSet_s *lockSet);
void wakeupLockRequests(ByteRangeLock_s *lock);
ByteRangeLock_s *allocByteRangeLock (
GeneralMsg_s *genMsg,
LockSet_s *lockSet,
struct LockByteRangeMsg_s *msg);
BOOL checkDeadLockByFH(
FileHandle_s *waiter,
FileHandle_s *holder,
BOOL setWaitFor);
void clearXactionWaitForByFH(
FileHandle_s *fh);
/***************************************************************************
* Logical lock definitions
***************************************************************************/
#define LOCK_HASH_SIZE 128
#define LOCK_MODE_EXCLUSIVE 1
#define LOCK_MODE_SHARED 2
#define LOCKED TRUE
#define NOT_LOCKED FALSE
#define MAX_KEY_LEN_BYTES 128
typedef struct Lock_s
{
BYTE key[MAX_KEY_LEN_BYTES];
BYTE keyLen;
BYTE pad[3];
Latch_s latch;
OneShot_s alarm;
DQlink_t hashLink;
} Lock_s;
extern STATUS LOCK_Startup(void);
extern void LOCK_Shutdown(void);
extern Lock_s *COMN_LookupLock(
BYTE *key,
NINT keyBytes,
BOOL allocIfNotThere);
extern BOOL COMN_LockFunc(
BYTE *key,
NINT keyBytes,
NINT mode,
SLONG msecs);
extern void COMN_UnLockFunc(
BYTE *key,
NINT keyBytes);
#ifdef __cplusplus
}
#endif
#endif