2011-06-09 15:31 UTC+0200 Przemyslaw Czerpak (druzus/at/priv.onet.pl)
* harbour/include/hbapifs.h
* harbour/src/rtl/filesys.c
% removed unnecessary PID setting in POSIX file lock function.
+ added new C function:
int hb_fsLockTest( HB_FHANDLE hFileHandle, HB_FOFFSET nStart,
HB_FOFFSET nLength, HB_USHORT uiMode );
It allows to test file range lock status.
It returns -1 on error, 0 when lock can be set and value greater
then 0 if part of given range is locked by other process. In POSIX
systems this value is PID of current lock owner. In other systems
it's always 1.
In uiMode only FLX_SHARED bit is significant.
* harbour/include/hbapifs.h
* harbour/src/rtl/filebuf.c
+ added new C function:
int hb_fileLockTest( PHB_FILE pFile, HB_FOFFSET nStart,
HB_FOFFSET nLen, int iType );
It's redirected to hb_fsLockTest()
* harbour/contrib/hbnetio/netio.h
* harbour/contrib/hbnetio/netiocli.c
* harbour/contrib/hbnetio/netiosrv.c
* harbour/contrib/hbmemio/memio.c
+ implemented hb_fileLockTest() low level code
* harbour/include/dbinfo.ch
+ added DBI_LOCKTEST
* harbour/src/rdd/dbf1.c
% small code simplification
+ implemented DBI_LOCKTEST
dbInfo( DBI_LOCKTEST [, <nRecNo> ] ) -> <nStatus>
returns corresponding results to C level hb_fsLockTest() function.
If current workarea is already locked then 0 is returned.
If low level FS is located on POSIX system (accessed directly or by
HBNETIO) then value greater then 0 is PID of current lock owner.
If the lock is hold by aliased area or other thread of calling
process then <nStatus> is current PID. In Other systems 1 is returned
when lock cannot be set in current workarea.
If <nRecNo> is given then the test is for RLOCK() otherwise FLOCK()
operation.
This commit is contained in:
@@ -16,6 +16,50 @@
|
||||
The license applies to all entries newer than 2009-04-28.
|
||||
*/
|
||||
|
||||
2011-06-09 15:31 UTC+0200 Przemyslaw Czerpak (druzus/at/priv.onet.pl)
|
||||
* harbour/include/hbapifs.h
|
||||
* harbour/src/rtl/filesys.c
|
||||
% removed unnecessary PID setting in POSIX file lock function.
|
||||
+ added new C function:
|
||||
int hb_fsLockTest( HB_FHANDLE hFileHandle, HB_FOFFSET nStart,
|
||||
HB_FOFFSET nLength, HB_USHORT uiMode );
|
||||
It allows to test file range lock status.
|
||||
It returns -1 on error, 0 when lock can be set and value greater
|
||||
then 0 if part of given range is locked by other process. In POSIX
|
||||
systems this value is PID of current lock owner. In other systems
|
||||
it's always 1.
|
||||
In uiMode only FLX_SHARED bit is significant.
|
||||
|
||||
* harbour/include/hbapifs.h
|
||||
* harbour/src/rtl/filebuf.c
|
||||
+ added new C function:
|
||||
int hb_fileLockTest( PHB_FILE pFile, HB_FOFFSET nStart,
|
||||
HB_FOFFSET nLen, int iType );
|
||||
It's redirected to hb_fsLockTest()
|
||||
|
||||
* harbour/contrib/hbnetio/netio.h
|
||||
* harbour/contrib/hbnetio/netiocli.c
|
||||
* harbour/contrib/hbnetio/netiosrv.c
|
||||
* harbour/contrib/hbmemio/memio.c
|
||||
+ implemented hb_fileLockTest() low level code
|
||||
|
||||
* harbour/include/dbinfo.ch
|
||||
+ added DBI_LOCKTEST
|
||||
|
||||
* harbour/src/rdd/dbf1.c
|
||||
% small code simplification
|
||||
+ implemented DBI_LOCKTEST
|
||||
dbInfo( DBI_LOCKTEST [, <nRecNo> ] ) -> <nStatus>
|
||||
returns corresponding results to C level hb_fsLockTest() function.
|
||||
If current workarea is already locked then 0 is returned.
|
||||
If low level FS is located on POSIX system (accessed directly or by
|
||||
HBNETIO) then value greater then 0 is PID of current lock owner.
|
||||
If the lock is hold by aliased area or other thread of calling
|
||||
process then <nStatus> is current PID. In Other systems 1 is returned
|
||||
when lock cannot be set in current workarea.
|
||||
If <nRecNo> is given then the test is for RLOCK() otherwise FLOCK()
|
||||
operation.
|
||||
|
||||
2011-06-07 18:15 UTC-0800 Pritpal Bedi (bedipritpal@hotmail.com)
|
||||
* contrib/hbide/ideactions.prg
|
||||
* contrib/hbide/idemain.prg
|
||||
|
||||
@@ -670,6 +670,15 @@ HB_MEMFS_EXPORT HB_BOOL hb_memfsLock( HB_FHANDLE hFile, HB_FOFFSET ulStart, HB_F
|
||||
return HB_TRUE;
|
||||
}
|
||||
|
||||
HB_MEMFS_EXPORT int hb_memfsLockTest( HB_FHANDLE hFile, HB_FOFFSET ulStart, HB_FOFFSET nLength, int iMode )
|
||||
{
|
||||
HB_SYMBOL_UNUSED( hFile );
|
||||
HB_SYMBOL_UNUSED( ulStart );
|
||||
HB_SYMBOL_UNUSED( nLength );
|
||||
HB_SYMBOL_UNUSED( iMode );
|
||||
return 0;
|
||||
}
|
||||
|
||||
/******************************************************
|
||||
*
|
||||
* I/O Driver for Memory file system
|
||||
@@ -790,6 +799,13 @@ static HB_BOOL s_fileLock( PHB_FILE pFile, HB_FOFFSET ulStart,
|
||||
}
|
||||
|
||||
|
||||
static int s_fileLockTest( PHB_FILE pFile, HB_FOFFSET ulStart,
|
||||
HB_FOFFSET nLen, int iType )
|
||||
{
|
||||
return hb_memfsLockTest( pFile->hFile, ulStart, nLen, iType );
|
||||
}
|
||||
|
||||
|
||||
static HB_SIZE s_fileReadAt( PHB_FILE pFile, void * buffer,
|
||||
HB_SIZE nSize, HB_FOFFSET llOffset )
|
||||
{
|
||||
@@ -843,6 +859,7 @@ static const HB_FILE_FUNCS s_fileFuncs =
|
||||
s_fileOpen,
|
||||
s_fileClose,
|
||||
s_fileLock,
|
||||
s_fileLockTest,
|
||||
s_fileReadAt,
|
||||
s_fileWriteAt,
|
||||
s_fileTruncAt,
|
||||
|
||||
@@ -107,6 +107,7 @@
|
||||
#define NETIO_SRVITEM 21
|
||||
#define NETIO_SRVDATA 22
|
||||
#define NETIO_SRVCLOSE 23
|
||||
#define NETIO_TESTLOCK 24
|
||||
#define NETIO_CONNECTED 0x4321DEAD
|
||||
|
||||
/* messages format */
|
||||
@@ -118,6 +119,7 @@
|
||||
/* { NETIO_READ, file_no[2], size[ 4 ], offset[ 8 ], ... } -> { NETIO_READ, read[ 4 ], err[ 4 ], ... } + data[ read ] */
|
||||
/* { NETIO_WRITE, file_no[2], size[ 4 ], offset[ 8 ], ... } + data[ size ] -> { NETIO_WRITE, written[ 4 ], err[ 4 ], ... } */
|
||||
/* { NETIO_LOCK, file_no[2], start[ 8 ], len[ 8 ], flags[ 2 ], ... } -> { NETIO_LOCK, ... } */
|
||||
/* { NETIO_TESTLOCK, file_no[2], start[ 8 ], len[ 8 ], flags[ 2 ], ... } -> { NETIO_TESTLOCK, result[ 4 ], ... } */
|
||||
/* { NETIO_TRUNC, file_no[2], offset[ 8 ], ... } -> { NETIO_TRUNC, ... } */
|
||||
/* { NETIO_SIZE, file_no[2], ... } -> { NETIO_SIZE, size[ 8 ], err[ 4 ], ... } */
|
||||
/* { NETIO_COMMIT, file_no[2], ... } -> { NETIO_SYNC, ... } | NULL */
|
||||
|
||||
@@ -1611,6 +1611,33 @@ static HB_BOOL s_fileLock( PHB_FILE pFile, HB_FOFFSET ulStart, HB_FOFFSET ulLen,
|
||||
return fResult;
|
||||
}
|
||||
|
||||
static int s_fileLockTest( PHB_FILE pFile, HB_FOFFSET ulStart, HB_FOFFSET ulLen,
|
||||
int iType )
|
||||
{
|
||||
int iResult = -1;
|
||||
|
||||
if( s_fileConLock( pFile->conn ) )
|
||||
{
|
||||
HB_BYTE msgbuf[ NETIO_MSGLEN ];
|
||||
|
||||
HB_PUT_LE_UINT32( &msgbuf[ 0 ], NETIO_TESTLOCK );
|
||||
HB_PUT_LE_UINT16( &msgbuf[ 4 ], pFile->fd );
|
||||
HB_PUT_LE_UINT64( &msgbuf[ 6 ], ulStart );
|
||||
HB_PUT_LE_UINT64( &msgbuf[ 14 ], ulLen );
|
||||
HB_PUT_LE_UINT16( &msgbuf[ 22 ], ( HB_USHORT ) iType );
|
||||
#if NETIO_MSGLEN > 24
|
||||
memset( msgbuf + 24, '\0', sizeof( msgbuf ) - 24 );
|
||||
#endif
|
||||
|
||||
if( s_fileSendMsg( pFile->conn, msgbuf, NULL, 0, HB_TRUE, HB_FALSE ) )
|
||||
iResult = HB_GET_LE_INT32( &msgbuf[ 4 ] );
|
||||
|
||||
s_fileConUnlock( pFile->conn );
|
||||
}
|
||||
|
||||
return iResult;
|
||||
}
|
||||
|
||||
static HB_SIZE s_fileReadAt( PHB_FILE pFile, void * data, HB_SIZE ulSize,
|
||||
HB_FOFFSET llOffset )
|
||||
{
|
||||
@@ -1759,6 +1786,7 @@ static const HB_FILE_FUNCS * s_fileMethods( void )
|
||||
s_fileOpen,
|
||||
s_fileClose,
|
||||
s_fileLock,
|
||||
s_fileLockTest,
|
||||
s_fileReadAt,
|
||||
s_fileWriteAt,
|
||||
s_fileTruncAt,
|
||||
|
||||
@@ -751,7 +751,7 @@ HB_FUNC( NETIO_SERVER )
|
||||
HB_BOOL fNoAnswer = HB_FALSE;
|
||||
HB_ERRCODE errCode = 0, errFsCode;
|
||||
long len = 0, size, size2;
|
||||
int iFileNo, iStreamID;
|
||||
int iFileNo, iStreamID, iResult;
|
||||
HB_U32 uiMsg;
|
||||
HB_USHORT uiFalgs;
|
||||
char * szExt;
|
||||
@@ -973,6 +973,7 @@ HB_FUNC( NETIO_SERVER )
|
||||
case NETIO_UNLOCK:
|
||||
fNoAnswer = HB_TRUE;
|
||||
case NETIO_LOCK:
|
||||
case NETIO_TESTLOCK:
|
||||
iFileNo = HB_GET_LE_UINT16( &msgbuf[ 4 ] );
|
||||
llOffset = HB_GET_LE_INT64( &msgbuf[ 6 ] );
|
||||
llSize = HB_GET_LE_INT64( &msgbuf[ 14 ] );
|
||||
@@ -980,6 +981,15 @@ HB_FUNC( NETIO_SERVER )
|
||||
pFile = s_srvFileGet( conn, iFileNo );
|
||||
if( pFile == NULL )
|
||||
errCode = NETIO_ERR_WRONG_FILE_HANDLE;
|
||||
else if( uiMsg == NETIO_TESTLOCK )
|
||||
{
|
||||
iResult = hb_fileLockTest( pFile, llOffset, llSize, uiFalgs );
|
||||
errFsCode = hb_fsError();
|
||||
HB_PUT_LE_UINT32( &msg[ 0 ], uiMsg );
|
||||
HB_PUT_LE_UINT32( &msg[ 4 ], iResult );
|
||||
HB_PUT_LE_UINT32( &msg[ 8 ], errFsCode );
|
||||
memset( msg + 12, '\0', NETIO_MSGLEN - 4 );
|
||||
}
|
||||
else if( !hb_fileLock( pFile, llOffset, llSize, uiFalgs ) )
|
||||
errCode = s_srvFsError();
|
||||
else if( !fNoAnswer )
|
||||
|
||||
@@ -291,6 +291,7 @@
|
||||
#define DBI_DIRTYREAD 143 /* Get/Set index dirty read flag */
|
||||
#define DBI_POSITIONED 144 /* Is cursor positioned to valid record */
|
||||
#define DBI_ISTEMPORARY 145 /* Is the table a temporary one? */
|
||||
#define DBI_LOCKTEST 146 /* record / file lock test */
|
||||
|
||||
/* RECORD MAP (RM) support */
|
||||
#define DBI_RM_SUPPORTED 150 /* has WA RDD record map support? */
|
||||
|
||||
@@ -152,6 +152,8 @@ extern HB_EXPORT HB_BOOL hb_fsIsDevice ( HB_FHANDLE hFileHandle ); /* dete
|
||||
extern HB_EXPORT HB_BOOL hb_fsLock ( HB_FHANDLE hFileHandle, HB_ULONG ulStart, HB_ULONG ulLength, HB_USHORT uiMode ); /* request a lock on a portion of a file */
|
||||
extern HB_EXPORT HB_BOOL hb_fsLockLarge ( HB_FHANDLE hFileHandle, HB_FOFFSET nStart,
|
||||
HB_FOFFSET nLength, HB_USHORT uiMode ); /* request a lock on a portion of a file using 64bit API */
|
||||
extern HB_EXPORT int hb_fsLockTest ( HB_FHANDLE hFileHandle, HB_FOFFSET nStart,
|
||||
HB_FOFFSET nLength, HB_USHORT uiMode );
|
||||
extern HB_EXPORT HB_BOOL hb_fsMkDir ( const char * pszDirName ); /* create a directory */
|
||||
extern HB_EXPORT HB_FHANDLE hb_fsOpen ( const char * pszFileName, HB_USHORT uiFlags ); /* open a file */
|
||||
extern HB_EXPORT HB_USHORT hb_fsRead ( HB_FHANDLE hFileHandle, void * pBuff, HB_USHORT uiCount ); /* read contents of a file into a buffer (<=64K) */
|
||||
@@ -310,6 +312,7 @@ extern HB_EXPORT const char * hb_fsNameConv( const char * szFileName, char ** ps
|
||||
PHB_ITEM pError );
|
||||
void (* Close ) ( PHB_FILE pFile );
|
||||
HB_BOOL (* Lock ) ( PHB_FILE, HB_FOFFSET nStart, HB_FOFFSET nLen, int iType );
|
||||
int (* LockTest ) ( PHB_FILE, HB_FOFFSET nStart, HB_FOFFSET nLen, int iType );
|
||||
HB_SIZE (* ReadAt ) ( PHB_FILE pFile, void * buffer, HB_SIZE nSize, HB_FOFFSET nOffset );
|
||||
HB_SIZE (* WriteAt ) ( PHB_FILE pFile, const void * buffer, HB_SIZE nSize, HB_FOFFSET nOffset );
|
||||
HB_BOOL (* TruncAt ) ( PHB_FILE pFile, HB_FOFFSET nOffset );
|
||||
@@ -340,6 +343,7 @@ extern HB_EXPORT PHB_FILE hb_fileCreateTempEx( char * pszName,
|
||||
HB_FATTR ulAttr );
|
||||
extern HB_EXPORT void hb_fileClose( PHB_FILE pFile );
|
||||
extern HB_EXPORT HB_BOOL hb_fileLock( PHB_FILE pFile, HB_FOFFSET nStart, HB_FOFFSET nLen, int iType );
|
||||
extern HB_EXPORT int hb_fileLockTest( PHB_FILE pFile, HB_FOFFSET nStart, HB_FOFFSET nLen, int iType );
|
||||
extern HB_EXPORT HB_SIZE hb_fileReadAt( PHB_FILE pFile, void * buffer, HB_SIZE nSize, HB_FOFFSET nOffset );
|
||||
extern HB_EXPORT HB_SIZE hb_fileWriteAt( PHB_FILE pFile, const void * buffer, HB_SIZE nSize, HB_FOFFSET nOffset );
|
||||
extern HB_EXPORT HB_BOOL hb_fileTruncAt( PHB_FILE pFile, HB_FOFFSET nOffset );
|
||||
|
||||
@@ -1315,6 +1315,49 @@ static HB_ERRCODE hb_dbfLockData( DBFAREAP pArea,
|
||||
return HB_SUCCESS;
|
||||
}
|
||||
|
||||
static int hb_dbfLockTest( DBFAREAP pArea, HB_USHORT uiAction, HB_ULONG ulRecNo )
|
||||
{
|
||||
int iResult = -1;
|
||||
|
||||
HB_TRACE(HB_TR_DEBUG, ("hb_dbfLockTest(%p, %hu, %lu)", pArea, uiAction, ulRecNo));
|
||||
|
||||
if( !pArea->fShared || pArea->fFLocked ||
|
||||
( uiAction == REC_LOCK && hb_dbfIsLocked( pArea, ulRecNo ) ) )
|
||||
iResult = 0;
|
||||
else
|
||||
{
|
||||
HB_FOFFSET nPos, nFlSize, nRlSize;
|
||||
int iDir;
|
||||
|
||||
if( hb_dbfLockData( pArea, &nPos, &nFlSize, &nRlSize, &iDir ) == HB_SUCCESS )
|
||||
{
|
||||
switch( uiAction )
|
||||
{
|
||||
case FILE_LOCK:
|
||||
if( iDir < 0 )
|
||||
nPos -= nFlSize;
|
||||
else
|
||||
nPos++;
|
||||
iResult = hb_fileLockTest( pArea->pDataFile, nPos, nFlSize, FL_LOCK );
|
||||
break;
|
||||
|
||||
case REC_LOCK:
|
||||
if( iDir < 0 )
|
||||
nPos -= ulRecNo;
|
||||
else if( iDir == 2 )
|
||||
nPos += ( ulRecNo - 1 ) * pArea->uiRecordLen + pArea->uiHeaderLen;
|
||||
else
|
||||
nPos += ulRecNo;
|
||||
|
||||
iResult = hb_fileLockTest( pArea->pDataFile, nPos, nRlSize, FL_LOCK );
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return iResult;
|
||||
}
|
||||
|
||||
/*
|
||||
* -- DBF METHODS --
|
||||
*/
|
||||
@@ -3408,6 +3451,13 @@ static HB_ERRCODE hb_dbfInfo( DBFAREAP pArea, HB_USHORT uiIndex, PHB_ITEM pItem
|
||||
break;
|
||||
}
|
||||
|
||||
case DBI_LOCKTEST:
|
||||
if( HB_IS_NUMERIC( pItem ) )
|
||||
hb_itemPutNI( pItem, hb_dbfLockTest( pArea, REC_LOCK, hb_itemGetNL( pItem ) ) );
|
||||
else
|
||||
hb_itemPutNI( pItem, hb_dbfLockTest( pArea, FILE_LOCK, 0 ) );
|
||||
break;
|
||||
|
||||
case DBI_LOCKSCHEME:
|
||||
{
|
||||
int iScheme = hb_itemGetNI( pItem );
|
||||
@@ -4814,10 +4864,11 @@ static HB_ERRCODE hb_dbfRawLock( DBFAREAP pArea, HB_USHORT uiAction, HB_ULONG ul
|
||||
if( !pArea->fFLocked )
|
||||
{
|
||||
if( iDir < 0 )
|
||||
fLck = hb_fileLock( pArea->pDataFile, nPos - nFlSize, nFlSize, FL_LOCK );
|
||||
nPos -= nFlSize;
|
||||
else
|
||||
fLck = hb_fileLock( pArea->pDataFile, nPos + 1, nFlSize, FL_LOCK );
|
||||
nPos++;
|
||||
|
||||
fLck = hb_fileLock( pArea->pDataFile, nPos, nFlSize, FL_LOCK );
|
||||
if( !fLck )
|
||||
errCode = HB_FAILURE;
|
||||
else
|
||||
@@ -4829,10 +4880,11 @@ static HB_ERRCODE hb_dbfRawLock( DBFAREAP pArea, HB_USHORT uiAction, HB_ULONG ul
|
||||
if( pArea->fFLocked )
|
||||
{
|
||||
if( iDir < 0 )
|
||||
fLck = hb_fileLock( pArea->pDataFile, nPos - nFlSize, nFlSize, FL_UNLOCK );
|
||||
nPos -= nFlSize;
|
||||
else
|
||||
fLck = hb_fileLock( pArea->pDataFile, nPos + 1, nFlSize, FL_UNLOCK );
|
||||
nPos++;
|
||||
|
||||
fLck = hb_fileLock( pArea->pDataFile, nPos, nFlSize, FL_UNLOCK );
|
||||
if( !fLck )
|
||||
errCode = HB_FAILURE;
|
||||
pArea->fFLocked = HB_FALSE;
|
||||
@@ -4843,12 +4895,13 @@ static HB_ERRCODE hb_dbfRawLock( DBFAREAP pArea, HB_USHORT uiAction, HB_ULONG ul
|
||||
if( !pArea->fFLocked )
|
||||
{
|
||||
if( iDir < 0 )
|
||||
fLck = hb_fileLock( pArea->pDataFile, nPos - ulRecNo, nRlSize, FL_LOCK );
|
||||
nPos -= ulRecNo;
|
||||
else if( iDir == 2 )
|
||||
fLck = hb_fileLock( pArea->pDataFile, nPos + ( ulRecNo - 1 ) * pArea->uiRecordLen + pArea->uiHeaderLen, nRlSize, FL_LOCK );
|
||||
nPos += ( ulRecNo - 1 ) * pArea->uiRecordLen + pArea->uiHeaderLen;
|
||||
else
|
||||
fLck = hb_fileLock( pArea->pDataFile, nPos + ulRecNo, nRlSize, FL_LOCK );
|
||||
nPos += ulRecNo;
|
||||
|
||||
fLck = hb_fileLock( pArea->pDataFile, nPos, nRlSize, FL_LOCK );
|
||||
if( !fLck )
|
||||
errCode = HB_FAILURE;
|
||||
}
|
||||
@@ -4858,11 +4911,13 @@ static HB_ERRCODE hb_dbfRawLock( DBFAREAP pArea, HB_USHORT uiAction, HB_ULONG ul
|
||||
if( !pArea->fFLocked )
|
||||
{
|
||||
if( iDir < 0 )
|
||||
fLck = hb_fileLock( pArea->pDataFile, nPos - ulRecNo, nRlSize, FL_UNLOCK );
|
||||
nPos -= ulRecNo;
|
||||
else if( iDir == 2 )
|
||||
fLck = hb_fileLock( pArea->pDataFile, nPos + ( ulRecNo - 1 ) * pArea->uiRecordLen + pArea->uiHeaderLen, nRlSize, FL_UNLOCK );
|
||||
nPos += ( ulRecNo - 1 ) * pArea->uiRecordLen + pArea->uiHeaderLen;
|
||||
else
|
||||
fLck = hb_fileLock( pArea->pDataFile, nPos + ulRecNo, nRlSize, FL_UNLOCK );
|
||||
nPos += ulRecNo;
|
||||
|
||||
fLck = hb_fileLock( pArea->pDataFile, nPos, nRlSize, FL_UNLOCK );
|
||||
if( !fLck )
|
||||
errCode = HB_FAILURE;
|
||||
}
|
||||
@@ -4875,7 +4930,7 @@ static HB_ERRCODE hb_dbfRawLock( DBFAREAP pArea, HB_USHORT uiAction, HB_ULONG ul
|
||||
for( ;; )
|
||||
{
|
||||
fLck = hb_fileLock( pArea->pDataFile, nPos, 1, FL_LOCK | FLX_WAIT );
|
||||
/* TODO: call special error handler (LOCKHANDLER) hiere if !fLck */
|
||||
/* TODO: call special error handler (LOCKHANDLER) if !fLck */
|
||||
if( fLck )
|
||||
break;
|
||||
hb_releaseCPU();
|
||||
|
||||
@@ -63,6 +63,9 @@
|
||||
#if !defined( HB_OS_WIN_CE )
|
||||
# include <sys/types.h>
|
||||
# include <sys/stat.h>
|
||||
# if defined( HB_OS_UNIX )
|
||||
# include <unistd.h>
|
||||
# endif
|
||||
#endif
|
||||
|
||||
|
||||
@@ -303,6 +306,22 @@ static HB_BOOL hb_fileUnlock( PHB_FILE pFile, HB_BOOL * pfLockFS,
|
||||
return fResult;
|
||||
}
|
||||
|
||||
static HB_BOOL hb_fileTestLock( PHB_FILE pFile,
|
||||
HB_FOFFSET nStart, HB_FOFFSET nLen )
|
||||
{
|
||||
HB_UINT uiPos;
|
||||
|
||||
uiPos = hb_fileFindOffset( pFile, nStart );
|
||||
if( uiPos < pFile->uiLocks )
|
||||
{
|
||||
PHB_FLOCK pLock = &pFile->pLocks[ uiPos ];
|
||||
if( nStart + nLen > pLock->start )
|
||||
return HB_TRUE;
|
||||
}
|
||||
|
||||
return HB_FALSE;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* file methods
|
||||
@@ -516,6 +535,29 @@ static HB_BOOL s_fileLock( PHB_FILE pFile, HB_FOFFSET nStart, HB_FOFFSET nLen,
|
||||
return fResult;
|
||||
}
|
||||
|
||||
static int s_fileLockTest( PHB_FILE pFile, HB_FOFFSET nStart, HB_FOFFSET nLen,
|
||||
int iType )
|
||||
{
|
||||
HB_BOOL fLocked;
|
||||
int iResult;
|
||||
|
||||
hb_threadEnterCriticalSection( &s_fileMtx );
|
||||
fLocked = hb_fileTestLock( pFile, nStart, nLen );
|
||||
hb_threadLeaveCriticalSection( &s_fileMtx );
|
||||
if( fLocked )
|
||||
{
|
||||
#if defined( HB_OS_UNIX )
|
||||
iResult = getpid();
|
||||
#else
|
||||
iResult = 1;
|
||||
#endif
|
||||
}
|
||||
else
|
||||
iResult = hb_fsLockTest( pFile->hFile, nStart, nLen, ( HB_USHORT ) iType );
|
||||
|
||||
return iResult;
|
||||
}
|
||||
|
||||
static HB_SIZE s_fileReadAt( PHB_FILE pFile, void * buffer, HB_SIZE nSize,
|
||||
HB_FOFFSET nOffset )
|
||||
{
|
||||
@@ -566,6 +608,7 @@ static const HB_FILE_FUNCS * s_fileMethods( void )
|
||||
s_fileExtOpen,
|
||||
s_fileClose,
|
||||
s_fileLock,
|
||||
s_fileLockTest,
|
||||
s_fileReadAt,
|
||||
s_fileWriteAt,
|
||||
s_fileTruncAt,
|
||||
@@ -669,6 +712,12 @@ HB_BOOL hb_fileLock( PHB_FILE pFile, HB_FOFFSET nStart, HB_FOFFSET nLen,
|
||||
return pFile->pFuncs->Lock( pFile, nStart, nLen, iType );
|
||||
}
|
||||
|
||||
int hb_fileLockTest( PHB_FILE pFile, HB_FOFFSET nStart, HB_FOFFSET nLen,
|
||||
int iType )
|
||||
{
|
||||
return pFile->pFuncs->LockTest( pFile, nStart, nLen, iType );
|
||||
}
|
||||
|
||||
HB_SIZE hb_fileReadAt( PHB_FILE pFile, void * buffer, HB_SIZE nSize,
|
||||
HB_FOFFSET nOffset )
|
||||
{
|
||||
|
||||
@@ -2535,7 +2535,7 @@ HB_BOOL hb_fsLock( HB_FHANDLE hFileHandle, HB_ULONG ulStart,
|
||||
lock_info.l_start = ulStart;
|
||||
lock_info.l_len = ulLength;
|
||||
lock_info.l_whence = SEEK_SET; /* start from the beginning of the file */
|
||||
lock_info.l_pid = getpid();
|
||||
lock_info.l_pid = 0;
|
||||
|
||||
HB_FAILURE_RETRY( iResult, fcntl( hFileHandle,
|
||||
( uiMode & FLX_WAIT ) ? F_SETLKW: F_SETLK,
|
||||
@@ -2549,7 +2549,7 @@ HB_BOOL hb_fsLock( HB_FHANDLE hFileHandle, HB_ULONG ulStart,
|
||||
lock_info.l_start = ulStart;
|
||||
lock_info.l_len = ulLength;
|
||||
lock_info.l_whence = SEEK_SET;
|
||||
lock_info.l_pid = getpid();
|
||||
lock_info.l_pid = 0;
|
||||
|
||||
HB_FAILURE_RETRY( iResult, fcntl( hFileHandle, F_SETLK, &lock_info ) );
|
||||
fResult = iResult != -1;
|
||||
@@ -2668,7 +2668,7 @@ HB_BOOL hb_fsLockLarge( HB_FHANDLE hFileHandle, HB_FOFFSET nStart,
|
||||
lock_info.l_start = nStart;
|
||||
lock_info.l_len = nLength;
|
||||
lock_info.l_whence = SEEK_SET; /* start from the beginning of the file */
|
||||
lock_info.l_pid = getpid();
|
||||
lock_info.l_pid = 0;
|
||||
|
||||
HB_FAILURE_RETRY( iResult, fcntl( hFileHandle,
|
||||
( uiMode & FLX_WAIT ) ? F_SETLKW64: F_SETLK64,
|
||||
@@ -2682,7 +2682,7 @@ HB_BOOL hb_fsLockLarge( HB_FHANDLE hFileHandle, HB_FOFFSET nStart,
|
||||
lock_info.l_start = nStart;
|
||||
lock_info.l_len = nLength;
|
||||
lock_info.l_whence = SEEK_SET;
|
||||
lock_info.l_pid = getpid();
|
||||
lock_info.l_pid = 0;
|
||||
|
||||
HB_FAILURE_RETRY( iResult, fcntl( hFileHandle, F_SETLK64, &lock_info ) );
|
||||
fResult = iResult != -1;
|
||||
@@ -2701,6 +2701,52 @@ HB_BOOL hb_fsLockLarge( HB_FHANDLE hFileHandle, HB_FOFFSET nStart,
|
||||
return fResult;
|
||||
}
|
||||
|
||||
int hb_fsLockTest( HB_FHANDLE hFileHandle, HB_FOFFSET nStart,
|
||||
HB_FOFFSET nLength, HB_USHORT uiMode )
|
||||
{
|
||||
int iResult;
|
||||
|
||||
HB_TRACE(HB_TR_DEBUG, ("hb_fsLockTest(%p, %" PFHL "u, %" PFHL "i, %hu)", ( void * ) ( HB_PTRDIFF ) hFileHandle, nStart, nLength, uiMode));
|
||||
|
||||
#if defined( HB_OS_UNIX )
|
||||
{
|
||||
# if defined( HB_USE_LARGEFILE64 )
|
||||
struct flock64 lock_info;
|
||||
|
||||
lock_info.l_type = ( uiMode & FLX_SHARED ) ? F_RDLCK : F_WRLCK;;
|
||||
lock_info.l_start = nStart;
|
||||
lock_info.l_len = nLength;
|
||||
lock_info.l_whence = SEEK_SET;
|
||||
lock_info.l_pid = 0;
|
||||
iResult = fcntl( hFileHandle, F_GETLK64, &lock_info ) != -1 ?
|
||||
( int ) lock_info.l_pid : -1;
|
||||
# else
|
||||
struct flock lock_info;
|
||||
|
||||
lock_info.l_type = ( uiMode & FLX_SHARED ) ? F_RDLCK : F_WRLCK;;
|
||||
lock_info.l_start = nStart;
|
||||
lock_info.l_len = nLength;
|
||||
lock_info.l_whence = SEEK_SET;
|
||||
lock_info.l_pid = 0;
|
||||
iResult = fcntl( hFileHandle, F_GETLK, &lock_info ) != -1 ?
|
||||
( int ) lock_info.l_pid : -1;
|
||||
# endif
|
||||
}
|
||||
#else
|
||||
if( hb_fsLockLarge( hFileHandle, nStart, nLength, ( uiMode & FLX_SHARED ) | FL_LOCK ) )
|
||||
{
|
||||
if( !hb_fsLockLarge( hFileHandle, nStart, nLength, FL_UNLOCK ) )
|
||||
iResult = -1;
|
||||
else
|
||||
iResult = 0;
|
||||
}
|
||||
else
|
||||
iResult = 1;
|
||||
#endif
|
||||
|
||||
return iResult;
|
||||
}
|
||||
|
||||
HB_ULONG hb_fsSeek( HB_FHANDLE hFileHandle, HB_LONG lOffset, HB_USHORT uiFlags )
|
||||
{
|
||||
HB_ULONG ulPos;
|
||||
|
||||
Reference in New Issue
Block a user