Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Defer closing file descriptors until all fcntl() locks have been dropped. |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | multi-process |
Files: | files | file ages | folders |
SHA1: |
3d0cf4bb36752812fb3979babe689567 |
User & Date: | dan 2012-09-04 20:17:56.817 |
Context
2012-09-05
| ||
10:32 | Fix a bug in intra-process connection locking. Turn on multi-process mode by default. Leaf check-in: 8d149a52d3 user: dan tags: multi-process | |
2012-09-04
| ||
20:17 | Defer closing file descriptors until all fcntl() locks have been dropped. check-in: 3d0cf4bb36 user: dan tags: multi-process | |
19:42 | Add real inter-process locks and shared memory in place of the stubs. Currently requires activation using LSM_CONFIG_MULTIPLE_PROCESSES. check-in: d37b353a55 user: dan tags: multi-process | |
Changes
Changes to src/lsmInt.h.
︙ | ︙ | |||
156 157 158 159 160 161 162 163 164 165 166 167 168 169 | struct LsmString { lsm_env *pEnv; /* Run-time environment */ int n; /* Size of string. -1 indicates error */ int nAlloc; /* Space allocated for z[] */ char *z; /* The string content */ }; /* ** An instance of the following type is used to store an ordered list of ** u32 values. ** ** Note: This is a place-holder implementation. It should be replaced by ** a version that avoids making a single large allocation when the array ** contains a large number of values. For this reason, the internals of | > > > > > > | 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 | struct LsmString { lsm_env *pEnv; /* Run-time environment */ int n; /* Size of string. -1 indicates error */ int nAlloc; /* Space allocated for z[] */ char *z; /* The string content */ }; typedef struct LsmFile LsmFile; struct LsmFile { lsm_file *pFile; LsmFile *pNext; }; /* ** An instance of the following type is used to store an ordered list of ** u32 values. ** ** Note: This is a place-holder implementation. It should be replaced by ** a version that avoids making a single large allocation when the array ** contains a large number of values. For this reason, the internals of |
︙ | ︙ | |||
783 784 785 786 787 788 789 790 791 792 793 794 795 796 | int lsmReleaseReadlock(lsm_db *); int lsmLsmInUse(lsm_db *db, i64 iLsmId, int *pbInUse); int lsmTreeInUse(lsm_db *db, u32 iLsmId, int *pbInUse); int lsmFreelistAppend(lsm_env *pEnv, Freelist *p, int iBlk, i64 iId); int lsmDbMultiProc(lsm_db *); /************************************************************************** ** functions in lsm_str.c */ void lsmStringInit(LsmString*, lsm_env *pEnv); int lsmStringExtend(LsmString*, int); | > | 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 | int lsmReleaseReadlock(lsm_db *); int lsmLsmInUse(lsm_db *db, i64 iLsmId, int *pbInUse); int lsmTreeInUse(lsm_db *db, u32 iLsmId, int *pbInUse); int lsmFreelistAppend(lsm_env *pEnv, Freelist *p, int iBlk, i64 iId); int lsmDbMultiProc(lsm_db *); void lsmDbDeferredClose(lsm_db *, lsm_file *, LsmFile *); /************************************************************************** ** functions in lsm_str.c */ void lsmStringInit(LsmString*, lsm_env *pEnv); int lsmStringExtend(LsmString*, int); |
︙ | ︙ |
Changes to src/lsm_file.c.
︙ | ︙ | |||
117 118 119 120 121 122 123 124 125 126 127 128 129 130 | char *zDb; /* Database file name */ char *zLog; /* Database file name */ int nMetasize; /* Size of meta pages in bytes */ int nPagesize; /* Database page-size in bytes */ int nBlocksize; /* Database block-size in bytes */ /* r/w file descriptors for both files. */ lsm_file *fdDb; /* Database file */ lsm_file *fdLog; /* Log file */ /* mmap() mode things */ int bUseMmap; /* True to use mmap() to access db file */ void *pMap; /* Current mapping of database file */ i64 nMap; /* Bytes mapped at pMap */ | > | 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 | char *zDb; /* Database file name */ char *zLog; /* Database file name */ int nMetasize; /* Size of meta pages in bytes */ int nPagesize; /* Database page-size in bytes */ int nBlocksize; /* Database block-size in bytes */ /* r/w file descriptors for both files. */ LsmFile *pLsmFile; lsm_file *fdDb; /* Database file */ lsm_file *fdLog; /* Log file */ /* mmap() mode things */ int bUseMmap; /* True to use mmap() to access db file */ void *pMap; /* Current mapping of database file */ i64 nMap; /* Bytes mapped at pMap */ |
︙ | ︙ | |||
394 395 396 397 398 399 400 401 402 403 404 405 406 407 | memcpy(&pFS->zLog[nDb], "-log", 5); /* Allocate the hash-table here. At some point, it should be changed ** so that it can grow dynamicly. */ pFS->nCacheMax = 2048; pFS->nHash = 4096; pFS->apHash = lsmMallocZeroRc(pDb->pEnv, sizeof(Page *) * pFS->nHash, &rc); /* Open the database file */ pFS->fdDb = fsOpenFile(pFS, 0, &rc); if( rc!=LSM_OK ){ lsmFsClose(pFS); pFS = 0; | > | 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 | memcpy(&pFS->zLog[nDb], "-log", 5); /* Allocate the hash-table here. At some point, it should be changed ** so that it can grow dynamicly. */ pFS->nCacheMax = 2048; pFS->nHash = 4096; pFS->apHash = lsmMallocZeroRc(pDb->pEnv, sizeof(Page *) * pFS->nHash, &rc); pFS->pLsmFile = lsmMallocZeroRc(pDb->pEnv, sizeof(LsmFile), &rc); /* Open the database file */ pFS->fdDb = fsOpenFile(pFS, 0, &rc); if( rc!=LSM_OK ){ lsmFsClose(pFS); pFS = 0; |
︙ | ︙ | |||
426 427 428 429 430 431 432 | Page *pNext = pPg->pLruNext; if( pPg->flags & PAGE_FREE ) lsmFree(pEnv, pPg->aData); lsmFree(pEnv, pPg); pPg = pNext; } if( pFS->fdDb ) lsmEnvClose(pFS->pEnv, pFS->fdDb ); | > > > > > | > > > | 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 | Page *pNext = pPg->pLruNext; if( pPg->flags & PAGE_FREE ) lsmFree(pEnv, pPg->aData); lsmFree(pEnv, pPg); pPg = pNext; } if( pFS->fdDb ) lsmEnvClose(pFS->pEnv, pFS->fdDb ); if( pFS->fdLog ){ if( lsmDbMultiProc(pFS->pDb) ){ lsmDbDeferredClose(pFS->pDb, pFS->fdLog, pFS->pLsmFile); pFS->pLsmFile = 0; }else{ lsmEnvClose(pFS->pEnv, pFS->fdLog ); } } lsmFree(pEnv, pFS->pLsmFile); lsmFree(pEnv, pFS->apHash); lsmFree(pEnv, pFS); } } /* |
︙ | ︙ |
Changes to src/lsm_shared.c.
︙ | ︙ | |||
41 42 43 44 45 46 47 48 49 50 51 52 53 54 | void *pId; /* Database id (file inode) */ int nId; /* Size of pId in bytes */ int nDbRef; /* Number of associated lsm_db handles */ Database *pDbNext; /* Next Database structure in global list */ /* Protected by the local mutex (pClientMutex) */ lsm_file *pFile; /* Used for locks/shm in multi-proc mode */ lsm_mutex *pClientMutex; /* Protects the apShmChunk[] and pConn */ int nShmChunk; /* Number of entries in apShmChunk[] array */ void **apShmChunk; /* Array of "shared" memory regions */ lsm_db *pConn; /* List of connections to this db. */ }; /* | > | 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 | void *pId; /* Database id (file inode) */ int nId; /* Size of pId in bytes */ int nDbRef; /* Number of associated lsm_db handles */ Database *pDbNext; /* Next Database structure in global list */ /* Protected by the local mutex (pClientMutex) */ lsm_file *pFile; /* Used for locks/shm in multi-proc mode */ LsmFile *pLsmFile; /* List of deferred closes */ lsm_mutex *pClientMutex; /* Protects the apShmChunk[] and pConn */ int nShmChunk; /* Number of entries in apShmChunk[] array */ void **apShmChunk; /* Array of "shared" memory regions */ lsm_db *pConn; /* List of connections to this db. */ }; /* |
︙ | ︙ | |||
354 355 356 357 358 359 360 | for(ppDb=&p->pConn; *ppDb!=pDb; ppDb=&((*ppDb)->pNext)); *ppDb = pDb->pNext; lsmMutexLeave(pDb->pEnv, p->pClientMutex); enterGlobalMutex(pDb->pEnv); p->nDbRef--; if( p->nDbRef==0 ){ | < > > > > > > > > > | 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 | for(ppDb=&p->pConn; *ppDb!=pDb; ppDb=&((*ppDb)->pNext)); *ppDb = pDb->pNext; lsmMutexLeave(pDb->pEnv, p->pClientMutex); enterGlobalMutex(pDb->pEnv); p->nDbRef--; if( p->nDbRef==0 ){ Database **pp; /* Remove the Database structure from the linked list. */ for(pp=&gShared.pDatabase; *pp!=p; pp=&((*pp)->pDbNext)); *pp = p->pDbNext; /* Free the Database object and shared memory buffers. */ if( p->pFile==0 ){ int i; for(i=0; i<p->nShmChunk; i++){ lsmFree(pDb->pEnv, p->apShmChunk[i]); } }else{ LsmFile *pIter; LsmFile *pNext; for(pIter=p->pLsmFile; pIter; pIter=pNext){ pNext = pIter->pNext; lsmEnvClose(pDb->pEnv, pIter->pFile); lsmFree(pDb->pEnv, pIter); } } lsmFree(pDb->pEnv, p->apShmChunk); freeDatabase(pDb->pEnv, p); } leaveGlobalMutex(pDb->pEnv); } } |
︙ | ︙ | |||
873 874 875 876 877 878 879 | /* ** This function may only be called after a successful call to ** lsmDbDatabaseConnect(). It returns true if the connection is in ** multi-process mode, or false otherwise. */ int lsmDbMultiProc(lsm_db *pDb){ | | > > > > > > > > > > > | 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 | /* ** This function may only be called after a successful call to ** lsmDbDatabaseConnect(). It returns true if the connection is in ** multi-process mode, or false otherwise. */ int lsmDbMultiProc(lsm_db *pDb){ return pDb->pDatabase && (pDb->pDatabase->pFile!=0); } void lsmDbDeferredClose(lsm_db *pDb, lsm_file *pFile, LsmFile *pLsmFile){ Database *p = pDb->pDatabase; lsm_env *pEnv = pDb->pEnv; lsmMutexEnter(pEnv, p->pClientMutex); pLsmFile->pFile = pFile; pLsmFile->pNext = p->pLsmFile; p->pLsmFile = pLsmFile; lsmMutexLeave(pEnv, p->pClientMutex); } /************************************************************************* ************************************************************************** ************************************************************************** ************************************************************************** |
︙ | ︙ |