From ac0c39980ab27749cc66662b4440565ea06ecc19 Mon Sep 17 00:00:00 2001 From: adam Date: Mon, 9 Nov 2009 19:30:44 +0000 Subject: [PATCH] Fix for lock structure sharing with AFP-style locking FossilOrigin-Name: 62f15c0aeaec5d778addb6edba62411c698bec0f --- manifest | 24 +++++++----------------- manifest.uuid | 2 +- src/os_unix.c | 40 ++++++++++++++++++++++++---------------- 3 files changed, 32 insertions(+), 34 deletions(-) diff --git a/manifest b/manifest index 11dc48d52c..2823d88879 100644 --- a/manifest +++ b/manifest @@ -1,8 +1,5 @@ ------BEGIN PGP SIGNED MESSAGE----- -Hash: SHA1 - -C Fix\san\sundefined\svariable\son\snon-Mac\sbuilds. -D 2009-11-05T18:31:56 +C Fix\sfor\slock\sstructure\ssharing\swith\sAFP-style\slocking +D 2009-11-09T19:30:44 F Makefile.arm-wince-mingw32ce-gcc fcd5e9cd67fe88836360bb4f9ef4cb7f8e2fb5a0 F Makefile.in 3400e494a10756968f8fcd8c3d553d279a063436 F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654 @@ -152,7 +149,7 @@ F src/os.c 8d62d8d98ad7909cb0dd294c1e5f3835c887ccb6 F src/os.h 00a1334a4eecee7f7bef79ac606b88d325119f21 F src/os_common.h 8c61457df58f1a4bd5f5adc3e90e01b37bf7afbc F src/os_os2.c bed77dc26e3a95ce4a204936b9a1ca6fe612fcc5 -F src/os_unix.c 1d06b265ff2de6ed97c12bf720a02877c2b2053f +F src/os_unix.c 6b74fa8300c2db55a143155371405ab49ae6afdf F src/os_win.c 5ffab20249a61e0625f869efe157fa009747039b F src/pager.c 729f73feeb33355ae1f0982a74f112ce190c74aa F src/pager.h 11852d044c86cf5a9d6e34171fb0c4fcf1f6265f @@ -768,14 +765,7 @@ F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224 F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f -P 941a01eb868815f566539e9ab21f807d9e798e40 -R d9c03bbaac32722b9588636aff9e886a -U drh -Z 8da6d73402e146bcaf41213dc98262d4 ------BEGIN PGP SIGNATURE----- -Version: GnuPG v1.4.6 (GNU/Linux) - -iD8DBQFK8xokoxKgR168RlERAqwWAJ0clMuAq3A66EFFkJvY8xLRuesiHACffaNk -SLV0EJK8N4eFsQ/98U9xm5I= -=SqO5 ------END PGP SIGNATURE----- +P 9552de8fb5ec7554c989edc138c0324c5fd0a206 +R c261e4bb35de3147ded75b7a34bb1974 +U adam +Z 70f10dd51ab98fc01c03c41ffe1c04c0 diff --git a/manifest.uuid b/manifest.uuid index 64003ab09b..0b14668256 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -9552de8fb5ec7554c989edc138c0324c5fd0a206 \ No newline at end of file +62f15c0aeaec5d778addb6edba62411c698bec0f \ No newline at end of file diff --git a/src/os_unix.c b/src/os_unix.c index 651b1a3f81..6075fbe98f 100644 --- a/src/os_unix.c +++ b/src/os_unix.c @@ -757,6 +757,9 @@ struct unixLockInfo { int cnt; /* Number of SHARED locks held */ int locktype; /* One of SHARED_LOCK, RESERVED_LOCK etc. */ int nRef; /* Number of pointers to this structure */ +#if defined(SQLITE_ENABLE_LOCKING_STYLE) + unsigned long long sharedByte; /* for AFP simulated shared lock */ +#endif struct unixLockInfo *pNext; /* List of all unixLockInfo objects */ struct unixLockInfo *pPrev; /* .... doubly linked */ }; @@ -1043,6 +1046,9 @@ static int findLockInfo( pLock->nRef = 1; pLock->cnt = 0; pLock->locktype = 0; +#if defined(SQLITE_ENABLE_LOCKING_STYLE) + pLock->sharedByte = 0; +#endif pLock->pNext = lockList; pLock->pPrev = 0; if( lockList ) lockList->pPrev = pLock; @@ -2443,7 +2449,6 @@ static int semClose(sqlite3_file *id) { */ typedef struct afpLockingContext afpLockingContext; struct afpLockingContext { - unsigned long long sharedByte; int reserved; const char *dbPath; /* Name of the open file */ }; @@ -2678,9 +2683,9 @@ static int afpLock(sqlite3_file *id, int locktype){ /* Now get the read-lock SHARED_LOCK */ /* note that the quality of the randomness doesn't matter that much */ lk = random(); - context->sharedByte = (lk & mask)%(SHARED_SIZE - 1); + pLock->sharedByte = (lk & mask)%(SHARED_SIZE - 1); lrc1 = afpSetLock(context->dbPath, pFile, - SHARED_FIRST+context->sharedByte, 1, 1); + SHARED_FIRST+pLock->sharedByte, 1, 1); if( IS_LOCK_ERROR(lrc1) ){ lrc1Errno = pFile->lastErrno; } @@ -2726,13 +2731,13 @@ static int afpLock(sqlite3_file *id, int locktype){ ** reestablish the shared lock if we can't get the afpUnlock */ if( !(failed = afpSetLock(context->dbPath, pFile, SHARED_FIRST + - context->sharedByte, 1, 0)) ){ + pLock->sharedByte, 1, 0)) ){ int failed2 = SQLITE_OK; /* now attemmpt to get the exclusive lock range */ failed = afpSetLock(context->dbPath, pFile, SHARED_FIRST, SHARED_SIZE, 1); if( failed && (failed2 = afpSetLock(context->dbPath, pFile, - SHARED_FIRST + context->sharedByte, 1, 1)) ){ + SHARED_FIRST + pLock->sharedByte, 1, 1)) ){ /* Can't reestablish the shared lock. Sqlite can't deal, this is ** a critical I/O error */ @@ -2776,6 +2781,7 @@ static int afpUnlock(sqlite3_file *id, int locktype) { unixFile *pFile = (unixFile*)id; struct unixLockInfo *pLock; afpLockingContext *context = (afpLockingContext *) pFile->lockingContext; + int skipShared = 0; #ifdef SQLITE_TEST int h = pFile->h; #endif @@ -2817,10 +2823,12 @@ static int afpUnlock(sqlite3_file *id, int locktype) { if( pFile->locktype==EXCLUSIVE_LOCK ){ rc = afpSetLock(context->dbPath, pFile, SHARED_FIRST, SHARED_SIZE, 0); - if( rc==SQLITE_OK && locktype==SHARED_LOCK ){ + if( rc==SQLITE_OK && (locktype==SHARED_LOCK || pLock->cnt>1) ){ /* only re-establish the shared lock if necessary */ - int sharedLockByte = SHARED_FIRST+context->sharedByte; + int sharedLockByte = SHARED_FIRST+pLock->sharedByte; rc = afpSetLock(context->dbPath, pFile, sharedLockByte, 1, 1); + } else { + skipShared = 1; } } if( rc==SQLITE_OK && pFile->locktype>=PENDING_LOCK ){ @@ -2832,31 +2840,31 @@ static int afpUnlock(sqlite3_file *id, int locktype) { context->reserved = 0; } } - if( rc==SQLITE_OK && locktype==SHARED_LOCK){ + if( rc==SQLITE_OK && (locktype==SHARED_LOCK || pLock->cnt>1)){ pLock->locktype = SHARED_LOCK; } - }else if( locktype==NO_LOCK ){ + } + if( rc==SQLITE_OK && locktype==NO_LOCK ){ /* Decrement the shared lock counter. Release the lock using an ** OS call only when all threads in this same process have released ** the lock. */ - int sharedLockByte = SHARED_FIRST+context->sharedByte; + unsigned long long sharedLockByte = SHARED_FIRST+pLock->sharedByte; pLock->cnt--; if( pLock->cnt==0 ){ SimulateIOErrorBenign(1); SimulateIOError( h=(-1) ) SimulateIOErrorBenign(0); - rc = afpSetLock(context->dbPath, pFile, sharedLockByte, 1, 0); - pLock->locktype = NO_LOCK; + if( !skipShared ){ + rc = afpSetLock(context->dbPath, pFile, sharedLockByte, 1, 0); + } if( !rc ){ + pLock->locktype = NO_LOCK; pFile->locktype = NO_LOCK; } } - } - - if( rc==SQLITE_OK ){ - if( locktype==NO_LOCK ){ + if( rc==SQLITE_OK ){ struct unixOpenCnt *pOpen = pFile->pOpen; pOpen->nLock--; -- 2.47.3