campo-sirio/cb/source/df4lock.c
alex 5432d61de9 Modifiche A.G.A.
git-svn-id: svn://10.65.10.50/trunk@4681 c028cbd2-c16b-5b4b-a496-9718f37d4682
1997-06-16 13:10:44 +00:00

1045 lines
30 KiB
C
Executable File

/* df4lock.c (c)Copyright Sequiter Software Inc., 1988-1996. All rights reserved. */
#include "d4all.h"
#ifndef S4UNIX
#ifdef __TURBOC__
#pragma hdrstop
#endif
#endif
#ifndef S4SINGLE
#ifdef S4CLIENT
int dfile4lock( DATA4FILE *data, const long clientId, const long serverId, const long rec, DATA4 *aux )
#else
int dfile4lock( DATA4FILE *data, const long clientId, const long serverId, const long rec )
#endif
{
int rc ;
CODE4 *c4 ;
#ifdef S4CLIENT
CONNECTION4 *connection ;
CONNECTION4LOCK_INFO_IN info ;
DATA4 *d4 ;
#else
long position ;
LOCK4 *lock, *lockOn ;
#endif
#ifdef E4PARM_LOW
if ( data == 0 || rec < 1L || clientId == 0
#ifdef S4SERVER
|| serverId == 0
#endif
)
return error4( 0, e4parm, E91102 ) ;
#endif
c4 = data->c4 ;
if ( error4code( c4 ) < 0 )
return e4codeBase ;
#ifdef S4CLIENT
if ( aux == 0 )
d4 = code4idData( c4, serverId, clientId ) ;
else
d4 = aux ;
if ( data->lockTest != 0 && code4unlockAuto( c4 ) != LOCK4ALL )
{
if ( c4->lockAttempts == WAIT4EVER )
return error4( c4, e4lock, E81523 ) ;
else
return r4locked ;
}
memset( &info, 0, sizeof( CONNECTION4LOCK_INFO_IN ) ) ;
connection = data->connection ;
if ( connection == 0 )
rc = e4connection ;
else
{
info.type = LOCK4RECORD ;
connection4assign( connection, CON4LOCK, clientId, data->serverId ) ;
connection4addData( connection, &info, sizeof( CONNECTION4LOCK_INFO_IN ), 0 ) ;
connection4addData( connection, &rec, sizeof( rec ), 0 ) ;
rc = connection4repeat( connection, -2, -1, -1, d4 ) ;
if ( rc < 0 )
connection4error( connection, c4, rc, E91102 ) ;
}
return rc ;
#else
if ( dfile4lockTest( data, clientId, serverId, rec ) > 0 ) /* if record or file already locked */
return 0 ;
if ( dfile4lockTest( data, 0L, 0L, rec ) > 0 ) /* if record or file already locked */
{
dfile4registerLocked( data, rec, 1 ) ;
#ifndef S4SERVER
if ( c4->lockAttempts == WAIT4EVER )
return error4( c4, e4lock, E81523 ) ;
#endif
return r4locked ;
}
if ( c4->lockMemory == 0 )
{
c4->lockMemory = mem4create( c4, c4->memStartLock, sizeof( LOCK4 ), c4->memExpandLock, 0 ) ;
if ( c4->lockMemory == 0 )
return -1 ;
}
#ifdef N4OTHER
position = L4LOCK_POS + rec ;
#endif
#ifdef S4MDX
position = L4LOCK_POS - rec - 1U ;
#endif
#ifdef S4FOX
if ( ( data->hasMdxMemo & 0x01 ) || data->version == 0x30 )
position = L4LOCK_POS - rec ;
else
position = L4LOCK_POS_OLD + dfile4recordPosition( data, rec ) ;
#endif
#ifdef S4MDX
rc = file4lock( &data->file, L4LOCK_POS - 1U, 1L ) ;
if ( rc == 0 )
{
#endif
rc = file4lock( &data->file, position, 1L) ;
#ifdef S4MDX
file4unlock( &data->file, L4LOCK_POS - 1U, 1L ) ;
}
#endif
if ( rc )
{
if ( rc == r4locked )
dfile4registerLocked( data, rec, 0 ) ;
return rc ;
}
lock = (LOCK4 *)mem4alloc( c4->lockMemory ) ;
if ( lock == 0 )
return -1 ;
lock->id.clientId = clientId ;
lock->id.serverId = serverId ;
lock->id.recNum = rec ;
for ( lockOn = 0 ;; )
{
lockOn =(LOCK4 *) l4next( &data->lockedRecords, lockOn ) ;
if ( lockOn == 0 )
{
lockOn = (LOCK4 *)l4last( &data->lockedRecords ) ;
if ( lockOn != 0 )
l4addAfter( &data->lockedRecords, lockOn, lock ) ;
else
{
l4add( &data->lockedRecords, lock ) ;
#ifdef E4MISC
if ( l4numNodes( &data->lockedRecords ) != 1 )
return error4( c4, e4info, E92723 ) ;
#endif
}
break ;
}
if ( lockOn->id.recNum > rec )
{
l4addBefore( &data->lockedRecords, lockOn, lock ) ;
break ;
}
}
return 0 ;
#endif
}
#ifndef S4CLIENT
#ifndef N4OTHER
#ifndef S4MEMO_OFF
int dfile4lockMemo( DATA4FILE *data )
{
return memo4fileLock( &data->memoFile ) ;
}
#endif
#endif
#endif
#ifdef S4CLIENT
int dfile4lockAppend( DATA4FILE *data, const long clientId, const long serverId, DATA4 *aux )
#else
int dfile4lockAppend( DATA4FILE *data, const long clientId, const long serverId )
#endif
{
int rc ;
CODE4 *c4 ;
#ifdef S4CLIENT
DATA4 *d4 ;
CONNECTION4LOCK_INFO_IN info ;
CONNECTION4 *connection ;
memset( &info, 0, sizeof( CONNECTION4LOCK_INFO_IN ) ) ;
#endif
#ifdef E4PARM_LOW
if ( data == 0 || clientId == 0
#ifdef S4SERVER
|| serverId == 0
#endif
)
return error4( 0, e4parm, E91102 ) ;
#endif
c4 = data->c4 ;
if ( error4code( c4 ) < 0 )
return -1 ;
#ifdef S4CLIENT
if ( aux == 0 )
d4 = code4idData( c4, serverId, clientId ) ;
else
d4 = aux ;
if ( data->lockTest != 0 && code4unlockAuto( c4 ) != LOCK4ALL )
{
if ( c4->lockAttempts == WAIT4EVER )
return error4( c4, e4lock, E81523 ) ;
else
return r4locked ;
}
connection = data->connection ;
if ( connection == 0 )
return e4connection ;
info.type = LOCK4APPEND ;
connection4assign( connection, CON4LOCK, clientId, data->serverId ) ;
connection4addData( connection, &info, sizeof( CONNECTION4LOCK_INFO_IN ), 0 ) ;
rc = connection4repeat( connection, -2, -1, -1, d4 ) ;
if ( rc < 0 )
return connection4error( connection, c4, rc, E91102 ) ;
#else
if ( dfile4lockTestAppend( data, clientId, serverId ) )
return 0 ;
if ( dfile4lockTestAppend( data, 0L, 0L ) )
{
dfile4registerLocked( data, 0L, 1 ) ;
#ifndef S4SERVER
if ( c4->lockAttempts == WAIT4EVER )
return error4( c4, e4lock, E81523 ) ;
#endif
return r4locked ;
}
rc = file4lock( &data->file, L4LOCK_POS, 1L ) ;
#ifndef S4OPTIMIZE_OFF
/* removed jan 29/96 AS. Unsure as to whether code still required under
new optimization lru-implementation. If so, this code must be
changed...
opt = &c4->opt ;
if ( data->file.lowAccessMode == OPEN4DENY_NONE && data->file.doBuffer == 1 && opt->numBuffers != 0 )
{
blockOn = opt4fileReturnBlock( &data->file, 0L, opt4fileHash( opt, &data->file, 0L ) ) ;
if ( blockOn )
if ( blockOn->changed )
{
l4remove( &opt->lists[ opt4fileHash( opt, &data->file, (unsigned long)blockOn->pos )], blockOn ) ;
opt4fileLruTop( &data->file, &blockOn->lruLink ) ;
l4add( &opt->avail, &blockOn->lruLink ) ;
opt4blockClear( blockOn ) ;
}
}
*/
#endif
if ( rc == 0 )
{
data->appendServerLock = serverId ;
data->appendClientLock = clientId ;
}
if ( rc == r4locked )
dfile4registerLocked( data, 0L, 0 ) ;
#endif
return rc ;
}
#ifdef S4USE_ADDITIVE_LOCK
#ifndef S4CLIENT
/* this function just performs the file4lock() command for a lock range.
if numRecs is 0 then this locks gap between recNum-1 and recNum for S4FOX with no prod. index
if numRecs is -1 then this locks to end of LOCK range */
static int dfile4lockRange( DATA4FILE *data, const long recNum, long numRecs )
{
int rc ;
#ifdef E4PARM_LOW
if ( recNum == 0L && numRecs != 1L )
return error4( data->c4, e4parm, E91102 ) ;
#endif
#ifdef N4OTHER
if (numRecs == 0)
return(0);
if (numRecs == -1L)
numRecs = L4LOCK_POS-recNum;
rc = file4lock( &data->file, L4LOCK_POS + recNum, numRecs ) ;
#endif
#ifdef S4MDX
if ( recNum == 0 ) /* lock append byte */
{
rc = file4lock( &data->file, L4LOCK_POS, 1L ) ;
return rc ;
}
if ( recNum == 1 )
{
rc = file4lock( &data->file, L4LOCK_POS - 1L, 1L ) ; /* lock flag */
if ( rc != 0 )
return rc ;
}
if (numRecs == 0)
return(0);
if ( numRecs == -1L )
rc = file4lock( &data->file, L4LOCK_POS_OLD, L4LOCK_POS - L4LOCK_POS_OLD - recNum ) ;
else
rc = file4lock( &data->file, L4LOCK_POS - recNum - numRecs, numRecs ) ;
if (rc != 0 && recNum == 1)
file4unlock( &data->file, L4LOCK_POS - 1L, 1L ) ;
#endif
#ifdef S4FOX
if ( recNum == 0L ) /* append byte */
rc = file4lock( &data->file, L4LOCK_POS, numRecs ) ;
else
{
if ( data->hasMdxMemo || data->version == 0x30 )
{
if (numRecs == 0)
return(0);
if (numRecs == -1L)
numRecs = L4LOCK_POS - L4LOCK_POS_OLD - recNum + 1L;
rc = file4lock( &data->file, L4LOCK_POS - recNum - numRecs + 1L, numRecs ) ;
}
else
{
if (numRecs == -1)
{
if (recNum == 1) /* also lock header bytes */
rc = file4lock( &data->file, L4LOCK_POS_OLD, L4LOCK_POS - L4LOCK_POS_OLD ) ;
else
rc = file4lock( &data->file, L4LOCK_POS_OLD + dfile4recordPosition( data, recNum-1L )+1L, L4LOCK_POS - L4LOCK_POS_OLD - dfile4recordPosition( data, recNum-1L )-1L) ;
}
else
{
if (recNum == 1) /* also lock header bytes */
rc = file4lock( &data->file, L4LOCK_POS_OLD, data->headerLen + numRecs*dfile4recWidth(data) ) ;
else
rc = file4lock( &data->file, L4LOCK_POS_OLD + dfile4recordPosition( data, recNum-1L )+1L, (numRecs+1L)*dfile4recWidth(data)-1L ) ;
}
}
}
#endif
return rc ;
}
#endif /* S4CLIENT */
#endif /* S4USE_ADDITIVE_LOCK */
#ifdef S4CLIENT
int dfile4lockFile( DATA4FILE *data, const long clientId, const long serverId, DATA4 *aux )
#else
int dfile4lockFile( DATA4FILE *data, const long clientId, const long serverId )
#endif
{
int rc = 0 ;
CODE4 *c4 ;
#ifdef S4CLIENT
DATA4 *d4 ;
CONNECTION4LOCK_INFO_IN info ;
CONNECTION4 *connection ;
memset( &info, 0, sizeof( CONNECTION4LOCK_INFO_IN ) ) ;
#else
#ifdef S4USE_ADDITIVE_LOCK
LOCK4 *lock ;
long prevLock;
#endif
#endif
#ifdef E4PARM_LOW
if ( data == 0 || clientId == 0
#ifdef S4SERVER
|| serverId == 0
#endif
)
return error4( 0, e4parm, E91102 ) ;
#endif
c4 = data->c4 ;
if ( error4code( c4 ) < 0 )
return e4codeBase ;
#ifdef S4CLIENT
if ( aux == 0 )
d4 = code4idData( c4, serverId, clientId ) ;
else
d4 = aux ;
if ( data->lockTest != 0 && code4unlockAuto( c4 ) != LOCK4ALL )
{
if ( c4->lockAttempts == WAIT4EVER )
return error4( c4, e4lock, E81523 ) ;
else
return r4locked ;
}
connection = data->connection ;
if ( connection == 0 )
return e4connection ;
info.type = LOCK4FILE ;
connection4assign( connection, CON4LOCK, clientId, data->serverId ) ;
connection4addData( connection, &info, sizeof( CONNECTION4LOCK_INFO_IN ), 0 ) ;
rc = connection4repeat( connection, -2, -1, -1, d4 ) ;
if ( rc < 0 )
connection4error( connection, c4, rc, E91102 ) ;
if ( rc == 0 )
data->fileLock = d4 ;
return rc ;
#else
#ifndef S4USE_ADDITIVE_LOCK
if ( dfile4lockTestFile( data, clientId, serverId ) )
return 0 ;
if ( dfile4lockTestFile( data, 0L, 0L ) )
{
dfile4registerLocked( data, -1L, 1 ) ;
#ifndef S4SERVER
if ( c4->lockAttempts == WAIT4EVER )
return error4( c4, e4lock, E81523 ) ;
#endif
return r4locked ;
}
/* now check if any other lock is conflicting */
if ( dfile4lockTestAppend( data, 0L, 0L ) )
{
dfile4registerLocked( data, 0L, 1 ) ;
#ifndef S4SERVER
if ( c4->lockAttempts == WAIT4EVER )
return error4( c4, e4lock, E81523 ) ;
#endif
return r4locked ;
}
if ( dfile4lockTest( data, 0L, 0L, 0L ) )
{
dfile4registerLocked( data, -2L, 1 ) ;
#ifndef S4SERVER
if ( c4->lockAttempts == WAIT4EVER )
return error4( c4, e4lock, E81523 ) ;
#endif
return r4locked ;
}
#ifdef N4OTHER
rc = file4lock( &data->file, L4LOCK_POS, L4LOCK_POS ) ;
#endif
#ifdef S4MDX
rc = file4lock( &data->file, L4LOCK_POS_OLD, L4LOCK_POS - L4LOCK_POS_OLD + 1 ) ;
#endif
#ifdef S4FOX
/* codebase locks the append byte as well... */
rc = file4lock( &data->file, L4LOCK_POS_OLD, L4LOCK_POS_OLD - 1L ) ;
#endif
if ( rc != 0 )
{
if ( rc == r4locked )
dfile4registerLocked( data, -1L, 0 ) ;
return rc ;
}
data->fileClientLock = clientId ;
data->fileServerLock = serverId ;
#ifndef S4OPTIMIZE_OFF
file4refresh( &data->file ) ; /* make sure all up to date */
#endif
return 0 ;
#else
if ( dfile4lockTestFile( data, clientId, serverId ) )
return 0 ;
if ( dfile4lockTestFile( data, 0L, 0L ) )
{
dfile4registerLocked( data, -1L, 1 ) ;
#ifndef S4SERVER
if ( c4->lockAttempts == WAIT4EVER )
return error4( c4, e4lock, E81523 ) ;
#endif
return r4locked ;
}
/* now check if any other lock is conflicting */
if ( dfile4lockTestAppend( data, clientId, serverId ) == 0 )
if ( dfile4lockTestAppend( data, 0L, 0L ) )
{
dfile4registerLocked( data, 0L, 1 ) ;
return r4locked ;
#ifndef S4SERVER
if ( c4->lockAttempts == WAIT4EVER )
return error4( c4, e4lock, E81523 ) ;
#endif
}
/* check for record locks by other DATA4's first */
for ( lock = 0 ;; )
{
lock = (LOCK4 *)l4next( &data->lockedRecords, lock ) ;
if ( lock == 0 )
break ;
if ( lock->id.serverId != serverId || lock->id.clientId != clientId )
{
dfile4registerLocked( data, -2L, 1 ) ;
#ifndef S4SERVER
if ( c4->lockAttempts == WAIT4EVER )
return error4( c4, e4lock, E81523 ) ;
#endif
return r4locked ;
}
}
prevLock = 0L ;
if ( dfile4lockTestAppend( data, clientId, serverId ) == 0 )
{
rc = dfile4lockRange( data, 0, 1 ) ; /* lock append byte */
if ( rc != 0 )
prevLock = -1L ;
}
if ( rc == 0 )
for ( lock = 0 ; rc == 0 ; )
{
lock = (LOCK4 *)l4next( &data->lockedRecords, lock ) ;
if ( lock == 0 )
{
rc = dfile4lockRange( data, prevLock + 1L, -1L ) ;
break;
}
else
{
rc = dfile4lockRange( data, prevLock + 1L, lock->id.recNum - prevLock - 1L ) ;
if ( rc == 0 )
prevLock = lock->id.recNum ;
}
}
if ( rc != 0 )
{
if ( rc == r4locked )
dfile4registerLocked( data, -2L, 0 ) ;
if ( prevLock != -1L )
if ( dfile4lockTestAppend( data, clientId, serverId ) == 0 ) /* undo append lock */
dfile4unlockRange( data, 0L, 1L ) ;
if ( prevLock <= 0L ) /* ie. no prev. successful record lock ranges */
return rc ;
for ( lock = 0 ;; ) /* unlock previous successful locks */
{
lock = (LOCK4 *)l4prev( &data->lockedRecords, lock ) ;
if ( lock == 0 )
{
dfile4unlockRange( data, 1L, prevLock - 1L ) ;
break;
}
if ( prevLock > lock->id.recNum )
{
dfile4unlockRange( data, lock->id.recNum + 1L, prevLock - lock->id.recNum - 1L ) ;
prevLock = lock->id.recNum ;
}
}
return rc ;
}
data->fileClientLock = clientId ;
data->fileServerLock = serverId ;
data->appendClientLock = 0 ; /* reset append lock marker */
data->appendServerLock = 0 ;
#ifndef S4OPTIMIZE_OFF
file4refresh( &data->file ) ; /* make sure all up to date */
#endif
return 0 ;
#endif /* S4USE_ADDITIVE_LOCK */
#endif /* S4CLIENT */
}
#ifdef S4CLIENT
int dfile4lockAll( DATA4FILE *data, const long clientId, const long serverId, DATA4 *aux )
{
CONNECTION4LOCK_INFO_IN info ;
CONNECTION4 *connection ;
int rc ;
CODE4 *c4 ;
memset( &info, 0, sizeof( CONNECTION4LOCK_INFO_IN ) ) ;
#ifdef E4PARM_LOW
if ( data == 0 )
return error4( 0, e4parm_null, E91102 ) ;
#endif
c4 = data->c4 ;
if ( error4code( c4 ) < 0 )
return e4codeBase ;
connection = data->connection ;
if ( connection == 0 )
return e4connection ;
info.type = LOCK4ALL ;
connection4assign( connection, CON4LOCK, clientId, data->serverId ) ;
connection4addData( connection, &info, sizeof( CONNECTION4LOCK_INFO_IN ), 0 ) ;
if ( aux == 0 )
rc = connection4repeat( connection, -2, -1, -1, code4idData( c4, serverId, clientId ) ) ;
else
rc = connection4repeat( connection, -2, -1, -1, aux ) ;
if ( rc < 0 )
connection4error( connection, c4, rc, E91102 ) ;
return rc ;
}
#else
/* not S4CLIENT */
S4EXPORT int S4FUNCTION dfile4lockIndex( DATA4FILE *data, const long serverId )
{
#ifndef S4INDEX_OFF
int rc, oldAttempts, count ;
#ifdef N4OTHER
TAG4FILE *tagOn ;
#else
INDEX4FILE *indexOn ;
#endif
CODE4 *c4 ;
#ifdef E4PARM_LOW
if ( data == 0 || serverId == 0 )
return error4( 0, e4parm, E91102 ) ;
#endif
c4 = data->c4 ;
if ( error4code( c4 ) < 0 )
return e4codeBase ;
#ifdef N4OTHER
if ( data->indexLocked == 1 )
return 0 ;
#endif
count = oldAttempts = c4->lockAttempts ; /* take care of wait here */
c4->lockAttempts = 1 ;
rc = 0 ;
for(;;)
{
#ifdef N4OTHER
for ( tagOn = 0 ;; )
{
tagOn = dfile4tagNext( data, tagOn ) ;
if ( tagOn == 0 )
break ;
rc = tfile4lock( tagOn, serverId ) ;
if ( rc != 0 )
break ;
}
#else
for ( indexOn = 0 ;; )
{
indexOn = (INDEX4FILE *)l4next( &data->indexes, indexOn ) ;
if ( indexOn == 0 )
break ;
rc = index4lock( indexOn, serverId ) ;
if ( rc != 0 )
break ;
}
#endif
if ( rc == 0 )
break ;
#ifdef N4OTHER
for ( tagOn = 0 ;; )
{
tagOn = dfile4tagNext( data, tagOn ) ;
if ( tagOn == 0 )
break ;
if ( tfile4unlock( tagOn, serverId ) < 0 )
rc = -1 ;
}
#else
for ( indexOn = 0 ;; )
{
indexOn = (INDEX4FILE *)l4next( &data->indexes, indexOn ) ;
if ( indexOn == 0 )
break ;
if ( index4unlock( indexOn, serverId ) < 0 )
rc = -1 ;
}
#endif
if ( rc != r4locked )
break ;
if ( count == 0 || rc == -1 )
break ;
if ( count > 0 )
count-- ;
#ifdef S4TEMP
if ( d4display_quit( &display ) )
return error4( c4, e4result, E80604 ) ;
#endif
u4delayHundredth( c4->lockDelay ) ; /* wait a second & try lock again */
}
#ifdef N4OTHER
data->indexLocked = 1 ;
#endif
c4->lockAttempts = oldAttempts ;
if ( error4code( c4 ) < 0 )
return -1 ;
return rc ;
#else
return 0 ;
#endif
}
/* not S4CLIENT */
int dfile4lockAll( DATA4FILE *data, const long clientId, const long serverId )
{
int rc, saveUnlockAuto ;
#ifdef E4PARM_LOW
if ( data == 0 )
return error4( 0, e4parm_null, E91102 ) ;
#endif
if ( error4code( data->c4 ) < 0 )
return e4codeBase ;
rc = dfile4lockFile( data, clientId, serverId ) ;
#ifndef N4OTHER
#ifndef S4MEMO_OFF
if ( !rc )
if ( data->nFieldsMemo > 0 )
return dfile4lockMemo( data ) ;
#endif
#endif
#ifndef S4INDEX_OFF
if ( !rc )
rc = dfile4lockIndex( data, serverId ) ;
#endif
if ( rc && code4unlockAuto( data->c4 ) == 1 )
{
saveUnlockAuto = code4unlockAuto( data->c4 ) ;
code4unlockAutoSet( data->c4, 1 ) ;
dfile4unlockData( data, clientId, serverId ) ;
#ifndef N4OTHER
#ifndef S4MEMO_OFF
dfile4memoUnlock( data ) ;
#endif
#endif
#ifndef S4INDEX_OFF
dfile4unlockIndex( data, serverId ) ;
#endif
code4unlockAutoSet( data->c4, saveUnlockAuto ) ;
}
return rc ;
}
#endif /* S4CLIENT */
/* for client, if clientId == 0, then any d4 with a lock will return success */
/* for server, if clientId == 0 and serverId == 0, then any d4 with a lock will return success */
/* for server, if clientId == 0 then any d4 with a serverId lock will return success */
int dfile4lockTest( DATA4FILE *data, const long clientId, const long serverId, const long rec )
{
int rc ;
#ifdef S4CLIENT
LOCK4LINK *lock ;
#else
LOCK4 *lock ;
#ifdef E4MISC
long recSave ;
#endif
#endif
#ifdef E4PARM_LOW
if ( data == 0 )
return error4( 0, e4parm_null, E91102 ) ;
#endif
rc = dfile4lockTestFile( data, clientId, serverId ) ;
if ( rc )
return rc ;
#ifdef S4CLIENT
if ( data->fileLock != 0 )
{
data->lockTest = data->fileLock ;
return 0 ;
}
for( lock = 0 ;; )
{
lock = (LOCK4LINK *)l4next( &data->lockedRecords, lock ) ;
if ( lock == 0 )
break ;
if ( lock->recNo == rec )
{
if ( clientId == 0 ) /* if clintId == 0 then any lock is considered success */
return 1 ;
if ( lock->data->clientId == clientId )
return 1 ;
else
{
data->lockTest = lock->data ;
return 0 ;
}
}
}
return 0 ;
#else
#ifdef E4MISC
/* verify the order of the list */
lock = (LOCK4 *)l4first( &data->lockedRecords ) ;
if ( lock != 0 )
for ( ;; )
{
recSave = lock->id.recNum ;
lock = (LOCK4 *)l4next( &data->lockedRecords, lock ) ;
if ( lock == 0 )
break ;
if ( lock->id.recNum <= recSave )
return error4( data->c4, e4info, E91102 ) ;
}
#endif
if ( clientId == 0 )
{
if ( data->fileServerLock != serverId )
return 1 ;
for ( lock = 0 ;; )
{
lock = (LOCK4 *)l4next( &data->lockedRecords, lock ) ;
if ( lock == 0 )
break ;
if ( lock->id.recNum == rec || rec == 0L )
if ( lock->id.serverId == serverId || serverId == 0 )
{
data->tempServerLock = lock->id.serverId ;
data->tempClientLock = lock->id.clientId ;
return 1 ;
}
if ( rec != 0 )
if ( lock->id.recNum > rec ) /* ordered list, so gone too far */
break ;
}
}
else
{
if ( data->fileServerLock == serverId && data->fileClientLock == clientId )
{
data->tempServerLock = data->fileServerLock ;
data->tempClientLock = data->fileClientLock ;
return 1 ;
}
for ( lock = 0 ;; )
{
lock = (LOCK4 *)l4next( &data->lockedRecords, lock ) ;
if ( lock == 0 )
break ;
if ( lock->id.recNum == rec || rec == 0L )
if ( serverId == 0 || ( lock->id.clientId == clientId && lock->id.serverId == serverId ) )
{
data->tempServerLock = lock->id.serverId ;
data->tempClientLock = lock->id.clientId ;
return 1 ;
}
if ( rec != 0 )
if ( lock->id.recNum > rec ) /* ordered list, so gone too far */
break ;
}
}
return 0 ;
#endif /* S4CLIENT */
}
#ifndef S4CLIENT
/* not S4CLIENT */
int dfile4lockTestIndex( DATA4FILE *data, const long serverId )
{
#ifndef S4INDEX_OFF
#ifdef N4OTHER
TAG4FILE *tagOn ;
#else
INDEX4FILE *indexOn ;
#endif
#ifdef E4PARM_LOW
if ( data == 0 )
return error4( 0, e4parm_null, E91102 ) ;
#endif
#ifdef S4LOCK_MATCH
if ( data->file.accessMode != OPEN4DENY_NONE )
return 1 ;
#endif
#ifdef S4SERVER
if ( data->exclusiveOpen != 0 )
return 1 ;
#endif
#ifdef N4OTHER
for( tagOn = 0 ; ; )
{
tagOn = (TAG4FILE *)l4next( &data->tagfiles, tagOn ) ;
if ( !tagOn )
break ;
if ( serverId == 0 && tagOn->fileLocked != 0 )
return 1 ;
if ( tagOn->fileLocked != serverId )
return 0 ;
}
#else
for( indexOn = 0 ; ; )
{
indexOn = (INDEX4FILE *)l4next( &data->indexes, indexOn ) ;
if ( !indexOn )
break ;
if ( serverId == 0 && indexOn->fileLocked != 0 )
return 1 ;
if ( indexOn->fileLocked != serverId )
return 0 ;
}
#endif
#endif
return 1 ;
}
#endif /* S4CLIENT */
#endif /* S4SINGLE */
#ifdef P4ARGS_USED
#pragma argsused
#endif
int S4FUNCTION dfile4lockTestAppend( DATA4FILE *data, const long clientId, const long serverId )
{
#ifdef S4SINGLE
return 1 ;
#else
#ifdef S4CLIENT
data->lockTest = 0 ;
if ( data->appendLock != 0 )
{
if ( data->appendLock->clientId == clientId )
return 1 ;
data->lockTest = data->appendLock ;
return 0 ;
}
if ( data->fileLock != 0 )
return ( data->fileLock->clientId == clientId ) ;
return 0 ;
#else
int rc ;
if ( data == 0 )
return error4( 0, e4parm_null, E91102 ) ;
rc = dfile4lockTestFile( data, clientId, serverId ) ;
if ( rc )
return rc ;
if ( serverId == 0 )
return ( data->appendServerLock != 0 ) ;
if ( clientId == 0 )
return ( data->appendServerLock == serverId ) ;
else
return ( data->appendServerLock == serverId && data->appendClientLock == clientId ) ;
#endif /* S4CLIENT */
#endif /* S4SINGLE */
}
#ifdef P4ARGS_USED
#pragma argsused
#endif
int S4FUNCTION dfile4lockTestFile( DATA4FILE *data, const long clientId, const long serverId )
{
#ifdef S4SINGLE
return 1 ;
#else
#ifdef S4CLIENT
data->lockTest = 0 ;
if ( data->accessMode != OPEN4DENY_NONE )
return 1 ;
if ( data->fileLock != 0 )
{
if ( data->fileLock->clientId == clientId )
return 1 ;
data->lockTest = data->fileLock ;
return 0 ;
}
return 0 ;
#else
if ( data == 0 )
return error4( 0, e4parm_null, E91102 ) ;
#ifdef S4LOCK_MATCH
if ( data->file.accessMode != OPEN4DENY_NONE )
return 1 ;
#endif
#ifdef S4SERVER
if ( data->exclusiveOpen != 0 )
return 1 ;
#else
if ( data->file.lowAccessMode != OPEN4DENY_NONE )
return 1 ;
#endif
if ( serverId == 0 )
{
if ( data->fileServerLock != 0 )
{
data->tempServerLock = data->fileServerLock ;
data->tempClientLock = data->fileClientLock ;
return 1 ;
}
return 0 ;
}
if ( clientId == 0 )
{
if ( data->fileServerLock != serverId )
{
data->tempServerLock = data->fileServerLock ;
data->tempClientLock = data->fileClientLock ;
return 0 ;
}
return 1 ;
}
else
return ( data->fileServerLock == serverId && data->fileClientLock == clientId ) ;
#endif /* S4CLIENT */
#endif /* S4SINGLE */
}