/ Check-in [23c0e6c3]
Login

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

Overview
Comment:Merge two wal leaves.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | wal
Files: files | file ages | folders
SHA1: 23c0e6c3f333e878fe5a2ae5d61df0d765f437b4
User & Date: dan 2010-05-03 08:19:34
Context
2010-05-03
11:05
Add the "PRAGMA wal_autocheckpoint" command. Rename "PRAGMA checkpoint" to "PRAGMA wal_checkpoint". check-in: 714e5947 user: dan tags: wal
08:19
Merge two wal leaves. check-in: 23c0e6c3 user: dan tags: wal
08:04
Add the sqlite3_wal_checkpoint() and sqlite3_wal_autocheckpoint() APIs. check-in: 9803196d user: dan tags: wal
2010-05-01
20:17
Change the SHM interface so that it does not take the name of the shared object but rather the name of the WAL file and derives its own name from that. Remove the xShmDelete method from the VFS and replace it with a delete flag on xShmClose. check-in: 94dea5f9 user: drh tags: wal
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to src/os_unix.c.

4919
4920
4921
4922
4923
4924
4925
4926








4927
4928
4929
4930
4931
4932
4933
4934
4935
4936
4937
4938
4939
4940

4941

4942
4943


4944
4945
4946









4947
4948
4949
4950
4951
4952
4953
4954
4955
4956
4957
4958
4959
4960
4961
4962
4963
4964
4965
4966
4967
4968
4969
4970
4971
4972
4973
4974
4975
4976
4977
....
4979
4980
4981
4982
4983
4984
4985
4986
4987
4988
4989
4990
4991
4992
4993
....
5029
5030
5031
5032
5033
5034
5035

5036
5037
5038
5039
5040
5041
5042

5043
5044
5045
5046
5047
5048
5049
5050
5051
....
5065
5066
5067
5068
5069
5070
5071

5072
5073
5074
5075
5076
5077
5078
....
5344
5345
5346
5347
5348
5349
5350
5351
5352
5353
5354
5355
5356
5357
5358
5359
5360
5361
5362
5363
5364
5365
5366
5367
5368
5369
5370
5371
5372
....
6583
6584
6585
6586
6587
6588
6589
6590
6591
6592
6593
6594
6595
6596
6597
6598
6599
6600
6601
    }else{
      pp = &p->pNext;
    }
  }
}

/*
** Open a shared-memory area.  This implementation uses mmapped files.








**
** 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 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 stat sStat;                 /* Result from stat() an fstat() */


  /* Allocate space for the new sqlite3_shm object */


  p = sqlite3_malloc( sizeof(*p) );
  if( p==0 ) return SQLITE_NOMEM;
  memset(p, 0, sizeof(*p));










  /* 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(zName, &sStat);
  if( rc==0 ){
    memset(&fid, 0, sizeof(fid));
    fid.dev = sStat.st_dev;
    fid.ino = sStat.st_ino;
    for(pFile = unixShmFileList; pFile; pFile=pFile->pNext){
      if( memcmp(&pFile->fid, &fid, sizeof(fid))==0 ) break;
    }
  }
  if( pFile==0 ){
    int nName = strlen(zName);
    pFile = sqlite3_malloc( sizeof(*pFile) + nName + 1 );
    if( pFile==0 ){
      rc = SQLITE_NOMEM;
      goto shm_open_err;
    }
    memset(pFile, 0, sizeof(*pFile));
    pFile->zFilename = (char*)&pFile[1];
    memcpy(pFile->zFilename, zName, nName+1);
    pFile->h = -1;
    pFile->pNext = unixShmFileList;
    unixShmFileList = pFile;

    pFile->mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_FAST);
    if( pFile->mutex==0 ){
      rc = SQLITE_NOMEM;
................................................................................
    }
    pFile->mutexBuf = sqlite3_mutex_alloc(SQLITE_MUTEX_FAST);
    if( pFile->mutexBuf==0 ){
      rc = SQLITE_NOMEM;
      goto shm_open_err;
    }

    pFile->h = open(zName, O_RDWR|O_CREAT, 0664);
    if( pFile->h<0 ){
      rc = SQLITE_CANTOPEN_BKPT;
      goto shm_open_err;
    }

    rc = fstat(pFile->h, &sStat);
    if( rc ){
................................................................................
  return SQLITE_OK;

  /* Jump here on any error */
