]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Fix for lock structure sharing with AFP-style locking
authoradam <adam@noemail.net>
Mon, 9 Nov 2009 19:30:44 +0000 (19:30 +0000)
committeradam <adam@noemail.net>
Mon, 9 Nov 2009 19:30:44 +0000 (19:30 +0000)
FossilOrigin-Name: 62f15c0aeaec5d778addb6edba62411c698bec0f

manifest
manifest.uuid
src/os_unix.c

index 11dc48d52c6b597784bf8fad1b5febb7fd60ddad..2823d88879a7e94cc78b894efa2a0c02f8f6b02d 100644 (file)
--- 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
index 64003ab09bb01421f9a4511ff5c19de131cd2b8d..0b14668256754dc689cedc1fd32a0bd4390236f8 100644 (file)
@@ -1 +1 @@
-9552de8fb5ec7554c989edc138c0324c5fd0a206
\ No newline at end of file
+62f15c0aeaec5d778addb6edba62411c698bec0f
\ No newline at end of file
index 651b1a3f81713890238ce708c97c24e33b49bc66..6075fbe98fc51f6714a1092119961ffaa0c2e579 100644 (file)
@@ -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--;