SQLite

Check-in [69567c5fca]
Login

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

Overview
Comment:Fix a couple uninitialized variables in the xShmLock method of the unix VFS. Improved debugging logic for xShmLock.
Downloads: Tarball | ZIP archive
Timelines: family | ancestors | descendants | both | wal
Files: files | file ages | folders
SHA1: 69567c5fca9e30b7660e6f56350be929c3890d7e
User & Date: drh 2010-04-30 15:54:47.000
Context
2010-04-30
16:12
Correctly record the fact that the SHM lock reached PENDING if it did so but failed to reach CHECKPOINT. (check-in: d9250e84ac user: drh tags: wal)
15:54
Fix a couple uninitialized variables in the xShmLock method of the unix VFS. Improved debugging logic for xShmLock. (check-in: 69567c5fca user: drh tags: wal)
15:49
When closing a WAL connection, attempt an exclusive lock on the database file. If the lock is obtained, checkpoint the database and delete the wal and wal-index files. (check-in: c05e7dca17 user: dan tags: wal)
Changes
Unified Diff Ignore Whitespace Patch
Changes to src/os_unix.c.
4712
4713
4714
4715
4716
4717
4718

4719
4720
4721
4722
4723
4724
4725

  /* Initialize the locking parameters */
  memset(&f, 0, sizeof(f));
  f.l_type = lockType;
  f.l_whence = SEEK_SET;
  if( (lockMask & UNIX_SHM_MUTEX)!=0 && lockType!=F_UNLCK ){
    lockOp = F_SETLKW;

  }else{
    lockOp = F_SETLK;
  }

  /* Find the first bit in lockMask that is set */
  for(i=0, mask=0x01; mask!=0 && (lockMask&mask)==0; mask <<= 1, i++){}
  assert( mask!=0 );







>







4712
4713
4714
4715
4716
4717
4718
4719
4720
4721
4722
4723
4724
4725
4726

  /* Initialize the locking parameters */
  memset(&f, 0, sizeof(f));
  f.l_type = lockType;
  f.l_whence = SEEK_SET;
  if( (lockMask & UNIX_SHM_MUTEX)!=0 && lockType!=F_UNLCK ){
    lockOp = F_SETLKW;
    OSTRACE(("SHM-LOCK requesting blocking lock\n"));
  }else{
    lockOp = F_SETLK;
  }

  /* Find the first bit in lockMask that is set */
  for(i=0, mask=0x01; mask!=0 && (lockMask&mask)==0; mask <<= 1, i++){}
  assert( mask!=0 );
4764
4765
4766
4767
4768
4769
4770
4771
4772
4773
4774
4775
4776
4777
4778
    }else if( lockType==F_RDLCK ){
      OSTRACE(("read-lock failed"));
    }else{
      assert( lockType==F_WRLCK );
      OSTRACE(("write-lock failed"));
    }
  }
  OSTRACE((" - change requested %s - afterwards %s,%s\n",
           unixShmLockString(lockMask),
           unixShmLockString(pFile->sharedMask),
           unixShmLockString(pFile->exclMask)));
#endif

  return rc;        
}







|







4765
4766
4767
4768
4769
4770
4771
4772
4773
4774
4775
4776
4777
4778
4779
    }else if( lockType==F_RDLCK ){
      OSTRACE(("read-lock failed"));
    }else{
      assert( lockType==F_WRLCK );
      OSTRACE(("write-lock failed"));
    }
  }
  OSTRACE((" - change requested %s - afterwards %s:%s\n",
           unixShmLockString(lockMask),
           unixShmLockString(pFile->sharedMask),
           unixShmLockString(pFile->exclMask)));
#endif

  return rc;        
}
4790
4791
4792
4793
4794
4795
4796