shm_open_err:
  unixShmPurge();
  sqlite3_free(p);
  sqlite3_free(pFile);

  *pShm = 0;
  unixLeaveMutex();
  return rc;
}

/*
** Close a connectioon to shared-memory.

*/
static int unixShmClose(sqlite3_shm *pSharedMem){
  unixShm *p;            /* The connection to be closed */
  unixShmFile *pFile;    /* The underlying shared-memory file */
  unixShm **pp;          /* For looping over sibling connections */

  if( pSharedMem==0 ) return SQLITE_OK;
  p = (struct unixShm*)pSharedMem;
  pFile = p->pFile;
................................................................................

  /* If pFile->nRef has reached 0, then close the underlying
  ** shared-memory file, too */
  unixEnterMutex();
  assert( pFile->nRef>0 );
  pFile->nRef--;
  if( pFile->nRef==0 ){

    unixShmPurge();
  }
  unixLeaveMutex();

  return SQLITE_OK;
}

................................................................................
  sqlite3_mutex_leave(pFile->mutex);
  OSTRACE(("SHM-LOCK shmid-%d, pid-%d got %s\n",
           p->id, getpid(), azLkName[p->lockState]));
  if( pGotLock ) *pGotLock = p->lockState;
  return rc;
}

/*
** Delete a shared-memory segment from the system.
*/
static int unixShmDelete(sqlite3_vfs *pVfs, const char *zName){
  return pVfs->xDelete(pVfs, zName, 0);
}

#else
# define unixShmOpen    0
# define unixShmSize    0
# define unixShmGet     0
# define unixShmRelease 0
# define unixShmLock    0
# define unixShmClose   0
# define unixShmDelete  0
#endif /* #ifndef SQLITE_OMIT_WAL */

/*
************************ End of sqlite3_vfs methods ***************************
******************************************************************************/

