]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Stop requiring the global VFS mutex to access the unixInodeInfo.pUnused field.
authordrh <drh@noemail.net>
Mon, 13 Aug 2018 22:50:34 +0000 (22:50 +0000)
committerdrh <drh@noemail.net>
Mon, 13 Aug 2018 22:50:34 +0000 (22:50 +0000)
The unixInodeInfo mutex is sufficient.

FossilOrigin-Name: e3ea43dabf099dc2954c23d348638e7b2a8b9122d2994154bc649a2c09260c46

manifest
manifest.uuid
src/os_unix.c

index 894fda23ab87f149dae1fe90966db316401e1ab8..09410ced16a90dd6b6ba0e8fce9ccfc239e9c3ef 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Take\sextra\sprecautions\sto\sensure\saccess\sto\sunixInodeInfo.pUnused\sis\sprotected\nby\sall\snecessary\smutexes.
-D 2018-08-13T20:46:18.212
+C Stop\srequiring\sthe\sglobal\sVFS\smutex\sto\saccess\sthe\sunixInodeInfo.pUnused\sfield.\nThe\sunixInodeInfo\smutex\sis\ssufficient.
+D 2018-08-13T22:50:34.627
 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
 F Makefile.in 0a3a6c81e6fcb969ff9106e882f0a08547014ba463cb6beca4c4efaecc924ee6
@@ -482,7 +482,7 @@ F src/os.c 8aeb0b0f40f8f5b0da03fe49706695adaf42d2f516ab95abc72e86c245e119de
 F src/os.h 48388821692e87da174ea198bf96b1b2d9d83be5dfc908f673ee21fafbe0d432
 F src/os_common.h b2f4707a603e36811d9b1a13278bffd757857b85
 F src/os_setup.h 0dbaea40a7d36bf311613d31342e0b99e2536586
-F src/os_unix.c 443f6331828b9d0d05f9528a2ae30d927ab988a951ea783dc85538dc9109d489
+F src/os_unix.c e681b2a3ab1085be3eb2e81254449782ca0bd0c38b73c48cb0c2480b8f2f25b9
 F src/os_win.c 070cdbb400097c6cda54aa005356095afdc2f3ee691d17192c54724ef146a971
 F src/os_win.h 7b073010f1451abe501be30d12f6bc599824944a
 F src/pager.c 76d29b8a960dcb8b67210f095899d91e4a90673a6674ea58cfd1115b705a7fb9
@@ -1754,7 +1754,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93
 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
 F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
 F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
-P 90f7c193b42f0d8120a8e429bdea5e1cec5d3f45b901db8fc5a5c2ca3e69cba8
-R de3b1179403c76c7e851316aaadc94be
+P 8b1e0010b9e0b548a90087f4d25843d2b40f7e9551722ac587fa925d37b510c2
+R c0b44ea86365eec38ab4ca860c436c2d
 U drh
