]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Add in-process blocking locks to os_win.c using a similar technique.
authordan <Dan Kennedy>
Tue, 20 Jul 2021 21:02:43 +0000 (21:02 +0000)
committerdan <Dan Kennedy>
Tue, 20 Jul 2021 21:02:43 +0000 (21:02 +0000)
FossilOrigin-Name: b67c157fd89f73078e3bf4e3d6e8d77fa59ef1ec5c3a9d0e3af955362d751960

manifest
manifest.uuid
src/os_win.c

index 9d5f61c82a9243c30eb3f903eba961102de710d5..fc55ac6e25765a22cf07c0c8bb757cd662374245 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Merge\schanges\sfrom\sthe\swin-blocking-locks\sbranch\sinto\sthis\sone.
-D 2021-07-20T17:23:02.039
+C Add\sin-process\sblocking\slocks\sto\sos_win.c\susing\sa\ssimilar\stechnique.
+D 2021-07-20T21:02:43.412
 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
 F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
@@ -529,7 +529,7 @@ F src/os.h 26890f540b475598cd9881dcc68931377b8d429d3ea3e2eeb64470cde64199f8
 F src/os_common.h b2f4707a603e36811d9b1a13278bffd757857b85
 F src/os_setup.h 0dbaea40a7d36bf311613d31342e0b99e2536586
 F src/os_unix.c aea96704db0860b61ad95272bd9cb3fc3a4910e6d68506cc6c48d5d8f7922d0b
-F src/os_win.c f1727066bfbf4c3a4308442a6b43699e2cb3fe8905e29c0f4cb73f402d04a184
+F src/os_win.c 03017ffbfa230d833421667a02edca8baab76ff8446533e796206a04c618b2d6
 F src/os_win.h 7b073010f1451abe501be30d12f6bc599824944a
 F src/pager.c 95c255256b13827caf038c8f963d334784073f38ab6ef9d70371d9d04f3c43e0
 F src/pager.h 4bf9b3213a4b2bebbced5eaa8b219cf25d4a82f385d093cd64b7e93e5285f66f
@@ -1920,7 +1920,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 952b4cae49cc6872e6e6075eeaca46506170377237ab74884cefd144bb52c743 3249a6a38d9c86d45d5d04b32d552f306d12fd4d3c94d2efed192104c0c3948a
-R 42718b88d29a1380262773ee0259a1be
+P 85fd18d7a2ea96d40fc1d59778ad5eabd0a42f775c417ece183b230eea57a993
+R 86dd5c706e5b2d8a1aff71102b4d56d3
 U dan
-Z 6d0b04621fe7742f4e6ae70108d87665
+Z e4f62272e7587bffc54dda28167a17c7
index afa9caead094af39b72e35978787bb68c8e6bd3e..0ed099d0a3582b015939497f10d807e159aed94e 100644 (file)
@@ -1 +1 @@
-85fd18d7a2ea96d40fc1d59778ad5eabd0a42f775c417ece183b230eea57a993
\ No newline at end of file
+b67c157fd89f73078e3bf4e3d6e8d77fa59ef1ec5c3a9d0e3af955362d751960
\ No newline at end of file
index 2f8a098179664ff8c7f11295ac009f4cfa61ca27..9ee517519a0dd138a24641f88d4d2107e629763c 100644 (file)
  must be defined."
 #endif
 