/******************************************************************************
................................................................................
    unixSleep,            /* xSleep */                      \
    unixCurrentTime,      /* xCurrentTime */                \
    unixGetLastError,     /* xGetLastError */               \
    unixShmOpen,          /* xShmOpen */                    \
    unixShmSize,          /* xShmSize */                    \
    unixShmGet,           /* xShmGet */                     \
    unixShmRelease,       /* xShmRelease */                 \
    0,                    /* xShmPush */                    \
    0,                    /* xShmPull */                    \
    unixShmLock,          /* xShmLock */                    \
    unixShmClose,         /* xShmClose */                   \
    unixShmDelete,        /* xShmDelete */                  \
    0,                    /* xRename */                     \
    0,                    /* xCurrentTimeInt64 */           \
  }

  /*
  ** All default VFSes for unix are contained in the following array.
  **







|
>
>
>
>
>
>
>
>







|






>

>

|
>
>



>
>
>
>
>
>
>
>
>





|








|
|
|
|
|
<
<
<
<
<







 







|







 







>






|
>

|







 







>







 







<
<
<
<
<
<
<







<







 







<
<


<







4919
4920
4921
4922
4923
4924
4925
4926
4927
4928
4929
4930
4931
4932
4933
4934
4935
4936
4937
4938
4939
4940
4941
4942
4943
4944
4945
4946
4947
4948
4949
4950
4951
4952
4953
4954
4955
4956
4957
4958
4959
4960
4961
4962
4963
4964
4965
4966
4967
4968
4969
4970
4971
4972
4973
4974
4975
4976
4977
4978
4979
4980
4981
4982
4983
4984
4985
4986





4987
4988
4989
4990
4991
4992
4993
....
4995
4996
4997
4998
4999
5000
5001
5002
5003
5004
5005
5006
5007
5008
5009
....
5045
5046
5047
5048
5049
5050
5051
5052
5053
5054
5055
5056
5057
5058
5059
5060
5061
5062
5063
5064
5065
5066
5067
5068
5069
....
5083
5084
5085
5086
5087
5088
5089
5090
5091
5092
5093
5094
5095
5096
5097
....
5363
5364
5365
5366
5367
5368
5369







5370
5371
5372
5373
5374
5375
5376

5377
5378
5379
5380
5381
5382
5383
....
6594
6595
6596
6597
6598
6599
6600


6601
6602

6603
6604
6605
6606
6607
6608
6609
    }else{
      pp = &p->pNext;
    }
  }
}

/*
** Open a shared-memory area.  This particular implementation uses
** mmapped files.
**
** zName is a filename used to identify the shared-memory area.  The
** implementation does not (and perhaps should not) use this name
** directly, but rather use it as a template for finding an appropriate
** name for the shared-memory storage.  In this implementation, the
** string "-index" is appended to zName and used as the name of the
** mmapped file.
**
** 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 */
  struct stat sStat;                 /* Result from stat() an fstat() */
  int nName;                         /* Size of zName in bytes */

  /* 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 ){
    rc = SQLITE_NOMEM;
    goto shm_open_err;
  }
  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 ){
    memset(&fid, 0, sizeof(fid));
    fid.dev = sStat.st_dev;
    fid.ino = sStat.st_ino;
    for(pFile = unixShmFileList; pFile; pFile=pFile->pNext){
      if( memcmp(&pFile->fid, &fid, sizeof(fid))==0 ) break;
    }
  }
  if( pFile ){
    sqlite3_free(pNew);
  }else{
    pFile = pNew;
    pNew = 0;





    pFile->h = -1;
    pFile->pNext = unixShmFileList;
    unixShmFileList = pFile;

    pFile->mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_FAST);
    if( pFile->mutex==0 ){
      rc = SQLITE_NOMEM;
................................................................................
    }
    pFile->mutexBuf = sqlite3_mutex_alloc(SQLITE_MUTEX_FAST);
    if( pFile->mutexBuf==0 ){
      rc = SQLITE_NOMEM;
      goto shm_open_err;
    }

    pFile->h = open(pFile->zFilename, O_RDWR|O_CREAT, 0664);
    if( pFile->h<0 ){
      rc = SQLITE_CANTOPEN_BKPT;
      goto shm_open_err;
    }

    rc = fstat(pFile->h, &sStat);
    if( rc ){
................................................................................
  return SQLITE_OK;

  /* Jump here on any error */
shm_open_err:
  unixShmPurge();
  sqlite3_free(p);
  sqlite3_free(pFile);
  sqlite3_free(pNew);
  *pShm = 0;
  unixLeaveMutex();
  return rc;
}

/*
** Close a connection to shared-memory.  Delete the underlying 
** storage if deleteFlag is true.
*/
static int unixShmClose(sqlite3_shm *pSharedMem, int deleteFlag){
  unixShm *p;            /* The connection to be closed */
  unixShmFile *pFile;    /* The underlying shared-memory file */
  unixShm **pp;          /* For looping over sibling connections */

  if( pSharedMem==0 ) return SQLITE_OK;
  p = (struct unixShm*)pSharedMem;
  pFile = p->pFile;
................................................................................

  /* If pFile->nRef has reached 0, then close the underlying
  ** shared-memory file, too */
  unixEnterMutex();
  assert( pFile->nRef>0 );
  pFile->nRef--;
  if( pFile->nRef==0 ){
    if( deleteFlag ) unlink(pFile->zFilename);
    unixShmPurge();
  }
  unixLeaveMutex();

  return SQLITE_OK;
}

................................................................................
  sqlite3_mutex_leave(pFile->mutex);
  OSTRACE(("SHM-LOCK shmid-%d, pid-%d got %s\n",
           p->id, getpid(), azLkName[p->lockState]));
  if( pGotLock ) *pGotLock = p->lockState;
  return rc;
}








