/ Check-in [a82a9bea]
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 | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: a82a9bea624caf6b24d8e3f3c596817968b258f06e54288022f6df8226281057
User & Date: dan 2017-07-10 18:33:41
Context
2017-07-10
18:52
Updates to the repository README.md file. check-in: 7bfd3ab7 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: a82a9bea 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: bde431b1 user: drh tags: trunk
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to ext/lsm1/lsm_shared.c.

   248    248     if( pDb->bReadonly ){
   249    249       lsmShmLock(pDb, LSM_LOCK_DMS3, LSM_LOCK_UNLOCK, 0);
   250    250     }else{
   251    251       /* Block for an exclusive lock on DMS1. This lock serializes all calls
   252    252       ** to doDbConnect() and doDbDisconnect() across all processes.  */
   253    253       rc = lsmShmLock(pDb, LSM_LOCK_DMS1, LSM_LOCK_EXCL, 1);
   254    254       if( rc==LSM_OK ){
          255  +
          256  +      lsmShmLock(pDb, LSM_LOCK_DMS2, LSM_LOCK_UNLOCK, 0);
   255    257   
   256    258         /* Try an exclusive lock on DMS2. If successful, this is the last
   257    259         ** connection to the database. In this case flush the contents of the
   258    260         ** in-memory tree to disk and write a checkpoint.  */
   259    261         rc = lsmShmTestLock(pDb, LSM_LOCK_DMS2, 1, LSM_LOCK_EXCL);
   260    262         if( rc==LSM_OK ){
   261    263           rc = lsmShmTestLock(pDb, LSM_LOCK_CHECKPOINTER, 1, LSM_LOCK_EXCL);
................................................................................
   320    322       }
   321    323   
   322    324       if( pDb->iRwclient>=0 ){
   323    325         lsmShmLock(pDb, LSM_LOCK_RWCLIENT(pDb->iRwclient), LSM_LOCK_UNLOCK, 0);
   324    326         pDb->iRwclient = -1;
   325    327       }
   326    328   
   327         -    lsmShmLock(pDb, LSM_LOCK_DMS2, LSM_LOCK_UNLOCK, 0);
   328    329       lsmShmLock(pDb, LSM_LOCK_DMS1, LSM_LOCK_UNLOCK, 0);
   329    330     }
   330    331     pDb->pShmhdr = 0;
   331    332   }
   332    333   
   333    334   static int doDbConnect(lsm_db *pDb){
   334    335     const int nUsMax = 100000;      /* Max value for nUs */
................................................................................
   473    474         ** attempt to take the exclusive lock on DMS2.  */
   474    475         if( rc==LSM_OK ){
   475    476           int bReadonly = (pDb->bReadonly && pDb->bMultiProc);
   476    477           rc = dbOpenSharedFd(pDb->pEnv, p, bReadonly);
   477    478         }
   478    479   
   479    480         if( rc==LSM_OK && p->bMultiProc==0 ){
          481  +        /* Hold an exclusive lock DMS1 while grabbing DMS2. This ensures
          482  +        ** that any ongoing call to doDbDisconnect() (even one in another
          483  +        ** process) is finished before proceeding.  */
   480    484           assert( p->bReadonly==0 );
   481         -        rc = lsmEnvLock(pDb->pEnv, p->pFile, LSM_LOCK_DMS2, LSM_LOCK_EXCL);
          485  +        rc = lsmEnvLock(pDb->pEnv, p->pFile, LSM_LOCK_DMS1, LSM_LOCK_EXCL);
          486  +        if( rc==LSM_OK ){
          487  +          rc = lsmEnvLock(pDb->pEnv, p->pFile, LSM_LOCK_DMS2, LSM_LOCK_EXCL);
          488  +          lsmEnvLock(pDb->pEnv, p->pFile, LSM_LOCK_DMS1, LSM_LOCK_UNLOCK);
          489  +        }
   482    490         }
   483    491   
   484    492         if( rc==LSM_OK ){
   485    493           p->pDbNext = gShared.pDatabase;
   486    494           gShared.pDatabase = p;
   487    495         }else{
   488    496           freeDatabase(pEnv, p);
................................................................................
  1743   1751     for(i=iLock; i<(iLock+nLock); i++){
  1744   1752       mask |= ((u64)1 << (iLock-1));
  1745   1753       if( eOp==LSM_LOCK_EXCL ) mask |= ((u64)1 << (iLock+32-1));
  1746   1754     }
  1747   1755   
  1748   1756     lsmMutexEnter(db->pEnv, p->pClientMutex);
  1749   1757     for(pIter=p->pConn; pIter; pIter=pIter->pNext){
  1750         -    if( pIter!=db && (pIter->mLock & mask) ) break;
         1758  +    if( pIter!=db && (pIter->mLock & mask) ){
         1759  +      assert( pIter!=db );
         1760  +      break;
         1761  +    }
  1751   1762     }
  1752   1763   
  1753   1764     if( pIter ){
  1754   1765       rc = LSM_BUSY;
  1755   1766     }else if( p->bMultiProc ){
  1756   1767       rc = lsmEnvTestLock(db->pEnv, p->pFile, iLock, nLock, eOp);
  1757   1768     }