SQLite

Check-in [a82a9bea62]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:In LSM, avoid calling the VFS xTestLock method to test for a lock that conflicts with one held by the same process. The results of such a call are considered undefined (since they are different under win32 and posix).
Downloads: Tarball | ZIP archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: a82a9bea624caf6b24d8e3f3c596817968b258f06e54288022f6df8226281057
User & Date: dan 2017-07-10 18:33:41.229
Context
2017-07-10
18:52
Updates to the repository README.md file. (check-in: 7bfd3ab799 user: drh tags: trunk)
18:33
In LSM, avoid calling the VFS xTestLock method to test for a lock that conflicts with one held by the same process. The results of such a call are considered undefined (since they are different under win32 and posix). (check-in: a82a9bea62 user: dan tags: trunk)
18:04
Add the "--newlines" option to the ".dump" command in the shell to disable the newline escaping mechanism. (check-in: bde431b1e3 user: drh tags: trunk)
Changes
Side-by-Side Diff Ignore Whitespace Patch
Changes to ext/lsm1/lsm_shared.c.
248
249
250
251
252
253
254


255
256
257
258
259
260
261
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263







+
+







  if( pDb->bReadonly ){
    lsmShmLock(pDb, LSM_LOCK_DMS3, LSM_LOCK_UNLOCK, 0);
  }else{
    /* Block for an exclusive lock on DMS1. This lock serializes all calls
    ** to doDbConnect() and doDbDisconnect() across all processes.  */
    rc = lsmShmLock(pDb, LSM_LOCK_DMS1, LSM_LOCK_EXCL, 1);
    if( rc==LSM_OK ){

      lsmShmLock(pDb, LSM_LOCK_DMS2, LSM_LOCK_UNLOCK, 0);

      /* Try an exclusive lock on DMS2. If successful, this is the last
      ** connection to the database. In this case flush the contents of the
      ** in-memory tree to disk and write a checkpoint.  */
      rc = lsmShmTestLock(pDb, LSM_LOCK_DMS2, 1, LSM_LOCK_EXCL);
      if( rc==LSM_OK ){
        rc = lsmShmTestLock(pDb, LSM_LOCK_CHECKPOINTER, 1, LSM_LOCK_EXCL);
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
322
323
324
325
326
327
328

329
330
331
332
333
334
335







-







    }

    if( pDb->iRwclient>=0 ){
      lsmShmLock(pDb, LSM_LOCK_RWCLIENT(pDb->iRwclient), LSM_LOCK_UNLOCK, 0);
      pDb->iRwclient = -1;
    }

    lsmShmLock(pDb, LSM_LOCK_DMS2, LSM_LOCK_UNLOCK, 0);
    lsmShmLock(pDb, LSM_LOCK_DMS1, LSM_LOCK_UNLOCK, 0);
  }
  pDb->pShmhdr = 0;
}

static int doDbConnect(lsm_db *pDb){
  const int nUsMax = 100000;      /* Max value for nUs */
473
474
475
476
477
478
479



480


481



482
483
484
485
486
487
488
474
475
476
477
478
479
480
481
482
483
484
485
486

487
488
489
490
491
492
493
494
495
496







+
+
+

+
+
-
+
+
+







      ** attempt to take the exclusive lock on DMS2.  */
      if( rc==LSM_OK ){
        int bReadonly = (pDb->bReadonly && pDb->bMultiProc);
        rc = dbOpenSharedFd(pDb->pEnv, p, bReadonly);
      }

      if( rc==LSM_OK && p->bMultiProc==0 ){
        /* Hold an exclusive lock DMS1 while grabbing DMS2. This ensures
        ** that any ongoing call to doDbDisconnect() (even one in another
        ** process) is finished before proceeding.  */
        assert( p->bReadonly==0 );
        rc = lsmEnvLock(pDb->pEnv, p->pFile, LSM_LOCK_DMS1, LSM_LOCK_EXCL);
        if( rc==LSM_OK ){
        rc = lsmEnvLock(pDb->pEnv, p->pFile, LSM_LOCK_DMS2, LSM_LOCK_EXCL);
          rc = lsmEnvLock(pDb->pEnv, p->pFile, LSM_LOCK_DMS2, LSM_LOCK_EXCL);
          lsmEnvLock(pDb->pEnv, p->pFile, LSM_LOCK_DMS1, LSM_LOCK_UNLOCK);
        }
      }

      if( rc==LSM_OK ){
        p->pDbNext = gShared.pDatabase;
        gShared.pDatabase = p;
      }else{
        freeDatabase(pEnv, p);
1743
1744
1745
1746
1747
1748
1749
1750




1751
1752
1753
1754
1755
1756
1757
1751
1752
1753
1754
1755
1756
1757

1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768







-
+
+
+
+







  for(i=iLock; i<(iLock+nLock); i++){
    mask |= ((u64)1 << (iLock-1));
    if( eOp==LSM_LOCK_EXCL ) mask |= ((u64)1 << (iLock+32-1));
  }

  lsmMutexEnter(db->pEnv, p->pClientMutex);
  for(pIter=p->pConn; pIter; pIter=pIter->pNext){
    if( pIter!=db && (pIter->mLock & mask) ) break;
    if( pIter!=db && (pIter->mLock & mask) ){
      assert( pIter!=db );
      break;
    }
  }

  if( pIter ){
    rc = LSM_BUSY;
  }else if( p->bMultiProc ){
    rc = lsmEnvTestLock(db->pEnv, p->pFile, iLock, nLock, eOp);
  }