campo-sirio/cb/source/d4unlock.c
alex af15e0698b Codebase
git-svn-id: svn://10.65.10.50/trunk@4679 c028cbd2-c16b-5b4b-a496-9718f37d4682
1997-06-16 13:01:08 +00:00

478 lines
12 KiB
C
Executable File

/* d4unlock.c (c)Copyright Sequiter Software Inc., 1988-1996. All rights reserved. */
#include "d4all.h"
#ifndef S4UNIX
#ifdef __TURBOC__
#pragma hdrstop
#endif
#endif
#ifndef S4SINGLE
static int d4hasLocks( DATA4 *data, long clientId, long serverId )
{
#ifdef S4CLIENT
LOCK4LINK *lock ;
#ifdef L4LOCK_CHECK
at return time, make sure call server to see if the expected lock matches...
#endif
if ( serverId == 0 ) /* likely failed open */
return 0 ;
if ( data->dataFile->fileLock != data && data->dataFile->appendLock != data )
{
for ( lock = 0 ;; )
{
lock = (LOCK4LINK *)l4next( &data->dataFile->lockedRecords, lock ) ;
if ( lock == 0 )
return 0 ;
if ( lock->data == data )
return 1 ;
}
}
return 1 ;
#else
LOCK4 *lock ;
if ( serverId == 0 ) /* likely failed open */
return 0 ;
#ifdef S4SERVER
if ( data->accessMode == OPEN4DENY_RW )
return 0 ;
#endif
if ( ( data->dataFile->fileServerLock == serverId && ( data->dataFile->fileClientLock == clientId || clientId == 0 ) ) ||
( ( data->dataFile->appendClientLock == clientId || clientId == 0 ) && data->dataFile->appendServerLock == serverId ) )
return 1 ;
for ( lock = 0 ;; )
{
lock = (LOCK4 *)l4next( &data->dataFile->lockedRecords, lock ) ;
if ( lock == 0 )
return 0 ;
if ( ( lock->id.clientId == clientId || clientId == 0 ) && lock->id.serverId == serverId )
return 1 ;
}
#endif
}
#endif
#ifdef S4CLIENT
void d4unlockClientData( DATA4 *data )
{
DATA4FILE *dfile ;
LOCK4LINK *lock, *nextLock ;
#ifdef S4SERVER
if ( data->accessMode == OPEN4DENY_RW )
return ;
#endif
dfile = data->dataFile ;
if ( dfile->fileLock == data )
{
data->dataFile->numRecs = -1 ;
dfile->fileLock = 0 ;
}
if ( dfile->appendLock == data )
{
data->dataFile->numRecs = -1 ;
dfile->appendLock = 0 ;
}
lock = (LOCK4LINK *)l4first( &dfile->lockedRecords ) ;
if ( lock != 0 )
for ( ;; )
{
nextLock = (LOCK4LINK *)l4next( &dfile->lockedRecords, lock ) ;
if ( lock->data == data )
{
l4remove( &dfile->lockedRecords, lock ) ;
mem4free( data->codeBase->lockLinkMemory, lock ) ;
}
if ( nextLock == 0 )
break ;
lock = nextLock ;
}
return ;
}
#endif
#ifndef S4SINGLE
/* clientId if set to 0 will unlock all client instance of the data file,
if set to a value will only unlock the given client instance */
static int d4unlockDo( DATA4 *data, const long clientId )
{
CODE4 *c4 ;
#ifdef S4CLIENT
int rc ;
CONNECTION4 *connection ;
#else
int rc, saveUnlockAuto ;
#endif
c4 = data->codeBase ;
#ifndef S4OFF_TRAN
#ifndef S4OFF_WRITE
if ( code4transEnabled( c4 ) )
if ( code4tranStatus( c4 ) == r4active )
return error4( c4, e4transViolation, E92801 ) ;
#endif
#endif
if ( d4hasLocks( data, clientId, data4serverId( data ) ) == 0 ) /* first make sure there are locks to undo */
return 0 ;
#ifdef S4CLIENT
rc = d4update( data ) ; /* returns -1 if error4code( codeBase ) < 0 */
if ( rc < 0 )
return error4stack( c4, (short int)rc, E92801 ) ;
/* in case of rollback and exclusive files, make sure count set to -1 */
data->dataFile->numRecs = -1 ;
connection = data->dataFile->connection ;
if ( connection == 0 )
return error4stack( c4, e4connection, E92801 ) ;
connection4assign( connection, CON4UNLOCK, clientId, data4serverId( data ) ) ;
connection4send( connection ) ;
rc = connection4receive( connection ) ;
if ( rc < 0 )
return error4stack( c4, rc, E92801 ) ;
rc = connection4status( connection ) ;
if ( rc < 0 )
return connection4error( connection, c4, rc, E92801 ) ;
if ( code4trans( c4 )->unlockAuto == 2 ) /* cb51 compat, remove lock */
d4unlockClientData( data ) ;
return rc ;
#else
#ifndef S4OFF_WRITE
#ifndef S4OFF_TRAN
if ( code4transEnabled( c4 ) )
if ( code4tranStatus( c4 ) != r4inactive )
return 0 ;
#endif
rc = d4update( data ) ; /* returns -1 if error4code( codeBase ) < 0 */
if ( rc < 0 )
return error4stack( c4, (short int)rc, E92801 ) ;
#else
rc = 0 ;
#endif
saveUnlockAuto = code4unlockAuto( c4 ) ;
if ( saveUnlockAuto == 0 ) /* leave if 1 or 2 -- don't change 2 */
code4unlockAutoSet( c4, 1 ) ;
#ifdef S4SERVER
dfile4unlockData( data->dataFile, clientId, data4serverId( data ) ) ;
if ( code4unlockAuto( c4 ) == LOCK4DATA )
if ( c4->currentClient->connection != 0 )
if ( c4->currentClient->connection->message != 0 )
packet4setDidUnlockData( c4->currentClient->connection->message->packet, 1 ) ;
#else
d4unlockData( data ) ;
#endif
#ifndef N4OTHER
#ifndef S4OFF_MEMO
dfile4memoUnlock( data->dataFile ) ;
#endif
#endif
#ifndef S4OFF_INDEX
dfile4unlockIndex( data->dataFile, data4serverId( data ) ) ;
#endif
code4unlockAutoSet( c4, saveUnlockAuto ) ;
if ( error4code( c4 ) < 0 )
return -1 ;
return rc ;
#endif
}
#endif /* S4SINGLE */
#ifdef P4ARGS_USED
#pragma argsused
#endif
int S4FUNCTION d4unlock( DATA4 *data )
{
#ifndef S4SINGLE
#ifdef S4CLIENT
int oldLock ;
#endif
int rc ;
#ifdef E4PARM_HIGH
if ( data == 0 )
return error4( 0, e4parm_null, E92801 ) ;
#endif
#ifdef S4CLIENT
oldLock = code4unlockAuto( data->codeBase ) ;
code4unlockAutoSet( data->codeBase, LOCK4DATA ) ;
#endif
rc = d4unlockDo( data, data4clientId( data ) ) ;
#ifdef S4CLIENT
code4unlockAutoSet( data->codeBase, oldLock ) ;
#endif
return rc ;
#else
return 0 ;
#endif
}
/*#ifdef S4STAND_ALONE*/
#ifndef S4CLIENT
/* only unlocks the append byte */
#ifdef P4ARGS_USED
#pragma argsused
#endif
int d4unlockAppend( DATA4 *data )
{
#ifndef S4SINGLE
#ifdef E4PARM_HIGH
if ( data == 0 )
return error4( 0, e4parm_null, E92802 ) ;
#endif
if ( code4unlockAuto( data->codeBase ) == LOCK4OFF )
return 0 ;
#ifdef S4SERVER
if ( data->accessMode == OPEN4DENY_RW )
return 0 ;
#endif
return dfile4unlockAppend( data->dataFile, data4clientId( data ), data4serverId( data ) ) ;
#else
return 0 ;
#endif
}
#ifdef P4ARGS_USED
#pragma argsused
#endif
int d4unlockData( DATA4 *data )
{
#ifndef S4SINGLE
#ifdef E4PARM_HIGH
if ( data == 0 )
return error4( 0, e4parm_null, E92803 ) ;
#endif
if ( code4unlockAuto( data->codeBase ) == LOCK4OFF )
return 0 ;
#ifdef S4SERVER
if ( data->accessMode == OPEN4DENY_RW )
return 0 ;
#endif
d4unlockFile( data ) ;
d4unlockAppend( data ) ;
d4unlockRecords( data ) ;
if ( error4code( data->codeBase ) < 0 )
return error4code( data->codeBase ) ;
#endif
return 0 ;
}
#ifdef P4ARGS_USED
#pragma argsused
#endif
int d4unlockFile( DATA4 *data )
{
#ifndef S4SINGLE
int rc ;
#ifdef S4VBASIC
if ( c4parm_check( data, 2, E92804 ) )
return -1 ;
#endif
#ifdef E4PARM_HIGH
if ( data == 0 )
return error4( 0, e4parm_null, E92804 ) ;
#endif
if ( code4unlockAuto( data->codeBase ) == LOCK4OFF )
return 0 ;
#ifdef S4SERVER
if ( data->accessMode == OPEN4DENY_RW )
return 0 ;
#endif
rc = dfile4unlockFile( data->dataFile, data4clientId( data ), data4serverId( data ) ) ;
if ( rc < 0 )
return error4stack( data->codeBase, rc, E92804 ) ;
data->recNumOld = -1 ;
#ifndef S4OFF_MEMO
data->memoValidated = 0 ;
#endif
#endif
return 0 ;
}
#ifdef P4ARGS_USED
#pragma argsused
#endif
int S4FUNCTION d4unlockRecord( DATA4 *data, long rec )
{
#ifndef S4SINGLE
#ifdef E4PARM_HIGH
if ( data == 0 )
return error4( 0, e4parm_null, E92805 ) ;
#endif
if ( code4unlockAuto( data->codeBase ) == LOCK4OFF )
return 0 ;
#ifdef S4SERVER
if ( data->accessMode == OPEN4DENY_RW )
return 0 ;
#endif
if ( rec == data->recNum )
{
data->recNumOld = -1 ;
#ifndef S4OFF_MEMO
data->memoValidated = 0 ;
#endif
}
return dfile4unlockRecord( data->dataFile, data4clientId( data ), data4serverId( data ), rec ) ;
#else
return 0 ;
#endif
}
#ifdef P4ARGS_USED
#pragma argsused
#endif
int d4unlockRecords( DATA4 *data )
{
#ifndef S4SINGLE
#ifdef E4PARM_HIGH
if ( data == 0 )
return error4( 0, e4parm_null, E92806 ) ;
#endif
if ( code4unlockAuto( data->codeBase ) == LOCK4OFF )
return 0 ;
#ifdef S4SERVER
if ( data->accessMode == OPEN4DENY_RW )
return 0 ;
#endif
data->recNumOld = -1 ;
#ifndef S4OFF_MEMO
data->memoValidated = 0 ;
#endif
return dfile4unlockRecords( data->dataFile, data4clientId( data ), data4serverId( data ) ) ;
#else
return 0 ;
#endif
}
#endif /* S4CLIENT */
/*#endif */ /* S4STAND_ALONE */
#ifndef S4SINGLE
int code4unlockDo( LIST4 *dataList )
{
DATA4 *dataOn ;
CODE4 *c4 ;
#ifdef S4CLIENT
int oldLock ;
#endif
c4 = 0 ;
#ifdef E4PARM_HIGH
if ( dataList == 0 )
return error4( 0, e4parm_null, E92807 ) ;
#endif
#ifdef S4CLIENT
/* for client, any request with LOCK4ALL should cause complete
unlocking of everything at the lower level.
Therefore, only need to call on a single database--but that
database better have a lock. if none have locks, call is
avioded. */
for( dataOn = 0 ;; )
{
dataOn = (DATA4 *)l4next( dataList, dataOn ) ;
if ( dataOn == 0 )
break ;
if ( d4hasLocks( dataOn, data4clientId( dataOn ), data4serverId( dataOn ) ) != 0 )
{
c4 = dataOn->codeBase ;
oldLock = code4unlockAuto( c4 ) ;
code4unlockAutoSet( c4, LOCK4ALL ) ;
d4unlockDo( dataOn, 0 ) ;
code4unlockAutoSet( c4, oldLock ) ;
break ;
}
}
#else
for ( dataOn = 0 ;; )
{
dataOn = (DATA4 *)l4next( dataList, dataOn ) ;
if ( dataOn == 0 )
break ;
/* reset record count because this function is likely called due to a transaction rollback */
d4unlockDo( dataOn, 0 ) ;
c4 = dataOn->codeBase ;
}
#endif
if ( c4 != 0 )
{
#ifdef S4SERVER
if ( c4->currentClient->connection != 0 )
packet4setDidUnlock( c4->currentClient->connection->message->packet, 1 ) ;
#endif
if ( error4code( c4 ) < 0 )
return error4code( c4 ) ;
}
return 0 ;
}
#endif /* S4SINGLE */
#ifdef P4ARGS_USED
#pragma argsused
#endif
int S4FUNCTION code4unlock( CODE4 *c4 )
{
#ifdef S4SINGLE
return 0 ;
#else
#ifndef S4OFF_WRITE
#ifndef S4OFF_TRAN
if ( code4transEnabled( c4 ) )
if ( code4tranStatus( c4 ) == r4active )
return error4( c4, e4transViolation, E92807 ) ;
#endif
#endif
#ifdef S4SERVER
return server4clientUnlock( c4->currentClient ) ;
#else
return code4unlockDo( tran4dataList( (&(c4->c4trans.trans)) ) ) ;
#endif
#endif
}