/ Check-in [a65c2939]
Login
SQLite training in Houston TX on 2019-11-05 (details)
Part of the 2019 Tcl Conference

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

Overview
Comment:Change the xShmOpen() method of the VFS to take the database file name as its argument, not the WAL file name. Also fix some unrelated compiler warnings.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: a65c2939267ef6acec4e355a207f98f217e263d6
User & Date: drh 2010-05-07 20:02:24
Context
2010-05-07
20:34
When running a checkpoint while in locking_mode=EXCLUSIVE, be sure to move the wal-index lock to UNLOCK from READ prior to promoting to CHECKPOINT. check-in: be114bdf user: drh tags: trunk
20:02
Change the xShmOpen() method of the VFS to take the database file name as its argument, not the WAL file name. Also fix some unrelated compiler warnings. check-in: a65c2939 user: drh tags: trunk
18:23
Additional tweaks to API documentation. No functional code changes. check-in: e1230782 user: drh tags: trunk
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to src/mutex_noop.c.

23
24
25
26
27
28
29

30
31
32
33
34
35
36
...
192
193
194
195
196
197
198

**
** If compiled with SQLITE_DEBUG, then additional logic is inserted
** that does error checking on mutexes to make sure they are being
** called correctly.
*/
#include "sqliteInt.h"



#ifndef SQLITE_DEBUG
/*
** Stub routines for all mutex methods.
**
** This routines provide no mutual exclusion or error checking.
*/
................................................................................
** is used regardless of the run-time threadsafety setting.
*/
#ifdef SQLITE_MUTEX_NOOP
sqlite3_mutex_methods *sqlite3DefaultMutex(void){
  return sqliteNoopMutex();
}
#endif /* SQLITE_MUTEX_NOOP */








>







 







>
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
...
193
194
195
196
197
198
199
200
**
** If compiled with SQLITE_DEBUG, then additional logic is inserted
** that does error checking on mutexes to make sure they are being
** called correctly.
*/
#include "sqliteInt.h"

#ifndef SQLITE_MUTEX_OMIT

#ifndef SQLITE_DEBUG
/*
** Stub routines for all mutex methods.
**
** This routines provide no mutual exclusion or error checking.
*/
................................................................................
** is used regardless of the run-time threadsafety setting.
*/
#ifdef SQLITE_MUTEX_NOOP
sqlite3_mutex_methods *sqlite3DefaultMutex(void){
  return sqliteNoopMutex();
}
#endif /* SQLITE_MUTEX_NOOP */
#endif /* SQLITE_MUTEX_OMIT */

Changes to src/os_unix.c.