#else
# define unixShmOpen    0
# define unixShmSize    0
# define unixShmGet     0
# define unixShmRelease 0
# define unixShmLock    0
# define unixShmClose   0

#endif /* #ifndef SQLITE_OMIT_WAL */

/*
************************ End of sqlite3_vfs methods ***************************
******************************************************************************/

/******************************************************************************
................................................................................
    unixSleep,            /* xSleep */                      \
    unixCurrentTime,      /* xCurrentTime */                \
    unixGetLastError,     /* xGetLastError */               \
    unixShmOpen,          /* xShmOpen */                    \
    unixShmSize,          /* xShmSize */                    \
    unixShmGet,           /* xShmGet */                     \
    unixShmRelease,       /* xShmRelease */                 \


    unixShmLock,          /* xShmLock */                    \
    unixShmClose,         /* xShmClose */                   \

    0,                    /* xRename */                     \
    0,                    /* xCurrentTimeInt64 */           \
  }

  /*
  ** All default VFSes for unix are contained in the following array.
  **

Changes to src/sqlite.h.in.

843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
  ** The methods above are in version 1 of the sqlite_vfs object
  ** definition.  Those that follow are added in version 2 or later
  */
  int (*xShmOpen)(sqlite3_vfs*, const char *zName, sqlite3_shm**);
  int (*xShmSize)(sqlite3_shm*, int reqSize, int *pNewSize);
  int (*xShmGet)(sqlite3_shm*, int reqMapSize, int *pMapSize, void**);
  int (*xShmRelease)(sqlite3_shm*);
  int (*xShmPush)(sqlite3_shm*);
  int (*xShmPull)(sqlite3_shm*);
  int (*xShmLock)(sqlite3_shm*, int desiredLock, int *gotLock);
  int (*xShmClose)(sqlite3_shm*);
  int (*xShmDelete)(sqlite3_vfs*, const char *zName);
  int (*xRename)(sqlite3_vfs*, const char *zOld, const char *zNew, int dirSync);
  int (*xCurrentTimeInt64)(sqlite3_vfs*, sqlite3_int64*);
  /*
  ** The methods above are in versions 1 and 2 of the sqlite_vfs object.
  ** New fields may be appended in figure versions.  The iVersion
  ** value will increment whenever this happens. 
  */







<
<

|
<







843
844
845
846
847
848
849


850
851

852
853
854
855
856
857
858
  ** The methods above are in version 1 of the sqlite_vfs object
  ** definition.  Those that follow are added in version 2 or later
  */
  int (*xShmOpen)(sqlite3_vfs*, const char *zName, sqlite3_shm**);
  int (*xShmSize)(sqlite3_shm*, int reqSize, int *pNewSize);
  int (*xShmGet)(sqlite3_shm*, int reqMapSize, int *pMapSize, void**);
  int (*xShmRelease)(sqlite3_shm*);


  int (*xShmLock)(sqlite3_shm*, int desiredLock, int *gotLock);
  int (*xShmClose)(sqlite3_shm*, int deleteFlag);

  int (*xRename)(sqlite3_vfs*, const char *zOld, const char *zNew, int dirSync);
  int (*xCurrentTimeInt64)(sqlite3_vfs*, sqlite3_int64*);
  /*
  ** The methods above are in versions 1 and 2 of the sqlite_vfs object.
  ** New fields may be appended in figure versions.  The iVersion
  ** value will increment whenever this happens. 
  */

Changes to src/test_devsym.c.

69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
...
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
...
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
...
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
static int devsymCurrentTime(sqlite3_vfs*, double*);

static int devsymShmOpen(sqlite3_vfs *, const char *, sqlite3_shm **);
static int devsymShmSize(sqlite3_shm *, int , int *);
static int devsymShmGet(sqlite3_shm *, int , int *, void **);
static int devsymShmRelease(sqlite3_shm *);
static int devsymShmLock(sqlite3_shm *, int , int *);
static int devsymShmClose(sqlite3_shm *);
static int devsymShmDelete(sqlite3_vfs *, const char *);