4797
4798
4799
4800
4801
4802
4803
  unixShm *pX; /* For looping over all sibling connections */
  u8 allMask;  /* Union of locks held by connections other than "p" */

  /* Access to the unixShmFile object is serialized by the caller */
  assert( sqlite3_mutex_held(pFile->mutex) );

  /* Compute locks held by sibling connections */

  for(pX=pFile->pFirst; pX; pX=pX->pNext){
    if( pX==p ) continue;
    assert( (pX->exclMask & (p->exclMask|p->sharedMask))==0 );
    allMask |= pX->sharedMask;
  }

  /* Unlock the system-level locks */







>







4791
4792
4793
4794
4795
4796
4797
4798
4799
4800
4801
4802
4803
4804
4805
  unixShm *pX; /* For looping over all sibling connections */
  u8 allMask;  /* Union of locks held by connections other than "p" */

  /* Access to the unixShmFile object is serialized by the caller */
  assert( sqlite3_mutex_held(pFile->mutex) );

  /* Compute locks held by sibling connections */
  allMask = 0;
  for(pX=pFile->pFirst; pX; pX=pX->pNext){
    if( pX==p ) continue;
    assert( (pX->exclMask & (p->exclMask|p->sharedMask))==0 );
    allMask |= pX->sharedMask;
  }

  /* Unlock the system-level locks */
4830
4831
4832
4833
4834
4835
4836

4837
4838
4839
4840
4841
4842
4843
  /* Access to the unixShmFile object is serialized by the caller */
  assert( sqlite3_mutex_held(pFile->mutex) );

  /* Find out which shared locks are already held by sibling connections.
  ** If any sibling already holds an exclusive lock, go ahead and return
  ** SQLITE_BUSY.
  */

  for(pX=pFile->pFirst; pX; pX=pX->pNext){
    if( pX==p ) continue;
    if( (pX->exclMask & readMask)!=0 ) return SQLITE_BUSY;
    allShared |= pX->sharedMask;
  }

  /* Get shared locks at the system level, if necessary */







>







4832
4833
4834
4835
4836
4837
4838
4839
4840
4841
4842
4843
4844
4845
4846
  /* Access to the unixShmFile object is serialized by the caller */
  assert( sqlite3_mutex_held(pFile->mutex) );

  /* Find out which shared locks are already held by sibling connections.
  ** If any sibling already holds an exclusive lock, go ahead and return
  ** SQLITE_BUSY.
  */
  allShared = 0;
  for(pX=pFile->pFirst; pX; pX=pX->pNext){
    if( pX==p ) continue;
    if( (pX->exclMask & readMask)!=0 ) return SQLITE_BUSY;
    allShared |= pX->sharedMask;
  }

  /* Get shared locks at the system level, if necessary */
5000
5001
5002
5003
5004
5005
5006
5007
5008
5009

5010
5011

5012

5013
5014
5015
5016
5017
5018
5019
    if( unixShmSystemLock(pFile, F_WRLCK, UNIX_SHM_MUTEX) ){
      rc = SQLITE_IOERR_LOCK;
      goto shm_open_err;
    }
    if( unixShmSystemLock(pFile, F_WRLCK, UNIX_SHM_DMS)==SQLITE_OK ){
      if( ftruncate(pFile->h, 0) ){
        rc = SQLITE_IOERR;
        goto shm_open_err;
      }
    }

    rc = unixShmSystemLock(pFile, F_RDLCK, UNIX_SHM_DMS);
    if( rc ) goto shm_open_err;

    unixShmSystemLock(pFile, F_UNLCK, UNIX_SHM_MUTEX);

  }

  /* Make the new connection a child of the unixShmFile */
  p->pFile = pFile;
  p->pNext = pFile->pFirst;
#ifdef SQLITE_DEBUG
  p->id = pFile->nextShmId++;







<


>
|
<
>

>







5003
5004
5005
5006
5007
5008
5009

5010
5011
5012
5013