4945
4946
4947
4948
4949
4950
4951
4952
4953
4954
4955
4956
4957
4958
4959
....
4963
4964
4965
4966
4967
4968
4969
4970
4971
4972
4973
4974
4975
4976
4977
4978
4979
4980
4981
4982
4983
4984
....
5219
5220
5221
5222
5223
5224
5225
5226
5227
5228
5229
5230
5231
5232
5233
5234
5235
**
** When opening a new shared-memory file, if no other instances of that
** file are currently open, in this process or in other processes, then
** the file must be truncated to zero length or have its header cleared.
*/
static int unixShmOpen(
  sqlite3_vfs *pVfs,    /* The VFS */
  const char *zName,    /* Base name of file to mmap */
  sqlite3_shm **pShm    /* Write the unixShm object created here */
){
  struct unixShm *p = 0;             /* The connection to be opened */
  struct unixShmFile *pFile = 0;     /* The underlying mmapped file */
  int rc;                            /* Result code */
  struct unixFileId fid;             /* Unix file identifier */
  struct unixShmFile *pNew;          /* Newly allocated pFile */
................................................................................
  /* Allocate space for the new sqlite3_shm object.  Also speculatively
  ** allocate space for a new unixShmFile and filename.
  */
  p = sqlite3_malloc( sizeof(*p) );
  if( p==0 ) return SQLITE_NOMEM;
  memset(p, 0, sizeof(*p));
  nName = strlen(zName);
  pNew = sqlite3_malloc( sizeof(*pFile) + nName + 10 );
  if( pNew==0 ){
    sqlite3_free(p);
    return SQLITE_NOMEM;
  }
  memset(pNew, 0, sizeof(*pNew));
  pNew->zFilename = (char*)&pNew[1];
  sqlite3_snprintf(nName+10, pNew->zFilename, "%s-index", zName);

  /* Look to see if there is an existing unixShmFile that can be used.
  ** If no matching unixShmFile currently exists, create a new one.
  */
  unixEnterMutex();
  rc = stat(pNew->zFilename, &sStat);
  if( rc==0 ){
................................................................................
** really want to release the lock, so in that case too, this routine
** is a no-op.
*/
static int unixShmRelease(sqlite3_vfs *pVfs, sqlite3_shm *pSharedMem){
  unixShm *p = (unixShm*)pSharedMem;
  UNUSED_PARAMETER(pVfs);
  if( p->hasMutexBuf && p->lockState!=SQLITE_SHM_RECOVER ){
    unixShmFile *pFile = p->pFile;
    assert( sqlite3_mutex_notheld(pFile->mutex) );
    sqlite3_mutex_leave(pFile->mutexBuf);
    p->hasMutexBuf = 0;
  }
  return SQLITE_OK;
}

/*
** Symbolic names for LOCK states used for debugging.







|







 







|






|







 







<
|
|







4945
4946
4947
4948
4949
4950
4951
4952
4953
4954
4955
4956
4957
4958
4959
....
4963
4964
4965
4966
4967
4968
4969
4970
4971
4972
4973
4974
4975
4976
4977
4978
4979
4980
4981
4982
4983
4984
....
5219
5220
5221
5222
5223
5224
5225

5226
5227
5228
5229
5230
5231
5232
5233
5234
**
** When opening a new shared-memory file, if no other instances of that
** file are currently open, in this process or in other processes, then
** the file must be truncated to zero length or have its header cleared.
*/
static int unixShmOpen(
  sqlite3_vfs *pVfs,    /* The VFS */
  const char *zName,    /* Name of the corresponding database file */
  sqlite3_shm **pShm    /* Write the unixShm object created here */
){
  struct unixShm *p = 0;             /* The connection to be opened */
  struct unixShmFile *pFile = 0;     /* The underlying mmapped file */
  int rc;                            /* Result code */
  struct unixFileId fid;             /* Unix file identifier */
  struct unixShmFile *pNew;          /* Newly allocated pFile */
................................................................................
  /* Allocate space for the new sqlite3_shm object.  Also speculatively
  ** allocate space for a new unixShmFile and filename.
  */
  p = sqlite3_malloc( sizeof(*p) );
  if( p==0 ) return SQLITE_NOMEM;
  memset(p, 0, sizeof(*p));
  nName = strlen(zName);
  pNew = sqlite3_malloc( sizeof(*pFile) + nName + 15 );
  if( pNew==0 ){
    sqlite3_free(p);
    return SQLITE_NOMEM;
  }
  memset(pNew, 0, sizeof(*pNew));
  pNew->zFilename = (char*)&pNew[1];
  sqlite3_snprintf(nName+10, pNew->zFilename, "%s-wal-index", zName);

  /* Look to see if there is an existing unixShmFile that can be used.
  ** If no matching unixShmFile currently exists, create a new one.
  */
  unixEnterMutex();
  rc = stat(pNew->zFilename, &sStat);
  if( rc==0 ){
................................................................................
** really want to release the lock, so in that case too, this routine
** is a no-op.
*/
static int unixShmRelease(sqlite3_vfs *pVfs, sqlite3_shm *pSharedMem){
  unixShm *p = (unixShm*)pSharedMem;
  UNUSED_PARAMETER(pVfs);
  if( p->hasMutexBuf && p->lockState!=SQLITE_SHM_RECOVER ){

    assert( sqlite3_mutex_notheld(p->pFile->mutex) );
    sqlite3_mutex_leave(p->pFile->mutexBuf);
    p->hasMutexBuf = 0;
  }
  return SQLITE_OK;
}

/*
** Symbolic names for LOCK states used for debugging.

Changes to src/wal.c.

639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
....
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
....
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
    return SQLITE_NOMEM;
  }

  pRet->pVfs = pVfs;
  pRet->pFd = (sqlite3_file *)&pRet[1];
  pRet->zName = zWal = pVfs->szOsFile + (char*)pRet->pFd;
  sqlite3_snprintf(nWal+5, zWal, "%s-wal", zDb);
  rc = pVfs->xShmOpen(pVfs, zWal, &pRet->pWIndex);

  /* Open file handle on the write-ahead log file. */
  if( rc==SQLITE_OK ){
    flags = (SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE|SQLITE_OPEN_MAIN_JOURNAL);
    rc = sqlite3OsOpen(pVfs, zWal, pRet->pFd, flags, &flags);
  }

................................................................................

/* 
** This function returns SQLITE_OK if the caller may write to the database.
** Otherwise, if the caller is operating on a snapshot that has already
** 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.
................................................................................
  int sync_flags                  /* Flags to pass to OsSync() (or 0) */
){
  int rc;                         /* Used to catch return codes */
  u32 iFrame;                     /* Next frame address */
  u8 aFrame[WAL_FRAME_HDRSIZE];   /* Buffer to assemble frame-header in */
  PgHdr *p;                       /* Iterator to run through pList with. */
  u32 aCksum[2];                  /* Checksums */
  PgHdr *pLast;                   /* Last frame in list */
  int nLast = 0;                  /* Number of extra copies of last page */

  assert( WAL_FRAME_HDRSIZE==(4 * 2 + 2*sizeof(u32)) );
  assert( pList );
  assert( pWal->lockState==SQLITE_SHM_WRITE );
  assert( pWal->pWiData==0 );








|







 







|







 







|







639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
....
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
....
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
    return SQLITE_NOMEM;
  }

  pRet->pVfs = pVfs;
  pRet->pFd = (sqlite3_file *)&pRet[1];
  pRet->zName = zWal = pVfs->szOsFile + (char*)pRet->pFd;
  sqlite3_snprintf(nWal+5, zWal, "%s-wal", zDb);
  rc = pVfs->xShmOpen(pVfs, zDb, &pRet->pWIndex);

  /* Open file handle on the write-ahead log file. */
  if( rc==SQLITE_OK ){
    flags = (SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE|SQLITE_OPEN_MAIN_JOURNAL);
    rc = sqlite3OsOpen(pVfs, zWal, pRet->pFd, flags, &flags);
  }

................................................................................

/* 
** This function returns SQLITE_OK if the caller may write to the database.
** Otherwise, if the caller is operating on a snapshot that has already
** been overwritten by another writer, SQLITE_BUSY is returned.
*/
int sqlite3WalWriteLock(Wal *pWal, int op){
  int rc = SQLITE_OK;
  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.
................................................................................
  int sync_flags                  /* Flags to pass to OsSync() (or 0) */
){
  int rc;                         /* Used to catch return codes */
  u32 iFrame;                     /* Next frame address */
  u8 aFrame[WAL_FRAME_HDRSIZE];   /* Buffer to assemble frame-header in */
  PgHdr *p;                       /* Iterator to run through pList with. */
  u32 aCksum[2];                  /* Checksums */
  PgHdr *pLast = 0;               /* Last frame in list */
  int nLast = 0;                  /* Number of extra copies of last page */

  assert( WAL_FRAME_HDRSIZE==(4 * 2 + 2*sizeof(u32)) );
  assert( pList );
  assert( pWal->lockState==SQLITE_SHM_WRITE );
  assert( pWal->pWiData==0 );