static sqlite3_vfs devsym_vfs = {
  2,                     /* iVersion */
  sizeof(devsym_file),      /* szOsFile */
  DEVSYM_MAX_PATHNAME,      /* mxPathname */
  0,                     /* pNext */
  DEVSYM_VFS_NAME,          /* zName */
................................................................................
  devsymSleep,              /* xSleep */
  devsymCurrentTime,        /* xCurrentTime */
  0,                        /* xGetLastError */
  devsymShmOpen,
  devsymShmSize,
  devsymShmGet,
  devsymShmRelease,
  0,
  0,
  devsymShmLock,
  devsymShmClose,
  devsymShmDelete,
  0,
  0,
};

static sqlite3_io_methods devsym_io_methods = {
  1,                            /* iVersion */
  devsymClose,                      /* xClose */
................................................................................
}
static int devsymShmRelease(sqlite3_shm *p){
  return g.pVfs->xShmRelease(p);
}
static int devsymShmLock(sqlite3_shm *p, int desiredLock, int *gotLock){
  return g.pVfs->xShmLock(p, desiredLock, gotLock);
}
static int devsymShmClose(sqlite3_shm *p){
  return g.pVfs->xShmClose(p);
}
static int devsymShmDelete(sqlite3_vfs *pVfs, const char *zName){
  return g.pVfs->xShmDelete(g.pVfs, zName);
}

/*
** This procedure registers the devsym vfs with SQLite. If the argument is
** true, the devsym vfs becomes the new default vfs. It is the only publicly
** available function in this file.
*/
................................................................................
    devsym_vfs.szOsFile += g.pVfs->szOsFile;
    devsym_vfs.xShmOpen = (g.pVfs->xShmOpen ? devsymShmOpen : 0);
    devsym_vfs.xShmSize = (g.pVfs->xShmSize ? devsymShmSize : 0);
    devsym_vfs.xShmGet = (g.pVfs->xShmGet ? devsymShmGet : 0);
    devsym_vfs.xShmRelease = (g.pVfs->xShmRelease ? devsymShmRelease : 0);
    devsym_vfs.xShmLock = (g.pVfs->xShmLock ? devsymShmLock : 0);
    devsym_vfs.xShmClose = (g.pVfs->xShmClose ? devsymShmClose : 0);
    devsym_vfs.xShmDelete = (g.pVfs->xShmDelete ? devsymShmDelete : 0);
    sqlite3_vfs_register(&devsym_vfs, 0);
  }
  if( iDeviceChar>=0 ){
    g.iDeviceChar = iDeviceChar;
  }else{
    g.iDeviceChar = 0;
  }







|
<







 







<
<


<







 







|
|
<
<
<







 







<







69
70
71
72
73
74
75
76

77
78
79
80
81
82
83
...
101
102
103
104
105
106
107


108
109

110
111
112
113
114
115
116
...
370
371
372
373
374
375
376
377
378



379
380
381
382
383
384
385
...
389
390
391
392
393
394
395

396
397
398
399
400
401
402
static int devsymCurrentTime(sqlite3_vfs*, double*);

static int devsymShmOpen(sqlite3_vfs *, const char *, sqlite3_shm **);
static int devsymShmSize(sqlite3_shm *, int , int *);
static int devsymShmGet(sqlite3_shm *, int , int *, void **);
static int devsymShmRelease(sqlite3_shm *);
static int devsymShmLock(sqlite3_shm *, int , int *);
static int devsymShmClose(sqlite3_shm *, int);


static sqlite3_vfs devsym_vfs = {
  2,                     /* iVersion */
  sizeof(devsym_file),      /* szOsFile */
  DEVSYM_MAX_PATHNAME,      /* mxPathname */
  0,                     /* pNext */
  DEVSYM_VFS_NAME,          /* zName */
................................................................................
  devsymSleep,              /* xSleep */
  devsymCurrentTime,        /* xCurrentTime */
  0,                        /* xGetLastError */
  devsymShmOpen,
  devsymShmSize,
  devsymShmGet,
  devsymShmRelease,


  devsymShmLock,
  devsymShmClose,

  0,
  0,
};

