modernc.org/cc@v1.0.1/v2/testdata/_sqlite/ext/lsm1/lsm_unix.c (about) 1 /* 2 ** 2011-12-03 3 ** 4 ** The author disclaims copyright to this source code. In place of 5 ** a legal notice, here is a blessing: 6 ** 7 ** May you do good and not evil. 8 ** May you find forgiveness for yourself and forgive others. 9 ** May you share freely, never taking more than you give. 10 ** 11 ************************************************************************* 12 ** 13 ** Unix-specific run-time environment implementation for LSM. 14 */ 15 16 #ifndef _WIN32 17 18 #if defined(__GNUC__) || defined(__TINYC__) 19 /* workaround for ftruncate() visibility on gcc. */ 20 # ifndef _XOPEN_SOURCE 21 # define _XOPEN_SOURCE 500 22 # endif 23 #endif 24 25 #include <unistd.h> 26 #include <sys/types.h> 27 28 #include <sys/stat.h> 29 #include <fcntl.h> 30 #include <assert.h> 31 #include <string.h> 32 33 #include <stdlib.h> 34 #include <stdarg.h> 35 #include <stdio.h> 36 #include <ctype.h> 37 38 #include <unistd.h> 39 #include <errno.h> 40 41 #include <sys/mman.h> 42 #include "lsmInt.h" 43 44 /* There is no fdatasync() call on Android */ 45 #ifdef __ANDROID__ 46 # define fdatasync(x) fsync(x) 47 #endif 48 49 /* 50 ** An open file is an instance of the following object 51 */ 52 typedef struct PosixFile PosixFile; 53 struct PosixFile { 54 lsm_env *pEnv; /* The run-time environment */ 55 const char *zName; /* Full path to file */ 56 int fd; /* The open file descriptor */ 57 int shmfd; /* Shared memory file-descriptor */ 58 void *pMap; /* Pointer to mapping of file fd */ 59 off_t nMap; /* Size of mapping at pMap in bytes */ 60 int nShm; /* Number of entries in array apShm[] */ 61 void **apShm; /* Array of 32K shared memory segments */ 62 }; 63 64 static char *posixShmFile(PosixFile *p){ 65 char *zShm; 66 int nName = strlen(p->zName); 67 zShm = (char *)lsmMalloc(p->pEnv, nName+4+1); 68 if( zShm ){ 69 memcpy(zShm, p->zName, nName); 70 memcpy(&zShm[nName], "-shm", 5); 71 } 72 return zShm; 73 } 74 75 static int lsmPosixOsOpen( 76 lsm_env *pEnv, 77 const char *zFile, 78 int flags, 79 lsm_file **ppFile 80 ){ 81 int rc = LSM_OK; 82 PosixFile *p; 83 84 p = lsm_malloc(pEnv, sizeof(PosixFile)); 85 if( p==0 ){ 86 rc = LSM_NOMEM; 87 }else{ 88 int bReadonly = (flags & LSM_OPEN_READONLY); 89 int oflags = (bReadonly ? O_RDONLY : (O_RDWR|O_CREAT)); 90 memset(p, 0, sizeof(PosixFile)); 91 p->zName = zFile; 92 p->pEnv = pEnv; 93 p->fd = open(zFile, oflags, 0644); 94 if( p->fd<0 ){ 95 lsm_free(pEnv, p); 96 p = 0; 97 if( errno==ENOENT ){ 98 rc = lsmErrorBkpt(LSM_IOERR_NOENT); 99 }else{ 100 rc = LSM_IOERR_BKPT; 101 } 102 } 103 } 104 105 *ppFile = (lsm_file *)p; 106 return rc; 107 } 108 109 static int lsmPosixOsWrite( 110 lsm_file *pFile, /* File to write to */ 111 lsm_i64 iOff, /* Offset to write to */ 112 void *pData, /* Write data from this buffer */ 113 int nData /* Bytes of data to write */ 114 ){ 115 int rc = LSM_OK; 116 PosixFile *p = (PosixFile *)pFile; 117 off_t offset; 118 119 offset = lseek(p->fd, (off_t)iOff, SEEK_SET); 120 if( offset!=iOff ){ 121 rc = LSM_IOERR_BKPT; 122 }else{ 123 ssize_t prc = write(p->fd, pData, (size_t)nData); 124 if( prc<0 ) rc = LSM_IOERR_BKPT; 125 } 126 127 return rc; 128 } 129 130 static int lsmPosixOsTruncate( 131 lsm_file *pFile, /* File to write to */ 132 lsm_i64 nSize /* Size to truncate file to */ 133 ){ 134 PosixFile *p = (PosixFile *)pFile; 135 int rc = LSM_OK; /* Return code */ 136 int prc; /* Posix Return Code */ 137 struct stat sStat; /* Result of fstat() invocation */ 138 139 prc = fstat(p->fd, &sStat); 140 if( prc==0 && sStat.st_size>nSize ){ 141 prc = ftruncate(p->fd, (off_t)nSize); 142 } 143 if( prc<0 ) rc = LSM_IOERR_BKPT; 144 145 return rc; 146 } 147 148 static int lsmPosixOsRead( 149 lsm_file *pFile, /* File to read from */ 150 lsm_i64 iOff, /* Offset to read from */ 151 void *pData, /* Read data into this buffer */ 152 int nData /* Bytes of data to read */ 153 ){ 154 int rc = LSM_OK; 155 PosixFile *p = (PosixFile *)pFile; 156 off_t offset; 157 158 offset = lseek(p->fd, (off_t)iOff, SEEK_SET); 159 if( offset!=iOff ){ 160 rc = LSM_IOERR_BKPT; 161 }else{ 162 ssize_t prc = read(p->fd, pData, (size_t)nData); 163 if( prc<0 ){ 164 rc = LSM_IOERR_BKPT; 165 }else if( prc<nData ){ 166 memset(&((u8 *)pData)[prc], 0, nData - prc); 167 } 168 169 } 170 171 return rc; 172 } 173 174 static int lsmPosixOsSync(lsm_file *pFile){ 175 int rc = LSM_OK; 176 177 #ifndef LSM_NO_SYNC 178 PosixFile *p = (PosixFile *)pFile; 179 int prc = 0; 180 181 if( p->pMap ){ 182 prc = msync(p->pMap, p->nMap, MS_SYNC); 183 } 184 if( prc==0 ) prc = fdatasync(p->fd); 185 if( prc<0 ) rc = LSM_IOERR_BKPT; 186 #else 187 (void)pFile; 188 #endif 189 190 return rc; 191 } 192 193 static int lsmPosixOsSectorSize(lsm_file *pFile){ 194 return 512; 195 } 196 197 static int lsmPosixOsRemap( 198 lsm_file *pFile, 199 lsm_i64 iMin, 200 void **ppOut, 201 lsm_i64 *pnOut 202 ){ 203 off_t iSz; 204 int prc; 205 PosixFile *p = (PosixFile *)pFile; 206 struct stat buf; 207 208 /* If the file is between 0 and 2MB in size, extend it in chunks of 256K. 209 ** Thereafter, in chunks of 1MB at a time. */ 210 const int aIncrSz[] = {256*1024, 1024*1024}; 211 int nIncrSz = aIncrSz[iMin>(2*1024*1024)]; 212 213 if( p->pMap ){ 214 munmap(p->pMap, p->nMap); 215 *ppOut = p->pMap = 0; 216 *pnOut = p->nMap = 0; 217 } 218 219 if( iMin>=0 ){ 220 memset(&buf, 0, sizeof(buf)); 221 prc = fstat(p->fd, &buf); 222 if( prc!=0 ) return LSM_IOERR_BKPT; 223 iSz = buf.st_size; 224 if( iSz<iMin ){ 225 iSz = ((iMin + nIncrSz-1) / nIncrSz) * nIncrSz; 226 prc = ftruncate(p->fd, iSz); 227 if( prc!=0 ) return LSM_IOERR_BKPT; 228 } 229 230 p->pMap = mmap(0, iSz, PROT_READ|PROT_WRITE, MAP_SHARED, p->fd, 0); 231 p->nMap = iSz; 232 } 233 234 *ppOut = p->pMap; 235 *pnOut = p->nMap; 236 return LSM_OK; 237 } 238 239 static int lsmPosixOsFullpath( 240 lsm_env *pEnv, 241 const char *zName, 242 char *zOut, 243 int *pnOut 244 ){ 245 int nBuf = *pnOut; 246 int nReq; 247 248 if( zName[0]!='/' ){ 249 char *z; 250 char *zTmp; 251 int nTmp = 512; 252 zTmp = lsmMalloc(pEnv, nTmp); 253 while( zTmp ){ 254 z = getcwd(zTmp, nTmp); 255 if( z || errno!=ERANGE ) break; 256 nTmp = nTmp*2; 257 zTmp = lsmReallocOrFree(pEnv, zTmp, nTmp); 258 } 259 if( zTmp==0 ) return LSM_NOMEM_BKPT; 260 if( z==0 ) return LSM_IOERR_BKPT; 261 assert( z==zTmp ); 262 263 nTmp = strlen(zTmp); 264 nReq = nTmp + 1 + strlen(zName) + 1; 265 if( nReq<=nBuf ){ 266 memcpy(zOut, zTmp, nTmp); 267 zOut[nTmp] = '/'; 268 memcpy(&zOut[nTmp+1], zName, strlen(zName)+1); 269 } 270 lsmFree(pEnv, zTmp); 271 }else{ 272 nReq = strlen(zName)+1; 273 if( nReq<=nBuf ){ 274 memcpy(zOut, zName, strlen(zName)+1); 275 } 276 } 277 278 *pnOut = nReq; 279 return LSM_OK; 280 } 281 282 static int lsmPosixOsFileid( 283 lsm_file *pFile, 284 void *pBuf, 285 int *pnBuf 286 ){ 287 int prc; 288 int nBuf; 289 int nReq; 290 PosixFile *p = (PosixFile *)pFile; 291 struct stat buf; 292 293 nBuf = *pnBuf; 294 nReq = (sizeof(buf.st_dev) + sizeof(buf.st_ino)); 295 *pnBuf = nReq; 296 if( nReq>nBuf ) return LSM_OK; 297 298 memset(&buf, 0, sizeof(buf)); 299 prc = fstat(p->fd, &buf); 300 if( prc!=0 ) return LSM_IOERR_BKPT; 301 302 memcpy(pBuf, &buf.st_dev, sizeof(buf.st_dev)); 303 memcpy(&(((u8 *)pBuf)[sizeof(buf.st_dev)]), &buf.st_ino, sizeof(buf.st_ino)); 304 return LSM_OK; 305 } 306 307 static int lsmPosixOsUnlink(lsm_env *pEnv, const char *zFile){ 308 int prc = unlink(zFile); 309 return prc ? LSM_IOERR_BKPT : LSM_OK; 310 } 311 312 static int lsmPosixOsLock(lsm_file *pFile, int iLock, int eType){ 313 int rc = LSM_OK; 314 PosixFile *p = (PosixFile *)pFile; 315 static const short aType[3] = { F_UNLCK, F_RDLCK, F_WRLCK }; 316 struct flock lock; 317 318 assert( aType[LSM_LOCK_UNLOCK]==F_UNLCK ); 319 assert( aType[LSM_LOCK_SHARED]==F_RDLCK ); 320 assert( aType[LSM_LOCK_EXCL]==F_WRLCK ); 321 assert( eType>=0 && eType<array_size(aType) ); 322 assert( iLock>0 && iLock<=32 ); 323 324 memset(&lock, 0, sizeof(lock)); 325 lock.l_whence = SEEK_SET; 326 lock.l_len = 1; 327 lock.l_type = aType[eType]; 328 lock.l_start = (4096-iLock); 329 330 if( fcntl(p->fd, F_SETLK, &lock) ){ 331 int e = errno; 332 if( e==EACCES || e==EAGAIN ){ 333 rc = LSM_BUSY; 334 }else{ 335 rc = LSM_IOERR_BKPT; 336 } 337 } 338 339 return rc; 340 } 341 342 static int lsmPosixOsTestLock(lsm_file *pFile, int iLock, int nLock, int eType){ 343 int rc = LSM_OK; 344 PosixFile *p = (PosixFile *)pFile; 345 static const short aType[3] = { 0, F_RDLCK, F_WRLCK }; 346 struct flock lock; 347 348 assert( eType==LSM_LOCK_SHARED || eType==LSM_LOCK_EXCL ); 349 assert( aType[LSM_LOCK_SHARED]==F_RDLCK ); 350 assert( aType[LSM_LOCK_EXCL]==F_WRLCK ); 351 assert( eType>=0 && eType<array_size(aType) ); 352 assert( iLock>0 && iLock<=32 ); 353 354 memset(&lock, 0, sizeof(lock)); 355 lock.l_whence = SEEK_SET; 356 lock.l_len = nLock; 357 lock.l_type = aType[eType]; 358 lock.l_start = (4096-iLock-nLock+1); 359 360 if( fcntl(p->fd, F_GETLK, &lock) ){ 361 rc = LSM_IOERR_BKPT; 362 }else if( lock.l_type!=F_UNLCK ){ 363 rc = LSM_BUSY; 364 } 365 366 return rc; 367 } 368 369 static int lsmPosixOsShmMap(lsm_file *pFile, int iChunk, int sz, void **ppShm){ 370 PosixFile *p = (PosixFile *)pFile; 371 372 *ppShm = 0; 373 assert( sz==LSM_SHM_CHUNK_SIZE ); 374 if( iChunk>=p->nShm ){ 375 int i; 376 void **apNew; 377 int nNew = iChunk+1; 378 off_t nReq = nNew * LSM_SHM_CHUNK_SIZE; 379 struct stat sStat; 380 381 /* If the shared-memory file has not been opened, open it now. */ 382 if( p->shmfd<=0 ){ 383 char *zShm = posixShmFile(p); 384 if( !zShm ) return LSM_NOMEM_BKPT; 385 p->shmfd = open(zShm, O_RDWR|O_CREAT, 0644); 386 lsmFree(p->pEnv, zShm); 387 if( p->shmfd<0 ){ 388 return LSM_IOERR_BKPT; 389 } 390 } 391 392 /* If the shared-memory file is not large enough to contain the 393 ** requested chunk, cause it to grow. */ 394 if( fstat(p->shmfd, &sStat) ){ 395 return LSM_IOERR_BKPT; 396 } 397 if( sStat.st_size<nReq ){ 398 if( ftruncate(p->shmfd, nReq) ){ 399 return LSM_IOERR_BKPT; 400 } 401 } 402 403 apNew = (void **)lsmRealloc(p->pEnv, p->apShm, sizeof(void *) * nNew); 404 if( !apNew ) return LSM_NOMEM_BKPT; 405 for(i=p->nShm; i<nNew; i++){ 406 apNew[i] = 0; 407 } 408 p->apShm = apNew; 409 p->nShm = nNew; 410 } 411 412 if( p->apShm[iChunk]==0 ){ 413 p->apShm[iChunk] = mmap(0, LSM_SHM_CHUNK_SIZE, 414 PROT_READ|PROT_WRITE, MAP_SHARED, p->shmfd, iChunk*LSM_SHM_CHUNK_SIZE 415 ); 416 if( p->apShm[iChunk]==0 ) return LSM_IOERR_BKPT; 417 } 418 419 *ppShm = p->apShm[iChunk]; 420 return LSM_OK; 421 } 422 423 static void lsmPosixOsShmBarrier(void){ 424 } 425 426 static int lsmPosixOsShmUnmap(lsm_file *pFile, int bDelete){ 427 PosixFile *p = (PosixFile *)pFile; 428 if( p->shmfd>0 ){ 429 int i; 430 for(i=0; i<p->nShm; i++){ 431 if( p->apShm[i] ){ 432 munmap(p->apShm[i], LSM_SHM_CHUNK_SIZE); 433 p->apShm[i] = 0; 434 } 435 } 436 close(p->shmfd); 437 p->shmfd = 0; 438 if( bDelete ){ 439 char *zShm = posixShmFile(p); 440 if( zShm ) unlink(zShm); 441 lsmFree(p->pEnv, zShm); 442 } 443 } 444 return LSM_OK; 445 } 446 447 448 static int lsmPosixOsClose(lsm_file *pFile){ 449 PosixFile *p = (PosixFile *)pFile; 450 lsmPosixOsShmUnmap(pFile, 0); 451 if( p->pMap ) munmap(p->pMap, p->nMap); 452 close(p->fd); 453 lsm_free(p->pEnv, p->apShm); 454 lsm_free(p->pEnv, p); 455 return LSM_OK; 456 } 457 458 static int lsmPosixOsSleep(lsm_env *pEnv, int us){ 459 #if 0 460 /* Apparently on Android usleep() returns void */ 461 if( usleep(us) ) return LSM_IOERR; 462 #endif 463 usleep(us); 464 return LSM_OK; 465 } 466 467 /**************************************************************************** 468 ** Memory allocation routines. 469 */ 470 #define BLOCK_HDR_SIZE ROUND8( sizeof(size_t) ) 471 472 static void *lsmPosixOsMalloc(lsm_env *pEnv, size_t N){ 473 unsigned char * m; 474 N += BLOCK_HDR_SIZE; 475 m = (unsigned char *)malloc(N); 476 *((size_t*)m) = N; 477 return m + BLOCK_HDR_SIZE; 478 } 479 480 static void lsmPosixOsFree(lsm_env *pEnv, void *p){ 481 if(p){ 482 free( ((unsigned char *)p) - BLOCK_HDR_SIZE ); 483 } 484 } 485 486 static void *lsmPosixOsRealloc(lsm_env *pEnv, void *p, size_t N){ 487 unsigned char * m = (unsigned char *)p; 488 if(1>N){ 489 lsmPosixOsFree( pEnv, p ); 490 return NULL; 491 }else if(NULL==p){ 492 return lsmPosixOsMalloc(pEnv, N); 493 }else{ 494 void * re = NULL; 495 m -= BLOCK_HDR_SIZE; 496 #if 0 /* arguable: don't shrink */ 497 size_t * sz = (size_t*)m; 498 if(*sz >= (size_t)N){ 499 return p; 500 } 501 #endif 502 re = realloc( m, N + BLOCK_HDR_SIZE ); 503 if(re){ 504 m = (unsigned char *)re; 505 *((size_t*)m) = N; 506 return m + BLOCK_HDR_SIZE; 507 }else{ 508 return NULL; 509 } 510 } 511 } 512 513 static size_t lsmPosixOsMSize(lsm_env *pEnv, void *p){ 514 unsigned char * m = (unsigned char *)p; 515 return *((size_t*)(m-BLOCK_HDR_SIZE)); 516 } 517 #undef BLOCK_HDR_SIZE 518 519 520 #ifdef LSM_MUTEX_PTHREADS 521 /************************************************************************* 522 ** Mutex methods for pthreads based systems. If LSM_MUTEX_PTHREADS is 523 ** missing then a no-op implementation of mutexes found in lsm_mutex.c 524 ** will be used instead. 525 */ 526 #include <pthread.h> 527 528 typedef struct PthreadMutex PthreadMutex; 529 struct PthreadMutex { 530 lsm_env *pEnv; 531 pthread_mutex_t mutex; 532 #ifdef LSM_DEBUG 533 pthread_t owner; 534 #endif 535 }; 536 537 #ifdef LSM_DEBUG 538 # define LSM_PTHREAD_STATIC_MUTEX { 0, PTHREAD_MUTEX_INITIALIZER, 0 } 539 #else 540 # define LSM_PTHREAD_STATIC_MUTEX { 0, PTHREAD_MUTEX_INITIALIZER } 541 #endif 542 543 static int lsmPosixOsMutexStatic( 544 lsm_env *pEnv, 545 int iMutex, 546 lsm_mutex **ppStatic 547 ){ 548 static PthreadMutex sMutex[2] = { 549 LSM_PTHREAD_STATIC_MUTEX, 550 LSM_PTHREAD_STATIC_MUTEX 551 }; 552 553 assert( iMutex==LSM_MUTEX_GLOBAL || iMutex==LSM_MUTEX_HEAP ); 554 assert( LSM_MUTEX_GLOBAL==1 && LSM_MUTEX_HEAP==2 ); 555 556 *ppStatic = (lsm_mutex *)&sMutex[iMutex-1]; 557 return LSM_OK; 558 } 559 560 static int lsmPosixOsMutexNew(lsm_env *pEnv, lsm_mutex **ppNew){ 561 PthreadMutex *pMutex; /* Pointer to new mutex */ 562 pthread_mutexattr_t attr; /* Attributes object */ 563 564 pMutex = (PthreadMutex *)lsmMallocZero(pEnv, sizeof(PthreadMutex)); 565 if( !pMutex ) return LSM_NOMEM_BKPT; 566 567 pMutex->pEnv = pEnv; 568 pthread_mutexattr_init(&attr); 569 pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE); 570 pthread_mutex_init(&pMutex->mutex, &attr); 571 pthread_mutexattr_destroy(&attr); 572 573 *ppNew = (lsm_mutex *)pMutex; 574 return LSM_OK; 575 } 576 577 static void lsmPosixOsMutexDel(lsm_mutex *p){ 578 PthreadMutex *pMutex = (PthreadMutex *)p; 579 pthread_mutex_destroy(&pMutex->mutex); 580 lsmFree(pMutex->pEnv, pMutex); 581 } 582 583 static void lsmPosixOsMutexEnter(lsm_mutex *p){ 584 PthreadMutex *pMutex = (PthreadMutex *)p; 585 pthread_mutex_lock(&pMutex->mutex); 586 587 #ifdef LSM_DEBUG 588 assert( !pthread_equal(pMutex->owner, pthread_self()) ); 589 pMutex->owner = pthread_self(); 590 assert( pthread_equal(pMutex->owner, pthread_self()) ); 591 #endif 592 } 593 594 static int lsmPosixOsMutexTry(lsm_mutex *p){ 595 int ret; 596 PthreadMutex *pMutex = (PthreadMutex *)p; 597 ret = pthread_mutex_trylock(&pMutex->mutex); 598 #ifdef LSM_DEBUG 599 if( ret==0 ){ 600 assert( !pthread_equal(pMutex->owner, pthread_self()) ); 601 pMutex->owner = pthread_self(); 602 assert( pthread_equal(pMutex->owner, pthread_self()) ); 603 } 604 #endif 605 return ret; 606 } 607 608 static void lsmPosixOsMutexLeave(lsm_mutex *p){ 609 PthreadMutex *pMutex = (PthreadMutex *)p; 610 #ifdef LSM_DEBUG 611 assert( pthread_equal(pMutex->owner, pthread_self()) ); 612 pMutex->owner = 0; 613 assert( !pthread_equal(pMutex->owner, pthread_self()) ); 614 #endif 615 pthread_mutex_unlock(&pMutex->mutex); 616 } 617 618 #ifdef LSM_DEBUG 619 static int lsmPosixOsMutexHeld(lsm_mutex *p){ 620 PthreadMutex *pMutex = (PthreadMutex *)p; 621 return pMutex ? pthread_equal(pMutex->owner, pthread_self()) : 1; 622 } 623 static int lsmPosixOsMutexNotHeld(lsm_mutex *p){ 624 PthreadMutex *pMutex = (PthreadMutex *)p; 625 return pMutex ? !pthread_equal(pMutex->owner, pthread_self()) : 1; 626 } 627 #endif 628 /* 629 ** End of pthreads mutex implementation. 630 *************************************************************************/ 631 #else 632 /************************************************************************* 633 ** Noop mutex implementation 634 */ 635 typedef struct NoopMutex NoopMutex; 636 struct NoopMutex { 637 lsm_env *pEnv; /* Environment handle (for xFree()) */ 638 int bHeld; /* True if mutex is held */ 639 int bStatic; /* True for a static mutex */ 640 }; 641 static NoopMutex aStaticNoopMutex[2] = { 642 {0, 0, 1}, 643 {0, 0, 1}, 644 }; 645 646 static int lsmPosixOsMutexStatic( 647 lsm_env *pEnv, 648 int iMutex, 649 lsm_mutex **ppStatic 650 ){ 651 assert( iMutex>=1 && iMutex<=(int)array_size(aStaticNoopMutex) ); 652 *ppStatic = (lsm_mutex *)&aStaticNoopMutex[iMutex-1]; 653 return LSM_OK; 654 } 655 static int lsmPosixOsMutexNew(lsm_env *pEnv, lsm_mutex **ppNew){ 656 NoopMutex *p; 657 p = (NoopMutex *)lsmMallocZero(pEnv, sizeof(NoopMutex)); 658 if( p ) p->pEnv = pEnv; 659 *ppNew = (lsm_mutex *)p; 660 return (p ? LSM_OK : LSM_NOMEM_BKPT); 661 } 662 static void lsmPosixOsMutexDel(lsm_mutex *pMutex) { 663 NoopMutex *p = (NoopMutex *)pMutex; 664 assert( p->bStatic==0 && p->pEnv ); 665 lsmFree(p->pEnv, p); 666 } 667 static void lsmPosixOsMutexEnter(lsm_mutex *pMutex){ 668 NoopMutex *p = (NoopMutex *)pMutex; 669 assert( p->bHeld==0 ); 670 p->bHeld = 1; 671 } 672 static int lsmPosixOsMutexTry(lsm_mutex *pMutex){ 673 NoopMutex *p = (NoopMutex *)pMutex; 674 assert( p->bHeld==0 ); 675 p->bHeld = 1; 676 return 0; 677 } 678 static void lsmPosixOsMutexLeave(lsm_mutex *pMutex){ 679 NoopMutex *p = (NoopMutex *)pMutex; 680 assert( p->bHeld==1 ); 681 p->bHeld = 0; 682 } 683 #ifdef LSM_DEBUG 684 static int lsmPosixOsMutexHeld(lsm_mutex *pMutex){ 685 NoopMutex *p = (NoopMutex *)pMutex; 686 return p ? p->bHeld : 1; 687 } 688 static int lsmPosixOsMutexNotHeld(lsm_mutex *pMutex){ 689 NoopMutex *p = (NoopMutex *)pMutex; 690 return p ? !p->bHeld : 1; 691 } 692 #endif 693 /***************************************************************************/ 694 #endif /* else LSM_MUTEX_NONE */ 695 696 /* Without LSM_DEBUG, the MutexHeld tests are never called */ 697 #ifndef LSM_DEBUG 698 # define lsmPosixOsMutexHeld 0 699 # define lsmPosixOsMutexNotHeld 0 700 #endif 701 702 lsm_env *lsm_default_env(void){ 703 static lsm_env posix_env = { 704 sizeof(lsm_env), /* nByte */ 705 1, /* iVersion */ 706 /***** file i/o ******************/ 707 0, /* pVfsCtx */ 708 lsmPosixOsFullpath, /* xFullpath */ 709 lsmPosixOsOpen, /* xOpen */ 710 lsmPosixOsRead, /* xRead */ 711 lsmPosixOsWrite, /* xWrite */ 712 lsmPosixOsTruncate, /* xTruncate */ 713 lsmPosixOsSync, /* xSync */ 714 lsmPosixOsSectorSize, /* xSectorSize */ 715 lsmPosixOsRemap, /* xRemap */ 716 lsmPosixOsFileid, /* xFileid */ 717 lsmPosixOsClose, /* xClose */ 718 lsmPosixOsUnlink, /* xUnlink */ 719 lsmPosixOsLock, /* xLock */ 720 lsmPosixOsTestLock, /* xTestLock */ 721 lsmPosixOsShmMap, /* xShmMap */ 722 lsmPosixOsShmBarrier, /* xShmBarrier */ 723 lsmPosixOsShmUnmap, /* xShmUnmap */ 724 /***** memory allocation *********/ 725 0, /* pMemCtx */ 726 lsmPosixOsMalloc, /* xMalloc */ 727 lsmPosixOsRealloc, /* xRealloc */ 728 lsmPosixOsFree, /* xFree */ 729 lsmPosixOsMSize, /* xSize */ 730 /***** mutexes *********************/ 731 0, /* pMutexCtx */ 732 lsmPosixOsMutexStatic, /* xMutexStatic */ 733 lsmPosixOsMutexNew, /* xMutexNew */ 734 lsmPosixOsMutexDel, /* xMutexDel */ 735 lsmPosixOsMutexEnter, /* xMutexEnter */ 736 lsmPosixOsMutexTry, /* xMutexTry */ 737 lsmPosixOsMutexLeave, /* xMutexLeave */ 738 lsmPosixOsMutexHeld, /* xMutexHeld */ 739 lsmPosixOsMutexNotHeld, /* xMutexNotHeld */ 740 /***** other *********************/ 741 lsmPosixOsSleep, /* xSleep */ 742 }; 743 return &posix_env; 744 } 745 746 #endif