From: dan Date: Tue, 20 Jul 2021 21:02:43 +0000 (+0000) Subject: Add in-process blocking locks to os_win.c using a similar technique. X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=658c53409f8977e44e0c2cc9376571e3c242f4d8;p=thirdparty%2Fsqlite.git Add in-process blocking locks to os_win.c using a similar technique. FossilOrigin-Name: b67c157fd89f73078e3bf4e3d6e8d77fa59ef1ec5c3a9d0e3af955362d751960 --- diff --git a/manifest b/manifest index 9d5f61c82a..fc55ac6e25 100644 --- 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 diff --git a/manifest.uuid b/manifest.uuid index afa9caead0..0ed099d0a3 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -85fd18d7a2ea96d40fc1d59778ad5eabd0a42f775c417ece183b230eea57a993 \ No newline at end of file +b67c157fd89f73078e3bf4e3d6e8d77fa59ef1ec5c3a9d0e3af955362d751960 \ No newline at end of file diff --git a/src/os_win.c b/src/os_win.c index 2f8a098179..9ee517519a 100644 --- a/src/os_win.c +++ b/src/os_win.c @@ -64,6 +64,12 @@ 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; inRegion; 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<1 || mask==(1<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; }