+/*
+** Define this symbol to enable blocking in-process locks if the
+** core is built with SQLITE_ENABLE_SETLK_TIMEOUT.
+*/
+#define SQLITE_WIN32_LOCKTMOUT 1
+
 /*
 ** Define the required Windows SDK version constants if they are not
 ** already available.
@@ -3766,7 +3772,12 @@ static int winShmMutexHeld(void) {
 **
 */
 struct winShmNode {
+#ifdef SQLITE_WIN32_LOCKTMOUT
+  CRITICAL_SECTION winMutex;
+  CONDITION_VARIABLE winCond;
+#else
   sqlite3_mutex *mutex;      /* Mutex to access this object */
+#endif
   char *zFilename;           /* Name of the file */
   winFile hFile;             /* File handle from winOpen */
 
@@ -3789,6 +3800,14 @@ struct winShmNode {
 #endif
 };
 
+#ifdef SQLITE_WIN32_LOCKTMOUT
+# define ENTER_SHMNODE_MUTEX(p) EnterCriticalSection(&(p)->winMutex)
+# define LEAVE_SHMNODE_MUTEX(p) LeaveCriticalSection(&(p)->winMutex)
+#else
+# define ENTER_SHMNODE_MUTEX(p) sqlite3_mutex_enter(pShmNode->mutex)
+# define LEAVE_SHMNODE_MUTEX(p) sqlite3_mutex_leave(pShmNode->mutex)
+#endif
+
 /*
 ** A global array of all winShmNode objects.
 **
@@ -4019,7 +4038,11 @@ static void winShmPurge(sqlite3_vfs *pVfs, int deleteFlag){
   while( (p = *pp)!=0 ){
     if( p->nRef==0 ){
       int i;
+#ifdef SQLITE_WIN32_LOCKTMOUT
+      DeleteCriticalSection(&p->winMutex);
+#else
       if( p->mutex ){ sqlite3_mutex_free(p->mutex); }
+#endif
       for(i=0; i<p->nRegion; i++){
         BOOL bRc = osUnmapViewOfFile(p->aRegion[i].pMap);
         OSTRACE(("SHM-PURGE-UNMAP pid=%lu, region=%d, rc=%s\n",
@@ -4139,11 +4162,16 @@ static int winOpenSharedMemory(winFile *pDbFd){
     winShmNodeList = pShmNode;
 
     if( sqlite3GlobalConfig.bCoreMutex ){
+#ifdef SQLITE_WIN32_LOCKTMOUT
+      InitializeCriticalSection(&pShmNode->winMutex);
+      InitializeConditionVariable(&pShmNode->winCond);
+#else
       pShmNode->mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_FAST);
       if( pShmNode->mutex==0 ){
         rc = SQLITE_IOERR_NOMEM_BKPT;
         goto shm_open_err;
       }
+#endif
     }
 
     if( 0==sqlite3_uri_boolean(pDbFd->zPath, "readonly_shm", 0) ){
@@ -4181,10 +4209,10 @@ static int winOpenSharedMemory(winFile *pDbFd){
   ** at pShmNode->pFirst. This must be done while holding the pShmNode->mutex
   ** mutex.
   */
-  sqlite3_mutex_enter(pShmNode->mutex);
+  ENTER_SHMNODE_MUTEX(pShmNode);
   p->pNext = pShmNode->pFirst;
   pShmNode->pFirst = p;
-  sqlite3_mutex_leave(pShmNode->mutex);
+  LEAVE_SHMNODE_MUTEX(pShmNode);
   return rc;
 
   /* Jump here on any error */
@@ -4217,14 +4245,14 @@ static int winShmUnmap(
 
   /* Remove connection p from the set of connections associated
   ** with pShmNode */
-  sqlite3_mutex_enter(pShmNode->mutex);
+  ENTER_SHMNODE_MUTEX(pShmNode);
   for(pp=&pShmNode->pFirst; (*pp)!=p; pp = &(*pp)->pNext){}
   *pp = p->pNext;
 
   /* Free the connection p */
   sqlite3_free(p);
   pDbFd->pShm = 0;
-  sqlite3_mutex_leave(pShmNode->mutex);
+  LEAVE_SHMNODE_MUTEX(pShmNode);
 
   /* If pShmNode->nRef has reached 0, then close the underlying
   ** shared-memory file, too */
@@ -4254,6 +4282,10 @@ static int winShmLock(
   winShmNode *pShmNode = p->pShmNode;
   int rc = SQLITE_OK;                   /* Result code */
   u16 mask;                             /* Mask of locks to take or release */
+#ifdef SQLITE_WIN32_LOCKTMOUT
+  i64 iTimeout = 0;
+  int bRetry;
+#endif
 
   assert( ofst>=0 && ofst+n<=SQLITE_SHM_NLOCK );
   assert( n>=1 );
@@ -4265,8 +4297,14 @@ static int winShmLock(
 
   mask = (u16)((1U<<(ofst+n)) - (1U<<ofst));
   assert( n>1 || mask==(1<<ofst) );
-  sqlite3_mutex_enter(pShmNode->mutex);
+  ENTER_SHMNODE_MUTEX(pShmNode);
   pShmNode->hFile.iBusyTimeout = pDbFd->iBusyTimeout;
+
+#ifdef SQLITE_WIN32_LOCKTMOUT
+  do{
+    bRetry = 0;
+#endif
+
   if( flags & SQLITE_SHM_UNLOCK ){
     u16 allMask = 0; /* Mask of locks held by siblings */
 
@@ -4288,6 +4326,9 @@ static int winShmLock(
     if( rc==SQLITE_OK ){
       p->exclMask &= ~mask;
       p->sharedMask &= ~mask;
+#ifdef SQLITE_WIN32_LOCKTMOUT
+      WakeAllConditionVariable(&pShmNode->winCond);
+#endif
     }
   }else if( flags & SQLITE_SHM_SHARED ){
     u16 allShared = 0;  /* Union of locks held by connections other than "p" */
@@ -4299,6 +4340,9 @@ static int winShmLock(
     for(pX=pShmNode->pFirst; pX; pX=pX->pNext){
       if( (pX->exclMask & mask)!=0 ){
         rc = SQLITE_BUSY;
+#ifdef SQLITE_WIN32_LOCKTMOUT
+        bRetry = (pDbFd->iBusyTimeout!=0);
+#endif
         break;
       }
       allShared |= pX->sharedMask;
@@ -4324,6 +4368,9 @@ static int winShmLock(
     for(pX=pShmNode->pFirst; pX; pX=pX->pNext){
       if( (pX->exclMask & mask)!=0 || (pX->sharedMask & mask)!=0 ){
         rc = SQLITE_BUSY;
+#ifdef SQLITE_WIN32_LOCKTMOUT
+        bRetry = (pDbFd->iBusyTimeout!=0);
+#endif
         break;
       }
     }
@@ -4339,7 +4386,26 @@ static int winShmLock(
       }
     }
   }
-  sqlite3_mutex_leave(pShmNode->mutex);
+
+#ifdef SQLITE_WIN32_LOCKTMOUT
+    if( bRetry ){
+      i64 iMs;
+      if( iTimeout==0 ){
+        pDbFd->pVfs->xCurrentTimeInt64(pDbFd->pVfs, &iTimeout);
+        iTimeout += pDbFd->iBusyTimeout;
+        iMs = pDbFd->iBusyTimeout;
+      }else{
+        pDbFd->pVfs->xCurrentTimeInt64(pDbFd->pVfs, &iMs);
+        iMs -= iTimeout;
+      }
+      bRetry = (int)SleepConditionVariableCS(
+          &pShmNode->winCond, &pShmNode->winMutex, iMs
+      );
+    }
+  }while( bRetry );
+#endif
+
+  LEAVE_SHMNODE_MUTEX(pShmNode);
   OSTRACE(("SHM-LOCK pid=%lu, id=%d, sharedMask=%03x, exclMask=%03x, rc=%s\n",
            osGetCurrentProcessId(), p->id, p->sharedMask, p->exclMask,
            sqlite3ErrName(rc)));
@@ -4402,7 +4468,7 @@ static int winShmMap(
   }
   pShmNode = pShm->pShmNode;
 
-  sqlite3_mutex_enter(pShmNode->mutex);
+  ENTER_SHMNODE_MUTEX(pShmNode);
   if( pShmNode->isUnlocked ){
     rc = winLockSharedMemory(pShmNode);
     if( rc!=SQLITE_OK ) goto shmpage_out;
@@ -4519,7 +4585,7 @@ shmpage_out:
     *pp = 0;
   }
   if( pShmNode->isReadonly && rc==SQLITE_OK ) rc = SQLITE_READONLY;
-  sqlite3_mutex_leave(pShmNode->mutex);
+  LEAVE_SHMNODE_MUTEX(pShmNode);
   return rc;
 }