/ Check-in [d9250e84]
Login

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

Overview
Comment:Correctly record the fact that the SHM lock reached PENDING if it did so but failed to reach CHECKPOINT.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | wal
Files: files | file ages | folders
SHA1: d9250e84ac1fc6590f8670e1d801630650c7846a
User & Date: drh 2010-04-30 16:12:04
Context
2010-04-30
16:19
Add xShmXXX() methods to the test VFS in test_devsym.test. check-in: 1d203424 user: dan tags: wal
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
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to src/wal.c.

213
214
215
216
217
218
219
220
221
222
223
224

225
226
227
228
229
230
231
...
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
....
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
** type of reader lock (either SQLITE_SHM_READ or SQLITE_SHM_READ_FULL)
** in pWal->readerType.
*/
static int walSetLock(Wal *pWal, int desiredStatus){
  int rc, got;
  if( pWal->lockState==desiredStatus ) return SQLITE_OK;
  rc = pWal->pVfs->xShmLock(pWal->pWIndex, desiredStatus, &got);
  if( rc==SQLITE_OK ){
    pWal->lockState = desiredStatus;
    if( desiredStatus==SQLITE_SHM_READ ){
      pWal->readerType = got;
    }

  }
  return rc;
}

/*
** Update the header of the wal-index file.
*/
................................................................................
  Wal *pWal,                      /* Wal to close */
  sqlite3_file *pFd,              /* Database file */
  int sync_flags,                 /* Flags to pass to OsSync() (or 0) */
  u8 *zBuf                        /* Buffer of at least page-size bytes */
){
  int rc = SQLITE_OK;
  if( pWal ){
    int isDelete = 0;             /* True to unlink wal and wal-index files */

    /* If an EXCLUSIVE lock can be obtained on the database file (using the
    ** ordinary, rollback-mode locking methods, this guarantees that the
    ** connection associated with this log file is the only connection to
    ** the database. In this case checkpoint the database and unlink both
    ** the wal and wal-index files.
    **
    ** The EXCLUSIVE lock is not released before returning.
    */
    rc = sqlite3OsLock(pFd, SQLITE_LOCK_EXCLUSIVE);
    if( rc==SQLITE_OK ){
      rc = walCheckpoint(pWal, pFd, sync_flags, zBuf);
      if( rc==SQLITE_OK ){
        isDelete = 1;
      }
      walIndexUnmap(pWal);
    }

    pWal->pVfs->xShmClose(pWal->pWIndex);
    sqlite3OsClose(pWal->pFd);
    if( isDelete ){
      int nWal;
      char *zWal = &((char *)pWal->pFd)[pWal->pVfs->szOsFile];
      sqlite3OsDelete(pWal->pVfs, zWal, 0);
      nWal = sqlite3Strlen30(zWal);
      memcpy(&zWal[nWal], "-index", 7);
      pWal->pVfs->xShmDelete(pWal->pVfs, zWal);
    }
    sqlite3_free(pWal);
  }
  return rc;
}

/*
** Try to read the wal-index header. Attempt to verify the header
................................................................................
** been overwritten by another writer, SQLITE_BUSY is returned.
*/
int sqlite3WalWriteLock(Wal *pWal, int op){
  int rc;
  if( op ){
    assert( pWal->lockState == SQLITE_SHM_READ );
    rc = walSetLock(pWal, SQLITE_SHM_WRITE);

    /* If this connection is not reading the most recent database snapshot,
    ** it is not possible to write to the database. In this case release
    ** the write locks and return SQLITE_BUSY.
    */
    if( rc==SQLITE_OK ){
      rc = walIndexMap(pWal, -1);
      if( rc==SQLITE_OK 
       && memcmp(&pWal->hdr, pWal->pWiData, sizeof(WalIndexHdr))
      ){
        rc = SQLITE_BUSY;
      }
      walIndexUnmap(pWal);
      if( rc!=SQLITE_OK ){
        walSetLock(pWal, SQLITE_SHM_READ);
      }
    }

  }else if( pWal->lockState==SQLITE_SHM_WRITE ){
    rc = walSetLock(pWal, SQLITE_SHM_READ);
  }
  return rc;
}

/*







<
|
|
|
<
>







 







<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<


<
<
<
<
<
<
<
<







 







<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







213
214
215
216
217
218
219

220
221
222

223
224
225
226
227
228
229
230
...
780
781
782
783
784
785
786



















787
788








789
790
791
792
793
794
795
....
1004
1005
1006
1007
1008
1009
1010


















1011
1012
1013
1014
1015
1016
1017
** type of reader lock (either SQLITE_SHM_READ or SQLITE_SHM_READ_FULL)
** in pWal->readerType.
*/
static int walSetLock(Wal *pWal, int desiredStatus){
  int rc, got;
  if( pWal->lockState==desiredStatus ) return SQLITE_OK;
  rc = pWal->pVfs->xShmLock(pWal->pWIndex, desiredStatus, &got);

  pWal->lockState = got;
  if( got==SQLITE_SHM_READ_FULL || got==SQLITE_SHM_READ ){
    pWal->readerType = got;

    pWal->lockState = SQLITE_SHM_READ;
  }
  return rc;
}

/*
** Update the header of the wal-index file.
*/
................................................................................
  Wal *pWal,                      /* Wal to close */
  sqlite3_file *pFd,              /* Database file */
  int sync_flags,                 /* Flags to pass to OsSync() (or 0) */
  u8 *zBuf                        /* Buffer of at least page-size bytes */
){
  int rc = SQLITE_OK;
  if( pWal ){



















    pWal->pVfs->xShmClose(pWal->pWIndex);
    sqlite3OsClose(pWal->pFd);








    sqlite3_free(pWal);
  }
  return rc;
}

/*
** Try to read the wal-index header. Attempt to verify the header
................................................................................
** been overwritten by another writer, SQLITE_BUSY is returned.
*/
int sqlite3WalWriteLock(Wal *pWal, int op){
  int rc;
  if( op ){
    assert( pWal->lockState == SQLITE_SHM_READ );
    rc = walSetLock(pWal, SQLITE_SHM_WRITE);


















  }else if( pWal->lockState==SQLITE_SHM_WRITE ){
    rc = walSetLock(pWal, SQLITE_SHM_READ);
  }
  return rc;
}

/*