/ Check-in [69567c5f]
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 | SQL archive
Timelines: family | ancestors | descendants | both | wal
Files: files | file ages | folders
SHA1: 69567c5fca9e30b7660e6f56350be929c3890d7e
User & Date: drh 2010-04-30 15:54:47
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: d9250e84 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: 69567c5f 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: c05e7dca user: dan tags: wal
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to src/os_unix.c.

4712
4713
4714
4715
4716
4717
4718

4719
4720
4721
4722
4723
4724
4725
....
4764
4765
4766
4767
4768
4769
4770
4771
4772
4773
4774
4775
4776
4777
4778
....
4790
4791
4792
4793
4794
4795
4796

4797
4798
4799
4800
4801
4802
4803
....
4830
4831
4832
4833
4834
4835
4836

4837
4838
4839
4840
4841
4842
4843
....
5000
5001
5002
5003
5004
5005
5006
5007
5008
5009

5010
5011

5012

5013
5014
5015
5016
5017
5018
5019
....
5197
5198
5199
5200
5201
5202
5203


5204
5205
5206
5207


5208
5209
5210
5211
5212
5213
5214
....
5289
5290
5291
5292
5293
5294
5295

5296
5297
5298
5299
5300
5301
5302

  /* 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 );
................................................................................
    }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;        
}
................................................................................
  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 */
................................................................................
  /* 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 */
................................................................................
    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++;
................................................................................
  /* 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;
................................................................................
      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.
*/







>







 







|







 







>







 







>







 







<


>
|
<
>

>







 







>
>




>
>







 







>







4712
4713
4714
4715
4716
4717
4718
4719
4720
4721
4722
4723
4724
4725
4726
....
4765
4766
4767
4768
4769
4770
4771
4772
4773
4774
4775
4776
4777
4778
4779
....
4791
4792
4793
4794
4795
4796
4797
4798
4799
4800
4801
4802
4803
4804
4805
....
4832
4833
4834
4835
4836
4837
4838
4839
4840
4841
4842
4843
4844
4845
4846
....
5003
5004
5005
5006
5007
5008
5009

5010
5011
5012
5013

5014
5015
5016
5017
5018
5019
5020
5021
5022
5023
....
5201
5202
5203
5204
5205
5206
5207
5208
5209
5210
5211
5212
5213
5214
5215
5216
5217
5218
5219
5220
5221
5222
....
5297
5298
5299
5300
5301
5302
5303
5304
5305
5306
5307
5308
5309
5310
5311

  /* 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 );
................................................................................
    }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;        
}
................................................................................
  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 */
................................................................................
  /* 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 */
................................................................................
    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++;
................................................................................
  /* 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;
................................................................................
      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.
*/