static sqlite3_io_methods devsym_io_methods = {
  1,                            /* iVersion */
  devsymClose,                      /* xClose */
................................................................................
}
static int devsymShmRelease(sqlite3_shm *p){
  return g.pVfs->xShmRelease(p);
}
static int devsymShmLock(sqlite3_shm *p, int desiredLock, int *gotLock){
  return g.pVfs->xShmLock(p, desiredLock, gotLock);
}
static int devsymShmClose(sqlite3_shm *p, int deleteFlag){
  return g.pVfs->xShmClose(p, deleteFlag);



}

/*
** This procedure registers the devsym vfs with SQLite. If the argument is
** true, the devsym vfs becomes the new default vfs. It is the only publicly
** available function in this file.
*/
................................................................................
    devsym_vfs.szOsFile += g.pVfs->szOsFile;
    devsym_vfs.xShmOpen = (g.pVfs->xShmOpen ? devsymShmOpen : 0);
    devsym_vfs.xShmSize = (g.pVfs->xShmSize ? devsymShmSize : 0);
    devsym_vfs.xShmGet = (g.pVfs->xShmGet ? devsymShmGet : 0);
    devsym_vfs.xShmRelease = (g.pVfs->xShmRelease ? devsymShmRelease : 0);
    devsym_vfs.xShmLock = (g.pVfs->xShmLock ? devsymShmLock : 0);
    devsym_vfs.xShmClose = (g.pVfs->xShmClose ? devsymShmClose : 0);

    sqlite3_vfs_register(&devsym_vfs, 0);
  }
  if( iDeviceChar>=0 ){
    g.iDeviceChar = iDeviceChar;
  }else{
    g.iDeviceChar = 0;
  }

Changes to src/test_onefile.c.

197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
    fsDlSym,                                    /* xDlSym */
    fsDlClose,                                  /* xDlClose */
    fsRandomness,                               /* xRandomness */
    fsSleep,                                    /* xSleep */
    fsCurrentTime,                              /* xCurrentTime */
    0,                                          /* xShmOpen */
    0,                                          /* xShmSize */
    0,                                          /* xShmPush */
    0,                                          /* xShmPull */
    0,                                          /* xShmLock */
    0,                                          /* xShmClose */
    0,                                          /* xShmDelete */
    0,                                          /* xRename */
    0                                           /* xCurrentTimeInt64 */
  }, 
  0,                                            /* pFileList */







<
<







197
198
199
200
201
202
203


204
205
206
207
208
209
210
    fsDlSym,                                    /* xDlSym */
    fsDlClose,                                  /* xDlClose */
    fsRandomness,                               /* xRandomness */
    fsSleep,                                    /* xSleep */
    fsCurrentTime,                              /* xCurrentTime */
    0,                                          /* xShmOpen */
    0,                                          /* xShmSize */


    0,                                          /* xShmLock */
    0,                                          /* xShmClose */
    0,                                          /* xShmDelete */
    0,                                          /* xRename */
    0                                           /* xCurrentTimeInt64 */
  }, 
  0,                                            /* pFileList */

Changes to src/wal.c.

129
130
131
132
133
134
135

136
137
138
139
140
141
142
...
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
...
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
  u32 iCallback;             /* Value to pass to log callback (or 0) */
  sqlite3_shm *pWIndex;      /* The open wal-index file */
  int szWIndex;              /* Size of the wal-index that is mapped in mem */
  u32 *pWiData;              /* Pointer to wal-index content in memory */
  u8 lockState;              /* SQLITE_SHM_xxxx constant showing lock state */
  u8 readerType;             /* SQLITE_SHM_READ or SQLITE_SHM_READ_FULL */
  WalIndexHdr hdr;           /* Wal-index for current snapshot */

};