5014
5015
5016
5017
5018
5019
5020
5021
5022
5023
    if( unixShmSystemLock(pFile, F_WRLCK, UNIX_SHM_MUTEX) ){
      rc = SQLITE_IOERR_LOCK;
      goto shm_open_err;
    }
    if( unixShmSystemLock(pFile, F_WRLCK, UNIX_SHM_DMS)==SQLITE_OK ){
      if( ftruncate(pFile->h, 0) ){
        rc = SQLITE_IOERR;

      }
    }
    if( rc==SQLITE_OK ){
      rc = unixShmSystemLock(pFile, F_RDLCK, UNIX_SHM_DMS);

    }
    unixShmSystemLock(pFile, F_UNLCK, UNIX_SHM_MUTEX);
    if( rc ) goto shm_open_err;
  }

  /* Make the new connection a child of the unixShmFile */
  p->pFile = pFile;
  p->pNext = pFile->pFirst;
#ifdef SQLITE_DEBUG
  p->id = pFile->nextShmId++;
5197
5198
5199
5200
5201
5202
5203


5204
5205
5206
5207


5208
5209
5210
5211
5212
5213
5214
  /* Return directly if this is just a lock state query, or if
  ** the connection is already in the desired locking state.
  */
  if( desiredLock==SQLITE_SHM_QUERY
   || desiredLock==p->lockState
   || (desiredLock==SQLITE_SHM_READ && p->lockState==SQLITE_SHM_READ_FULL)
  ){


    if( pGotLock ) *pGotLock = p->lockState;
    return SQLITE_OK;
  }



  sqlite3_mutex_enter(pFile->mutex);
  switch( desiredLock ){
    case SQLITE_SHM_UNLOCK: {
      assert( p->lockState!=SQLITE_SHM_RECOVER );
      unixShmUnlock(pFile, p, UNIX_SHM_A|UNIX_SHM_B|UNIX_SHM_C|UNIX_SHM_D);
      rc = SQLITE_OK;
      p->lockState = SQLITE_SHM_UNLOCK;







>
>




>
>







5201
5202
5203
5204
5205
5206
5207
5208
5209
5210
5211
5212
5213
5214
5215
5216
5217
5218
5219
5220
5221
5222
  /* Return directly if this is just a lock state query, or if
  ** the connection is already in the desired locking state.
  */
  if( desiredLock==SQLITE_SHM_QUERY
   || desiredLock==p->lockState
   || (desiredLock==SQLITE_SHM_READ && p->lockState==SQLITE_SHM_READ_FULL)
  ){
    OSTRACE(("SHM-LOCK shmid-%d, pid-%d request %d and got %d\n",
             p->id, getpid(), desiredLock, p->lockState));
    if( pGotLock ) *pGotLock = p->lockState;
    return SQLITE_OK;
  }

  OSTRACE(("SHM-LOCK shmid-%d, pid-%d request %d->%d\n",
            p->id, getpid(), p->lockState, desiredLock));
  sqlite3_mutex_enter(pFile->mutex);
  switch( desiredLock ){
    case SQLITE_SHM_UNLOCK: {
      assert( p->lockState!=SQLITE_SHM_RECOVER );
      unixShmUnlock(pFile, p, UNIX_SHM_A|UNIX_SHM_B|UNIX_SHM_C|UNIX_SHM_D);
      rc = SQLITE_OK;
      p->lockState = SQLITE_SHM_UNLOCK;
5289
5290
5291
5292
5293
5294
5295

5296
5297
5298
5299
5300
5301
5302
      if( rc==SQLITE_OK ){
        p->lockState = SQLITE_SHM_RECOVER;
      }
      break;
    }
  }
  sqlite3_mutex_leave(pFile->mutex);

  if( pGotLock ) *pGotLock = p->lockState;
  return rc;
}

/*
** Delete a shared-memory segment from the system.
*/







>







5297
5298
5299
5300
5301
5302
5303
5304
5305
5306
5307
5308
5309
5310
5311
      if( rc==SQLITE_OK ){
        p->lockState = SQLITE_SHM_RECOVER;
      }
      break;
    }
  }
  sqlite3_mutex_leave(pFile->mutex);
  OSTRACE(("SHM-LOCK shmid-%d, pid-%d got %d\n", p->id,getpid(),p->lockState));
  if( pGotLock ) *pGotLock = p->lockState;
  return rc;
}

/*
** Delete a shared-memory segment from the system.
*/