2015-11-16 16:00:22 +00:00
/*
* * 2011 - 12 - 03
* *
* * The author disclaims copyright to this source code . In place of
* * a legal notice , here is a blessing :
* *
* * May you do good and not evil .
* * May you find forgiveness for yourself and forgive others .
* * May you share freely , never taking more than you give .
* *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* *
* * Unix - specific run - time environment implementation for LSM .
*/
2017-06-01 16:13:57 +00:00
2017-06-27 05:59:47 +00:00
# ifndef _WIN32
2017-06-01 16:13:57 +00:00
2015-11-16 16:00:22 +00:00
# if defined(__GNUC__) || defined(__TINYC__)
/* workaround for ftruncate() visibility on gcc. */
# ifndef _XOPEN_SOURCE
# define _XOPEN_SOURCE 500
# endif
# endif
# include <unistd.h>
# include <sys/types.h>
# include <sys/stat.h>
# include <fcntl.h>
# include <assert.h>
# include <string.h>
# include <stdlib.h>
# include <stdarg.h>
# include <stdio.h>
# include <ctype.h>
# include <unistd.h>
# include <errno.h>
# include <sys/mman.h>
# include "lsmInt.h"
/* There is no fdatasync() call on Android */
# ifdef __ANDROID__
# define fdatasync(x) fsync(x)
# endif
/*
* * An open file is an instance of the following object
*/
typedef struct PosixFile PosixFile ;
struct PosixFile {
lsm_env * pEnv ; /* The run-time environment */
const char * zName ; /* Full path to file */
int fd ; /* The open file descriptor */
int shmfd ; /* Shared memory file-descriptor */
void * pMap ; /* Pointer to mapping of file fd */
off_t nMap ; /* Size of mapping at pMap in bytes */
int nShm ; /* Number of entries in array apShm[] */
void * * apShm ; /* Array of 32K shared memory segments */
} ;
static char * posixShmFile ( PosixFile * p ) {
char * zShm ;
int nName = strlen ( p - > zName ) ;
zShm = ( char * ) lsmMalloc ( p - > pEnv , nName + 4 + 1 ) ;
if ( zShm ) {
memcpy ( zShm , p - > zName , nName ) ;
memcpy ( & zShm [ nName ] , " -shm " , 5 ) ;
}
return zShm ;
}
static int lsmPosixOsOpen (
lsm_env * pEnv ,
const char * zFile ,
int flags ,
lsm_file * * ppFile
) {
int rc = LSM_OK ;
PosixFile * p ;
p = lsm_malloc ( pEnv , sizeof ( PosixFile ) ) ;
if ( p = = 0 ) {
rc = LSM_NOMEM ;
} else {
int bReadonly = ( flags & LSM_OPEN_READONLY ) ;
int oflags = ( bReadonly ? O_RDONLY : ( O_RDWR | O_CREAT ) ) ;
memset ( p , 0 , sizeof ( PosixFile ) ) ;
p - > zName = zFile ;
p - > pEnv = pEnv ;
p - > fd = open ( zFile , oflags , 0644 ) ;
if ( p - > fd < 0 ) {
lsm_free ( pEnv , p ) ;
p = 0 ;
if ( errno = = ENOENT ) {
rc = lsmErrorBkpt ( LSM_IOERR_NOENT ) ;
} else {
rc = LSM_IOERR_BKPT ;
}
}
}
* ppFile = ( lsm_file * ) p ;
return rc ;
}
static int lsmPosixOsWrite (
lsm_file * pFile , /* File to write to */
lsm_i64 iOff , /* Offset to write to */
void * pData , /* Write data from this buffer */
int nData /* Bytes of data to write */
) {
int rc = LSM_OK ;
PosixFile * p = ( PosixFile * ) pFile ;
off_t offset ;
offset = lseek ( p - > fd , ( off_t ) iOff , SEEK_SET ) ;
if ( offset ! = iOff ) {
rc = LSM_IOERR_BKPT ;
} else {
ssize_t prc = write ( p - > fd , pData , ( size_t ) nData ) ;
if ( prc < 0 ) rc = LSM_IOERR_BKPT ;
}
return rc ;
}
static int lsmPosixOsTruncate (
lsm_file * pFile , /* File to write to */
lsm_i64 nSize /* Size to truncate file to */
) {
PosixFile * p = ( PosixFile * ) pFile ;
int rc = LSM_OK ; /* Return code */
int prc ; /* Posix Return Code */
struct stat sStat ; /* Result of fstat() invocation */
prc = fstat ( p - > fd , & sStat ) ;
if ( prc = = 0 & & sStat . st_size > nSize ) {
prc = ftruncate ( p - > fd , ( off_t ) nSize ) ;
}
if ( prc < 0 ) rc = LSM_IOERR_BKPT ;
return rc ;
}
static int lsmPosixOsRead (
lsm_file * pFile , /* File to read from */
lsm_i64 iOff , /* Offset to read from */
void * pData , /* Read data into this buffer */
int nData /* Bytes of data to read */
) {
int rc = LSM_OK ;
PosixFile * p = ( PosixFile * ) pFile ;
off_t offset ;
offset = lseek ( p - > fd , ( off_t ) iOff , SEEK_SET ) ;
if ( offset ! = iOff ) {
rc = LSM_IOERR_BKPT ;
} else {
ssize_t prc = read ( p - > fd , pData , ( size_t ) nData ) ;
if ( prc < 0 ) {
rc = LSM_IOERR_BKPT ;
} else if ( prc < nData ) {
memset ( & ( ( u8 * ) pData ) [ prc ] , 0 , nData - prc ) ;
}
}
return rc ;
}
static int lsmPosixOsSync ( lsm_file * pFile ) {
int rc = LSM_OK ;
# ifndef LSM_NO_SYNC
PosixFile * p = ( PosixFile * ) pFile ;
int prc = 0 ;
if ( p - > pMap ) {
prc = msync ( p - > pMap , p - > nMap , MS_SYNC ) ;
}
if ( prc = = 0 ) prc = fdatasync ( p - > fd ) ;
if ( prc < 0 ) rc = LSM_IOERR_BKPT ;
# else
( void ) pFile ;
# endif
return rc ;
}
static int lsmPosixOsSectorSize ( lsm_file * pFile ) {
return 512 ;
}
static int lsmPosixOsRemap (
lsm_file * pFile ,
lsm_i64 iMin ,
void * * ppOut ,
lsm_i64 * pnOut
) {
off_t iSz ;
int prc ;
PosixFile * p = ( PosixFile * ) pFile ;
struct stat buf ;
/* If the file is between 0 and 2MB in size, extend it in chunks of 256K.
* * Thereafter , in chunks of 1 MB at a time . */
const int aIncrSz [ ] = { 256 * 1024 , 1024 * 1024 } ;
int nIncrSz = aIncrSz [ iMin > ( 2 * 1024 * 1024 ) ] ;
if ( p - > pMap ) {
munmap ( p - > pMap , p - > nMap ) ;
* ppOut = p - > pMap = 0 ;
* pnOut = p - > nMap = 0 ;
}
if ( iMin > = 0 ) {
memset ( & buf , 0 , sizeof ( buf ) ) ;
prc = fstat ( p - > fd , & buf ) ;
if ( prc ! = 0 ) return LSM_IOERR_BKPT ;
iSz = buf . st_size ;
if ( iSz < iMin ) {
iSz = ( ( iMin + nIncrSz - 1 ) / nIncrSz ) * nIncrSz ;
prc = ftruncate ( p - > fd , iSz ) ;
if ( prc ! = 0 ) return LSM_IOERR_BKPT ;
}
p - > pMap = mmap ( 0 , iSz , PROT_READ | PROT_WRITE , MAP_SHARED , p - > fd , 0 ) ;
2020-06-22 16:02:06 +00:00
if ( p - > pMap = = MAP_FAILED ) {
p - > pMap = 0 ;
return LSM_IOERR_BKPT ;
}
2015-11-16 16:00:22 +00:00
p - > nMap = iSz ;
}
* ppOut = p - > pMap ;
* pnOut = p - > nMap ;
return LSM_OK ;
}
static int lsmPosixOsFullpath (
lsm_env * pEnv ,
const char * zName ,
char * zOut ,
int * pnOut
) {
int nBuf = * pnOut ;
int nReq ;
if ( zName [ 0 ] ! = ' / ' ) {
char * z ;
char * zTmp ;
int nTmp = 512 ;
zTmp = lsmMalloc ( pEnv , nTmp ) ;
while ( zTmp ) {
z = getcwd ( zTmp , nTmp ) ;
if ( z | | errno ! = ERANGE ) break ;
nTmp = nTmp * 2 ;
zTmp = lsmReallocOrFree ( pEnv , zTmp , nTmp ) ;
}
if ( zTmp = = 0 ) return LSM_NOMEM_BKPT ;
if ( z = = 0 ) return LSM_IOERR_BKPT ;
assert ( z = = zTmp ) ;
nTmp = strlen ( zTmp ) ;
nReq = nTmp + 1 + strlen ( zName ) + 1 ;
if ( nReq < = nBuf ) {
memcpy ( zOut , zTmp , nTmp ) ;
zOut [ nTmp ] = ' / ' ;
memcpy ( & zOut [ nTmp + 1 ] , zName , strlen ( zName ) + 1 ) ;
}
lsmFree ( pEnv , zTmp ) ;
} else {
nReq = strlen ( zName ) + 1 ;
if ( nReq < = nBuf ) {
memcpy ( zOut , zName , strlen ( zName ) + 1 ) ;
}
}
* pnOut = nReq ;
return LSM_OK ;
}
static int lsmPosixOsFileid (
lsm_file * pFile ,
void * pBuf ,
int * pnBuf
) {
int prc ;
int nBuf ;
int nReq ;
PosixFile * p = ( PosixFile * ) pFile ;
struct stat buf ;
nBuf = * pnBuf ;
nReq = ( sizeof ( buf . st_dev ) + sizeof ( buf . st_ino ) ) ;
* pnBuf = nReq ;
if ( nReq > nBuf ) return LSM_OK ;
memset ( & buf , 0 , sizeof ( buf ) ) ;
prc = fstat ( p - > fd , & buf ) ;
if ( prc ! = 0 ) return LSM_IOERR_BKPT ;
memcpy ( pBuf , & buf . st_dev , sizeof ( buf . st_dev ) ) ;
memcpy ( & ( ( ( u8 * ) pBuf ) [ sizeof ( buf . st_dev ) ] ) , & buf . st_ino , sizeof ( buf . st_ino ) ) ;
return LSM_OK ;
}
static int lsmPosixOsUnlink ( lsm_env * pEnv , const char * zFile ) {
int prc = unlink ( zFile ) ;
return prc ? LSM_IOERR_BKPT : LSM_OK ;
}
2017-06-30 18:12:09 +00:00
static int lsmPosixOsLock ( lsm_file * pFile , int iLock , int eType ) {
2015-11-16 16:00:22 +00:00
int rc = LSM_OK ;
PosixFile * p = ( PosixFile * ) pFile ;
static const short aType [ 3 ] = { F_UNLCK , F_RDLCK , F_WRLCK } ;
struct flock lock ;
assert ( aType [ LSM_LOCK_UNLOCK ] = = F_UNLCK ) ;
assert ( aType [ LSM_LOCK_SHARED ] = = F_RDLCK ) ;
assert ( aType [ LSM_LOCK_EXCL ] = = F_WRLCK ) ;
assert ( eType > = 0 & & eType < array_size ( aType ) ) ;
assert ( iLock > 0 & & iLock < = 32 ) ;
memset ( & lock , 0 , sizeof ( lock ) ) ;
lock . l_whence = SEEK_SET ;
lock . l_len = 1 ;
lock . l_type = aType [ eType ] ;
lock . l_start = ( 4096 - iLock ) ;
if ( fcntl ( p - > fd , F_SETLK , & lock ) ) {
int e = errno ;
if ( e = = EACCES | | e = = EAGAIN ) {
rc = LSM_BUSY ;
} else {
rc = LSM_IOERR_BKPT ;
}
}
return rc ;
}
2017-06-30 18:12:09 +00:00
static int lsmPosixOsTestLock ( lsm_file * pFile , int iLock , int nLock , int eType ) {
2015-11-16 16:00:22 +00:00
int rc = LSM_OK ;
PosixFile * p = ( PosixFile * ) pFile ;
static const short aType [ 3 ] = { 0 , F_RDLCK , F_WRLCK } ;
struct flock lock ;
assert ( eType = = LSM_LOCK_SHARED | | eType = = LSM_LOCK_EXCL ) ;
assert ( aType [ LSM_LOCK_SHARED ] = = F_RDLCK ) ;
assert ( aType [ LSM_LOCK_EXCL ] = = F_WRLCK ) ;
assert ( eType > = 0 & & eType < array_size ( aType ) ) ;
assert ( iLock > 0 & & iLock < = 32 ) ;
memset ( & lock , 0 , sizeof ( lock ) ) ;
lock . l_whence = SEEK_SET ;
lock . l_len = nLock ;
lock . l_type = aType [ eType ] ;
2017-06-29 19:08:52 +00:00
lock . l_start = ( 4096 - iLock - nLock + 1 ) ;
2015-11-16 16:00:22 +00:00
if ( fcntl ( p - > fd , F_GETLK , & lock ) ) {
rc = LSM_IOERR_BKPT ;
} else if ( lock . l_type ! = F_UNLCK ) {
rc = LSM_BUSY ;
}
return rc ;
}
2017-06-30 18:12:09 +00:00
static int lsmPosixOsShmMap ( lsm_file * pFile , int iChunk , int sz , void * * ppShm ) {
2015-11-16 16:00:22 +00:00
PosixFile * p = ( PosixFile * ) pFile ;
* ppShm = 0 ;
assert ( sz = = LSM_SHM_CHUNK_SIZE ) ;
if ( iChunk > = p - > nShm ) {
int i ;
void * * apNew ;
int nNew = iChunk + 1 ;
off_t nReq = nNew * LSM_SHM_CHUNK_SIZE ;
struct stat sStat ;
/* If the shared-memory file has not been opened, open it now. */
if ( p - > shmfd < = 0 ) {
char * zShm = posixShmFile ( p ) ;
if ( ! zShm ) return LSM_NOMEM_BKPT ;
p - > shmfd = open ( zShm , O_RDWR | O_CREAT , 0644 ) ;
lsmFree ( p - > pEnv , zShm ) ;
if ( p - > shmfd < 0 ) {
return LSM_IOERR_BKPT ;
}
}
/* If the shared-memory file is not large enough to contain the
* * requested chunk , cause it to grow . */
if ( fstat ( p - > shmfd , & sStat ) ) {
return LSM_IOERR_BKPT ;
}
if ( sStat . st_size < nReq ) {
if ( ftruncate ( p - > shmfd , nReq ) ) {
return LSM_IOERR_BKPT ;
}
}
apNew = ( void * * ) lsmRealloc ( p - > pEnv , p - > apShm , sizeof ( void * ) * nNew ) ;
if ( ! apNew ) return LSM_NOMEM_BKPT ;
for ( i = p - > nShm ; i < nNew ; i + + ) {
apNew [ i ] = 0 ;
}
p - > apShm = apNew ;
p - > nShm = nNew ;
}
if ( p - > apShm [ iChunk ] = = 0 ) {
p - > apShm [ iChunk ] = mmap ( 0 , LSM_SHM_CHUNK_SIZE ,
PROT_READ | PROT_WRITE , MAP_SHARED , p - > shmfd , iChunk * LSM_SHM_CHUNK_SIZE
) ;
2020-06-22 16:02:06 +00:00
if ( p - > apShm [ iChunk ] = = MAP_FAILED ) {
p - > apShm [ iChunk ] = 0 ;
return LSM_IOERR_BKPT ;
}
2015-11-16 16:00:22 +00:00
}
* ppShm = p - > apShm [ iChunk ] ;
return LSM_OK ;
}
2017-06-30 18:12:09 +00:00
static void lsmPosixOsShmBarrier ( void ) {
2015-11-16 16:00:22 +00:00
}
2017-06-30 18:12:09 +00:00
static int lsmPosixOsShmUnmap ( lsm_file * pFile , int bDelete ) {
2015-11-16 16:00:22 +00:00
PosixFile * p = ( PosixFile * ) pFile ;
if ( p - > shmfd > 0 ) {
int i ;
for ( i = 0 ; i < p - > nShm ; i + + ) {
if ( p - > apShm [ i ] ) {
munmap ( p - > apShm [ i ] , LSM_SHM_CHUNK_SIZE ) ;
p - > apShm [ i ] = 0 ;
}
}
close ( p - > shmfd ) ;
p - > shmfd = 0 ;
if ( bDelete ) {
char * zShm = posixShmFile ( p ) ;
if ( zShm ) unlink ( zShm ) ;
lsmFree ( p - > pEnv , zShm ) ;
}
}
return LSM_OK ;
}
static int lsmPosixOsClose ( lsm_file * pFile ) {
PosixFile * p = ( PosixFile * ) pFile ;
lsmPosixOsShmUnmap ( pFile , 0 ) ;
if ( p - > pMap ) munmap ( p - > pMap , p - > nMap ) ;
close ( p - > fd ) ;
lsm_free ( p - > pEnv , p - > apShm ) ;
lsm_free ( p - > pEnv , p ) ;
return LSM_OK ;
}
static int lsmPosixOsSleep ( lsm_env * pEnv , int us ) {
#if 0
/* Apparently on Android usleep() returns void */
if ( usleep ( us ) ) return LSM_IOERR ;
# endif
usleep ( us ) ;
return LSM_OK ;
}
/****************************************************************************
* * Memory allocation routines .
*/
# define BLOCK_HDR_SIZE ROUND8( sizeof(size_t) )
static void * lsmPosixOsMalloc ( lsm_env * pEnv , size_t N ) {
unsigned char * m ;
N + = BLOCK_HDR_SIZE ;
m = ( unsigned char * ) malloc ( N ) ;
* ( ( size_t * ) m ) = N ;
return m + BLOCK_HDR_SIZE ;
}
static void lsmPosixOsFree ( lsm_env * pEnv , void * p ) {
if ( p ) {
free ( ( ( unsigned char * ) p ) - BLOCK_HDR_SIZE ) ;
}
}
static void * lsmPosixOsRealloc ( lsm_env * pEnv , void * p , size_t N ) {
unsigned char * m = ( unsigned char * ) p ;
if ( 1 > N ) {
lsmPosixOsFree ( pEnv , p ) ;
return NULL ;
} else if ( NULL = = p ) {
return lsmPosixOsMalloc ( pEnv , N ) ;
} else {
void * re = NULL ;
m - = BLOCK_HDR_SIZE ;
#if 0 /* arguable: don't shrink */
size_t * sz = ( size_t * ) m ;
if ( * sz > = ( size_t ) N ) {
return p ;
}
# endif
re = realloc ( m , N + BLOCK_HDR_SIZE ) ;
if ( re ) {
m = ( unsigned char * ) re ;
* ( ( size_t * ) m ) = N ;
return m + BLOCK_HDR_SIZE ;
} else {
return NULL ;
}
}
}
static size_t lsmPosixOsMSize ( lsm_env * pEnv , void * p ) {
unsigned char * m = ( unsigned char * ) p ;
return * ( ( size_t * ) ( m - BLOCK_HDR_SIZE ) ) ;
}
# undef BLOCK_HDR_SIZE
# ifdef LSM_MUTEX_PTHREADS
/*************************************************************************
* * Mutex methods for pthreads based systems . If LSM_MUTEX_PTHREADS is
* * missing then a no - op implementation of mutexes found in lsm_mutex . c
* * will be used instead .
*/
# include <pthread.h>
typedef struct PthreadMutex PthreadMutex ;
struct PthreadMutex {
lsm_env * pEnv ;
pthread_mutex_t mutex ;
# ifdef LSM_DEBUG
pthread_t owner ;
# endif
} ;
# ifdef LSM_DEBUG
# define LSM_PTHREAD_STATIC_MUTEX { 0, PTHREAD_MUTEX_INITIALIZER, 0 }
# else
# define LSM_PTHREAD_STATIC_MUTEX { 0, PTHREAD_MUTEX_INITIALIZER }
# endif
static int lsmPosixOsMutexStatic (
lsm_env * pEnv ,
int iMutex ,
lsm_mutex * * ppStatic
) {
static PthreadMutex sMutex [ 2 ] = {
LSM_PTHREAD_STATIC_MUTEX ,
LSM_PTHREAD_STATIC_MUTEX
} ;
assert ( iMutex = = LSM_MUTEX_GLOBAL | | iMutex = = LSM_MUTEX_HEAP ) ;
assert ( LSM_MUTEX_GLOBAL = = 1 & & LSM_MUTEX_HEAP = = 2 ) ;
* ppStatic = ( lsm_mutex * ) & sMutex [ iMutex - 1 ] ;
return LSM_OK ;
}
static int lsmPosixOsMutexNew ( lsm_env * pEnv , lsm_mutex * * ppNew ) {
PthreadMutex * pMutex ; /* Pointer to new mutex */
pthread_mutexattr_t attr ; /* Attributes object */
pMutex = ( PthreadMutex * ) lsmMallocZero ( pEnv , sizeof ( PthreadMutex ) ) ;
if ( ! pMutex ) return LSM_NOMEM_BKPT ;
pMutex - > pEnv = pEnv ;
pthread_mutexattr_init ( & attr ) ;
pthread_mutexattr_settype ( & attr , PTHREAD_MUTEX_RECURSIVE ) ;
pthread_mutex_init ( & pMutex - > mutex , & attr ) ;
pthread_mutexattr_destroy ( & attr ) ;
* ppNew = ( lsm_mutex * ) pMutex ;
return LSM_OK ;
}
static void lsmPosixOsMutexDel ( lsm_mutex * p ) {
PthreadMutex * pMutex = ( PthreadMutex * ) p ;
pthread_mutex_destroy ( & pMutex - > mutex ) ;
lsmFree ( pMutex - > pEnv , pMutex ) ;
}
static void lsmPosixOsMutexEnter ( lsm_mutex * p ) {
PthreadMutex * pMutex = ( PthreadMutex * ) p ;
pthread_mutex_lock ( & pMutex - > mutex ) ;
# ifdef LSM_DEBUG
assert ( ! pthread_equal ( pMutex - > owner , pthread_self ( ) ) ) ;
pMutex - > owner = pthread_self ( ) ;
assert ( pthread_equal ( pMutex - > owner , pthread_self ( ) ) ) ;
# endif
}
static int lsmPosixOsMutexTry ( lsm_mutex * p ) {
int ret ;
PthreadMutex * pMutex = ( PthreadMutex * ) p ;
ret = pthread_mutex_trylock ( & pMutex - > mutex ) ;
# ifdef LSM_DEBUG
if ( ret = = 0 ) {
assert ( ! pthread_equal ( pMutex - > owner , pthread_self ( ) ) ) ;
pMutex - > owner = pthread_self ( ) ;
assert ( pthread_equal ( pMutex - > owner , pthread_self ( ) ) ) ;
}
# endif
return ret ;
}
static void lsmPosixOsMutexLeave ( lsm_mutex * p ) {
PthreadMutex * pMutex = ( PthreadMutex * ) p ;
# ifdef LSM_DEBUG
assert ( pthread_equal ( pMutex - > owner , pthread_self ( ) ) ) ;
pMutex - > owner = 0 ;
assert ( ! pthread_equal ( pMutex - > owner , pthread_self ( ) ) ) ;
# endif
pthread_mutex_unlock ( & pMutex - > mutex ) ;
}
# ifdef LSM_DEBUG
static int lsmPosixOsMutexHeld ( lsm_mutex * p ) {
PthreadMutex * pMutex = ( PthreadMutex * ) p ;
return pMutex ? pthread_equal ( pMutex - > owner , pthread_self ( ) ) : 1 ;
}
static int lsmPosixOsMutexNotHeld ( lsm_mutex * p ) {
PthreadMutex * pMutex = ( PthreadMutex * ) p ;
return pMutex ? ! pthread_equal ( pMutex - > owner , pthread_self ( ) ) : 1 ;
}
# endif
/*
* * End of pthreads mutex implementation .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
# else
/*************************************************************************
* * Noop mutex implementation
*/
typedef struct NoopMutex NoopMutex ;
struct NoopMutex {
lsm_env * pEnv ; /* Environment handle (for xFree()) */
int bHeld ; /* True if mutex is held */
int bStatic ; /* True for a static mutex */
} ;
static NoopMutex aStaticNoopMutex [ 2 ] = {
{ 0 , 0 , 1 } ,
{ 0 , 0 , 1 } ,
} ;
static int lsmPosixOsMutexStatic (
lsm_env * pEnv ,
int iMutex ,
lsm_mutex * * ppStatic
) {
assert ( iMutex > = 1 & & iMutex < = ( int ) array_size ( aStaticNoopMutex ) ) ;
* ppStatic = ( lsm_mutex * ) & aStaticNoopMutex [ iMutex - 1 ] ;
return LSM_OK ;
}
static int lsmPosixOsMutexNew ( lsm_env * pEnv , lsm_mutex * * ppNew ) {
NoopMutex * p ;
p = ( NoopMutex * ) lsmMallocZero ( pEnv , sizeof ( NoopMutex ) ) ;
if ( p ) p - > pEnv = pEnv ;
* ppNew = ( lsm_mutex * ) p ;
return ( p ? LSM_OK : LSM_NOMEM_BKPT ) ;
}
static void lsmPosixOsMutexDel ( lsm_mutex * pMutex ) {
NoopMutex * p = ( NoopMutex * ) pMutex ;
assert ( p - > bStatic = = 0 & & p - > pEnv ) ;
lsmFree ( p - > pEnv , p ) ;
}
static void lsmPosixOsMutexEnter ( lsm_mutex * pMutex ) {
NoopMutex * p = ( NoopMutex * ) pMutex ;
assert ( p - > bHeld = = 0 ) ;
p - > bHeld = 1 ;
}
static int lsmPosixOsMutexTry ( lsm_mutex * pMutex ) {
NoopMutex * p = ( NoopMutex * ) pMutex ;
assert ( p - > bHeld = = 0 ) ;
p - > bHeld = 1 ;
return 0 ;
}
static void lsmPosixOsMutexLeave ( lsm_mutex * pMutex ) {
NoopMutex * p = ( NoopMutex * ) pMutex ;
assert ( p - > bHeld = = 1 ) ;
p - > bHeld = 0 ;
}
# ifdef LSM_DEBUG
static int lsmPosixOsMutexHeld ( lsm_mutex * pMutex ) {
NoopMutex * p = ( NoopMutex * ) pMutex ;
return p ? p - > bHeld : 1 ;
}
static int lsmPosixOsMutexNotHeld ( lsm_mutex * pMutex ) {
NoopMutex * p = ( NoopMutex * ) pMutex ;
return p ? ! p - > bHeld : 1 ;
}
# endif
/***************************************************************************/
# endif /* else LSM_MUTEX_NONE */
/* Without LSM_DEBUG, the MutexHeld tests are never called */
# ifndef LSM_DEBUG
# define lsmPosixOsMutexHeld 0
# define lsmPosixOsMutexNotHeld 0
# endif
lsm_env * lsm_default_env ( void ) {
static lsm_env posix_env = {
sizeof ( lsm_env ) , /* nByte */
1 , /* iVersion */
/***** file i/o ******************/
0 , /* pVfsCtx */
lsmPosixOsFullpath , /* xFullpath */
lsmPosixOsOpen , /* xOpen */
lsmPosixOsRead , /* xRead */
lsmPosixOsWrite , /* xWrite */
lsmPosixOsTruncate , /* xTruncate */
lsmPosixOsSync , /* xSync */
lsmPosixOsSectorSize , /* xSectorSize */
lsmPosixOsRemap , /* xRemap */
lsmPosixOsFileid , /* xFileid */
lsmPosixOsClose , /* xClose */
lsmPosixOsUnlink , /* xUnlink */
lsmPosixOsLock , /* xLock */
lsmPosixOsTestLock , /* xTestLock */
lsmPosixOsShmMap , /* xShmMap */
lsmPosixOsShmBarrier , /* xShmBarrier */
lsmPosixOsShmUnmap , /* xShmUnmap */
/***** memory allocation *********/
0 , /* pMemCtx */
lsmPosixOsMalloc , /* xMalloc */
lsmPosixOsRealloc , /* xRealloc */
lsmPosixOsFree , /* xFree */
lsmPosixOsMSize , /* xSize */
/***** mutexes *********************/
0 , /* pMutexCtx */
lsmPosixOsMutexStatic , /* xMutexStatic */
lsmPosixOsMutexNew , /* xMutexNew */
lsmPosixOsMutexDel , /* xMutexDel */
lsmPosixOsMutexEnter , /* xMutexEnter */
lsmPosixOsMutexTry , /* xMutexTry */
lsmPosixOsMutexLeave , /* xMutexLeave */
lsmPosixOsMutexHeld , /* xMutexHeld */
lsmPosixOsMutexNotHeld , /* xMutexNotHeld */
/***** other *********************/
lsmPosixOsSleep , /* xSleep */
} ;
return & posix_env ;
}
2017-06-01 16:13:57 +00:00
# endif