-Z 4ac850f8e532f34d7b8e835a0f2cfeb4
+Z 61c21fbc1d363c0a3fe7befb1f84f230
index 5db1a564ffff77443253fb472fe8ade117a93768..2e68ed46d5db19e0d9d87e6fdb1aefc065a27f16 100644 (file)
@@ -1 +1 @@
-8b1e0010b9e0b548a90087f4d25843d2b40f7e9551722ac587fa925d37b510c2
\ No newline at end of file
+e3ea43dabf099dc2954c23d348638e7b2a8b9122d2994154bc649a2c09260c46
\ No newline at end of file
index 5a2b6b523a5a7701bc624114fcc30d4c7d08a729..ab0a5d919a78a6d5a5dc925139b65927ce602abc 100644 (file)
@@ -1126,17 +1126,13 @@ struct unixFileId {
 **
 **  (1) Only the pLockMutex mutex must be held in order to read or write
 **      any of the locking fields:
-**          nShared, nLock, eFileLock, or bProcessLock
+**          nShared, nLock, eFileLock, bProcessLock, pUnused
 **
 **  (2) When nRef>0, then the following fields are unchanging and can
 **      be read (but not written) without holding any mutex:
 **          fileId, pLockMutex
 **
-**  (3) The pUnused field may only be changed while holding bo the
-**      pLockMutex and the bigUnixLock mutex.  But it may be read
-**      while holding either.
-**
-**  (4) With the exceptions above, all the fields may only be read
+**  (3) With the exceptions above, all the fields may only be read
 **      or written while holding the global unixBigLock mutex.
 **
 ** Deadlock prevention:  The global unixBigLock mutex may not
@@ -1150,7 +1146,7 @@ struct unixInodeInfo {
   int nLock;                        /* Number of outstanding file locks */
   unsigned char eFileLock;          /* One of SHARED_LOCK, RESERVED_LOCK etc. */
   unsigned char bProcessLock;       /* An exclusive process lock is held */
-  UnixUnusedFd *pUnused;          /* Unused file descriptors to close */
+  UnixUnusedFd *pUnused;            /* Unused file descriptors to close */
   int nRef;                       /* Number of pointers to this structure */
   unixShmNode *pShmNode;          /* Shared memory associated with this inode */
   unixInodeInfo *pNext;           /* List of all unixInodeInfo objects */
@@ -1288,16 +1284,13 @@ static void closePendingFds(unixFile *pFile){
   unixInodeInfo *pInode = pFile->pInode;
   UnixUnusedFd *p;
   UnixUnusedFd *pNext;
-  assert( unixMutexHeld() );
-  assert( unixFileMutexNotheld(pFile) );
-  sqlite3_mutex_enter(pInode->pLockMutex);
+  assert( unixFileMutexHeld(pFile) );
   for(p=pInode->pUnused; p; p=pNext){
     pNext = p->pNext;
     robust_close(pFile, p->fd, __LINE__);
     sqlite3_free(p);
   }
   pInode->pUnused = 0;
-  sqlite3_mutex_leave(pInode->pLockMutex);
 }
 
 /*
@@ -1314,7 +1307,9 @@ static void releaseInodeInfo(unixFile *pFile){
     pInode->nRef--;
     if( pInode->nRef==0 ){
       assert( pInode->pShmNode==0 );
+      sqlite3_mutex_enter(pInode->pLockMutex);
       closePendingFds(pFile);
+      sqlite3_mutex_leave(pInode->pLockMutex);
       if( pInode->pPrev ){
         assert( pInode->pPrev->pNext==pInode );
         pInode->pPrev->pNext = pInode->pNext;
@@ -1863,12 +1858,9 @@ end_lock:
 static void setPendingFd(unixFile *pFile){
   unixInodeInfo *pInode = pFile->pInode;
   UnixUnusedFd *p = pFile->pPreallocatedUnused;
-  assert( unixMutexHeld() );
-  assert( unixFileMutexNotheld(pFile) );
-  sqlite3_mutex_enter(pInode->pLockMutex);
+  assert( unixFileMutexHeld(pFile) );
   p->pNext = pInode->pUnused;
   pInode->pUnused = p;
-  sqlite3_mutex_leave(pInode->pLockMutex);
   pFile->h = -1;
   pFile->pPreallocatedUnused = 0;
 }
@@ -1891,7 +1883,6 @@ static int posixUnlock(sqlite3_file *id, int eFileLock, int handleNFSUnlock){
   unixInodeInfo *pInode;
   struct flock lock;
   int rc = SQLITE_OK;
-  int wantToClosePending = 0;  /* True to try to close file old descriptors */
 
   assert( pFile );
   OSTRACE(("UNLOCK  %d %d was %d(%d,%d) pid=%d (unix)\n", pFile->h, eFileLock,
@@ -2029,20 +2020,13 @@ static int posixUnlock(sqlite3_file *id, int eFileLock, int handleNFSUnlock){
     */
     pInode->nLock--;
     assert( pInode->nLock>=0 );
-    if( pInode->nLock==0 && pInode->pUnused!=0 ){
-      wantToClosePending = 1;
-    }
+    if( pInode->nLock==0 ) closePendingFds(pFile);
   }
 
 end_unlock:
   sqlite3_mutex_leave(pInode->pLockMutex);
   if( rc==SQLITE_OK ){
     pFile->eFileLock = eFileLock;
-    if( wantToClosePending ){
-      unixEnterMutex();
-      if( pInode->nLock==0 ) closePendingFds(pFile);
-      unixLeaveMutex();
-    }
   }
   return rc;
 }
@@ -2114,6 +2098,9 @@ static int closeUnixFile(sqlite3_file *id){
 static int unixClose(sqlite3_file *id){
   int rc = SQLITE_OK;
   unixFile *pFile = (unixFile *)id;
+  unixInodeInfo *pInode = pFile->pInode;
+
+  assert( pInode!=0 );
   verifyDbFile(pFile);
   unixUnlock(id, NO_LOCK);
   assert( unixFileMutexNotheld(pFile) );
@@ -2123,7 +2110,8 @@ static int unixClose(sqlite3_file *id){
   ** routine (e.g. nolockClose()) would be called instead.
   */
   assert( pFile->pInode->nLock>0 || pFile->pInode->bProcessLock==0 );
-  if( ALWAYS(pFile->pInode) && pFile->pInode->nLock ){
+  sqlite3_mutex_enter(pInode->pLockMutex);
+  if( pFile->pInode->nLock ){
     /* If there are outstanding locks, do not actually close the file just
     ** yet because that would clear those locks.  Instead, add the file
     ** descriptor to pInode->pUnused list.  It will be automatically closed 
@@ -2131,6 +2119,7 @@ static int unixClose(sqlite3_file *id){
     */
     setPendingFd(pFile);
   }
+  sqlite3_mutex_leave(pInode->pLockMutex);
   releaseInodeInfo(pFile);
   rc = closeUnixFile(id);
   unixLeaveMutex();
@@ -3086,7 +3075,6 @@ static int afpUnlock(sqlite3_file *id, int eFileLock) {
   unixInodeInfo *pInode;
   afpLockingContext *context = (afpLockingContext *) pFile->lockingContext;
   int skipShared = 0;
-  int wantToClosePending = 0;
 #ifdef SQLITE_TEST
   int h = pFile->h;
 #endif
@@ -3170,18 +3158,13 @@ static int afpUnlock(sqlite3_file *id, int eFileLock) {
     if( rc==SQLITE_OK ){
       pInode->nLock--;
       assert( pInode->nLock>=0 );
-      if( pInode->nLock==0 && pInode->pUnused!=0 ) wantToClosePending = 1;
+      if( pInode->nLock==0 ) closePendingFds(pFile);
     }
   }
   
   sqlite3_mutex_leave(pInode->pLockMutex);
   if( rc==SQLITE_OK ){
     pFile->eFileLock = eFileLock;
-    if( wantToClosePending ){
-      unixEnterMutex();
-      if( pInode->nLock==0 ) closePendingFds(pFile);
-      unixLeaveMutex();
-    }
   }
   return rc;
 }
@@ -3196,13 +3179,18 @@ static int afpClose(sqlite3_file *id) {
   afpUnlock(id, NO_LOCK);
   assert( unixFileMutexNotheld(pFile) );
   unixEnterMutex();
-  if( pFile->pInode && pFile->pInode->nLock ){
-    /* If there are outstanding locks, do not actually close the file just
-    ** yet because that would clear those locks.  Instead, add the file
-    ** descriptor to pInode->aPending.  It will be automatically closed when
-    ** the last lock is cleared.
-    */
-    setPendingFd(pFile);
+  if( pFile->pInode ){
+    unixInodeInfo *pInode = pFile->pInode;
+    sqlite3_mutex_enter(pInode->pLockMutex);
+    if( pFile->pInode->nLock ){
+      /* If there are outstanding locks, do not actually close the file just
+      ** yet because that would clear those locks.  Instead, add the file
+      ** descriptor to pInode->aPending.  It will be automatically closed when
+      ** the last lock is cleared.
+      */
+      setPendingFd(pFile);
+    }
+    sqlite3_mutex_leave(pInode->pLockMutex);
   }
   releaseInodeInfo(pFile);
   sqlite3_free(pFile->lockingContext);