/*
** This structure is used to implement an iterator that iterates through
** all frames in the log in database page order. Where two or more frames
** correspond to the same database page, the iterator visits only the 
................................................................................

  assert( zDb );
  if( pVfs->xShmOpen==0 ) return SQLITE_CANTOPEN_BKPT;

  /* Allocate an instance of struct Wal to return. */
  *ppWal = 0;
  nWal = strlen(zDb);
  pRet = (Wal*)sqlite3MallocZero(sizeof(Wal) + pVfs->szOsFile + nWal+11);
  if( !pRet ) goto wal_open_out;
  pRet->pVfs = pVfs;
  pRet->pFd = (sqlite3_file *)&pRet[1];
  zWal = pVfs->szOsFile + (char*)pRet->pFd;
  sqlite3_snprintf(nWal+11, zWal, "%s-wal-index", zDb);
  rc = pVfs->xShmOpen(pVfs, zWal, &pRet->pWIndex);
  if( rc ) goto wal_open_out;

  /* Open file handle on the write-ahead log file. */
  zWal[nWal+4] = 0;
  flags = (SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE|SQLITE_OPEN_MAIN_JOURNAL);
  rc = sqlite3OsOpen(pVfs, zWal, pRet->pFd, flags, &flags);

wal_open_out:
  if( rc!=SQLITE_OK ){
    if( pRet ){
      pVfs->xShmClose(pRet->pWIndex);
      sqlite3OsClose(pRet->pFd);
      sqlite3_free(pRet);
    }
  }
  *ppWal = pRet;
  return rc;
}
................................................................................
      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;
}

/*







>







 







|



|
|




<






|







 







|


<
<
|
<
<
<







129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
...
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603

604
605
606
607
608
609
610
611
612
613
614
615
616
617
...
801
802
803
804
805
806
807
808
809
810


811



812
813
814
815
816
817
818
  u32 iCallback;             /* Value to pass to log callback (or 0) */
  sqlite3_shm *pWIndex;      /* The open wal-index file */
  int szWIndex;              /* Size of the wal-index that is mapped in mem */
  u32 *pWiData;              /* Pointer to wal-index content in memory */
  u8 lockState;              /* SQLITE_SHM_xxxx constant showing lock state */
  u8 readerType;             /* SQLITE_SHM_READ or SQLITE_SHM_READ_FULL */
  WalIndexHdr hdr;           /* Wal-index for current snapshot */
  char *zName;               /* Name of underlying storage */
};


/*
** This structure is used to implement an iterator that iterates through
** all frames in the log in database page order. Where two or more frames
** correspond to the same database page, the iterator visits only the 
................................................................................

  assert( zDb );
  if( pVfs->xShmOpen==0 ) return SQLITE_CANTOPEN_BKPT;

  /* Allocate an instance of struct Wal to return. */
  *ppWal = 0;
  nWal = strlen(zDb);
  pRet = (Wal*)sqlite3MallocZero(sizeof(Wal) + pVfs->szOsFile + nWal+5);
  if( !pRet ) goto wal_open_out;
  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);
  if( rc ) goto wal_open_out;

  /* Open file handle on the write-ahead log file. */

  flags = (SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE|SQLITE_OPEN_MAIN_JOURNAL);
  rc = sqlite3OsOpen(pVfs, zWal, pRet->pFd, flags, &flags);

wal_open_out:
  if( rc!=SQLITE_OK ){
    if( pRet ){
      pVfs->xShmClose(pRet->pWIndex, 0);
      sqlite3OsClose(pRet->pFd);
      sqlite3_free(pRet);
    }
  }
  *ppWal = pRet;
  return rc;
}
................................................................................
      rc = walCheckpoint(pWal, pFd, sync_flags, zBuf);
      if( rc==SQLITE_OK ){
        isDelete = 1;
      }
      walIndexUnmap(pWal);
    }

    pWal->pVfs->xShmClose(pWal->pWIndex, isDelete);
    sqlite3OsClose(pWal->pFd);
    if( isDelete ){


      sqlite3OsDelete(pWal->pVfs, pWal->zName, 0);



    }
    sqlite3_free(pWal);
  }
  return rc;
}

/*