/ Check-in [115b8305]
Login

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

Overview
Comment:Change the signature of the xUnfetch method to "int (*xUnfetch)(sqlite3_file*, sqlite3_int64 iOfst, void *p)".
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | experimental-mmap
Files: files | file ages | folders
SHA1:115b830509e8f0aa9d5965c1e9cd4f2ed9d01938
User & Date: dan 2013-03-25 17:00:24
Context
2013-03-25
18:25
Simulate OOM errors in the sqlite3OsFetch() function. Run malloc.test as part of the "mmap" permutation. check-in: 77443ef2 user: dan tags: experimental-mmap
17:00
Change the signature of the xUnfetch method to "int (*xUnfetch)(sqlite3_file*, sqlite3_int64 iOfst, void *p)". check-in: 115b8305 user: dan tags: experimental-mmap
16:28
Remove unnecessary code to round the size of a memory mapping to 4KB from os_unix.c. Rename SQLITE_IOERR_MREMAP to SQLITE_IOERR_MMAP. Fix other small issues in os_unix.c. check-in: dce35c01 user: dan tags: experimental-mmap
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to src/os.c.

140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
  DO_OS_MALLOC_TEST(id);
  return id->pMethods->xShmMap(id, iPage, pgsz, bExtend, pp);
}

int sqlite3OsFetch(sqlite3_file *id, i64 iOff, int iAmt, void **pp){
  return id->pMethods->xFetch(id, iOff, iAmt, pp);
}
int sqlite3OsUnfetch(sqlite3_file *id, void *p){
  return id->pMethods->xUnfetch(id, p);
}

/*
** The next group of routines are convenience wrappers around the
** VFS methods.
*/
int sqlite3OsOpen(







|
|







140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
  DO_OS_MALLOC_TEST(id);
  return id->pMethods->xShmMap(id, iPage, pgsz, bExtend, pp);
}

int sqlite3OsFetch(sqlite3_file *id, i64 iOff, int iAmt, void **pp){
  return id->pMethods->xFetch(id, iOff, iAmt, pp);
}
int sqlite3OsUnfetch(sqlite3_file *id, i64 iOff, void *p){
  return id->pMethods->xUnfetch(id, iOff, p);
}

/*
** The next group of routines are convenience wrappers around the
** VFS methods.
*/
int sqlite3OsOpen(

Changes to src/os.h.

256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
int sqlite3OsSectorSize(sqlite3_file *id);
int sqlite3OsDeviceCharacteristics(sqlite3_file *id);
int sqlite3OsShmMap(sqlite3_file *,int,int,int,void volatile **);
int sqlite3OsShmLock(sqlite3_file *id, int, int, int);
void sqlite3OsShmBarrier(sqlite3_file *id);
int sqlite3OsShmUnmap(sqlite3_file *id, int);
int sqlite3OsFetch(sqlite3_file *id, i64, int, void **);
int sqlite3OsUnfetch(sqlite3_file *, void *);


/* 
** Functions for accessing sqlite3_vfs methods 
*/
int sqlite3OsOpen(sqlite3_vfs *, const char *, sqlite3_file*, int, int *);
int sqlite3OsDelete(sqlite3_vfs *, const char *, int);







|







256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
int sqlite3OsSectorSize(sqlite3_file *id);
int sqlite3OsDeviceCharacteristics(sqlite3_file *id);
int sqlite3OsShmMap(sqlite3_file *,int,int,int,void volatile **);
int sqlite3OsShmLock(sqlite3_file *id, int, int, int);
void sqlite3OsShmBarrier(sqlite3_file *id);
int sqlite3OsShmUnmap(sqlite3_file *id, int);
int sqlite3OsFetch(sqlite3_file *id, i64, int, void **);
int sqlite3OsUnfetch(sqlite3_file *, i64, void *);


/* 
** Functions for accessing sqlite3_vfs methods 
*/
int sqlite3OsOpen(sqlite3_vfs *, const char *, sqlite3_file*, int, int *);
int sqlite3OsDelete(sqlite3_vfs *, const char *, int);

Changes to src/os_unix.c.

4587
4588
4589
4590
4591
4592
4593
4594
4595



4596
4597
4598
4599
4600
4601
4602
4603
4604
4605
4606
4607



4608
4609
4610
4611
4612
4613
4614
      pFd->nFetchOut++;
    }
  }
  return SQLITE_OK;
}

/*
** If the second argument is non-NULL, then this function releases a 
** reference obtained by an earlier call to unixFetch(). Or, if the second



** argument is NULL, then this function is being called to inform the VFS
** layer that, according to POSIX, any existing mapping may now be invalid
** and should be unmapped.
*/
static int unixUnfetch(sqlite3_file *fd, void *p){
  unixFile *pFd = (unixFile *)fd;   /* The underlying database file */

  /* If p==0 (unmap the entire file) then there must be no outstanding 
  ** xFetch references. Or, if p!=0 (meaning it is an xFetch reference),
  ** then there must be at least one outstanding.  */
  assert( (p==0)==(pFd->nFetchOut==0) );




  if( p ){
    pFd->nFetchOut--;
  }else{
    unixUnmapfile(pFd);
  }

  assert( pFd->nFetchOut>=0 );







|
|
>
>
>
|
|
|

|







>
>
>







4587
4588
4589
4590
4591
4592
4593
4594
4595
4596
4597
4598
4599
4600
4601
4602
4603
4604
4605
4606
4607
4608
4609
4610
4611
4612
4613
4614
4615
4616
4617
4618
4619
4620
      pFd->nFetchOut++;
    }
  }
  return SQLITE_OK;
}

/*
** If the third argument is non-NULL, then this function releases a 
** reference obtained by an earlier call to unixFetch(). The second
** argument passed to this function must be the same as the corresponding
** argument that was passed to the unixFetch() invocation. 
**
** Or, if the third argument is NULL, then this function is being called 
** to inform the VFS layer that, according to POSIX, any existing mapping 
** may now be invalid and should be unmapped.
*/
static int unixUnfetch(sqlite3_file *fd, i64 iOff, void *p){
  unixFile *pFd = (unixFile *)fd;   /* The underlying database file */

  /* If p==0 (unmap the entire file) then there must be no outstanding 
  ** xFetch references. Or, if p!=0 (meaning it is an xFetch reference),
  ** then there must be at least one outstanding.  */
  assert( (p==0)==(pFd->nFetchOut==0) );

  /* If p!=0, it must match the iOff value. */
  assert( p==0 || p==&((u8 *)pFd->pMapRegion)[iOff] );

  if( p ){
    pFd->nFetchOut--;
  }else{
    unixUnmapfile(pFd);
  }

  assert( pFd->nFetchOut>=0 );

Changes to src/pager.c.

3087
3088
3089
3090
3091
3092
3093
3094
3095
3096
3097
3098
3099
3100
3101
....
3866
3867
3868
3869
3870
3871
3872
3873
3874
3875
3876
3877
3878
3879
3880
....
3899
3900
3901
3902
3903
3904
3905
3906
3907
3908
3909
3910
3911
3912
3913
....
5091
5092
5093
5094
5095
5096
5097
5098
5099
5100
5101
5102
5103
5104
5105
....
5241
5242
5243
5244
5245
5246
5247
5248
5249
5250
5251
5252
5253
5254
5255
  ** the duplicate call is harmless.
  */
  sqlite3WalEndReadTransaction(pPager->pWal);

  rc = sqlite3WalBeginReadTransaction(pPager->pWal, &changed);
  if( rc!=SQLITE_OK || changed ){
    pager_reset(pPager);
    if( pPager->bUseFetch ) sqlite3OsUnfetch(pPager->fd, 0);
  }

  return rc;
}
#endif

/*
................................................................................
    *ppPage = p = pPager->pFree;
    pPager->pFree = p->pDirty;
    p->pDirty = 0;
    memset(p->pExtra, 0, pPager->nExtra);
  }else{
    *ppPage = p = (PgHdr *)sqlite3MallocZero(sizeof(PgHdr) + pPager->nExtra);
    if( p==0 ){
      sqlite3OsUnfetch(pPager->fd, pData);
      return SQLITE_NOMEM;
    }
    p->pExtra = (void *)&p[1];
    p->flags = PGHDR_MMAP;
    p->nRef = 1;
    p->pPager = pPager;
  }
................................................................................
static void pagerReleaseMapPage(PgHdr *pPg){
  Pager *pPager = pPg->pPager;
  pPager->nMmapOut--;
  pPg->pDirty = pPager->pFree;
  pPager->pFree = pPg;

  assert( pPager->fd->pMethods->iVersion>=3 );
  sqlite3OsUnfetch(pPager->fd, pPg->pData);
}

/*
** Free all PgHdr objects stored in the Pager.pFree list.
*/
static void pagerFreeMapHdrs(Pager *pPager){
  PgHdr *p;
................................................................................
        /* Unmap the database file. It is possible that external processes
        ** may have truncated the database file and then extended it back
        ** to its original size while this process was not holding a lock.
        ** In this case there may exist a Pager.pMap mapping that appears
        ** to be the right size but is not actually valid. Avoid this
        ** possibility by unmapping the db here. */
        if( pPager->bUseFetch ){
          sqlite3OsUnfetch(pPager->fd, 0);
        }
      }
    }

    /* If there is a WAL file in the file-system, open this database in WAL
    ** mode. Otherwise, the following function call is a no-op.
    */
................................................................................
      if( rc==SQLITE_OK && pData ){
        if( pPager->eState>PAGER_READER ){
          (void)sqlite3PcacheFetch(pPager->pPCache, pgno, 0, &pPg);
        }
        if( pPg==0 ){
          rc = pagerAcquireMapPage(pPager, pgno, pData, &pPg);
        }else{
          sqlite3OsUnfetch(pPager->fd, pData);
        }
        if( pPg ){
          assert( rc==SQLITE_OK );
          *ppPage = pPg;
          return SQLITE_OK;
        }
      }







|







 







|







 







|







 







|







 







|







3087
3088
3089
3090
3091
3092
3093
3094
3095
3096
3097
3098
3099
3100
3101
....
3866
3867
3868
3869
3870
3871
3872
3873
3874
3875
3876
3877
3878
3879
3880
....
3899
3900
3901
3902
3903
3904
3905
3906
3907
3908
3909
3910
3911
3912
3913
....
5091
5092
5093
5094
5095
5096
5097
5098
5099
5100
5101
5102
5103
5104
5105
....
5241
5242
5243
5244
5245
5246
5247
5248
5249
5250
5251
5252
5253
5254
5255
  ** the duplicate call is harmless.
  */
  sqlite3WalEndReadTransaction(pPager->pWal);

  rc = sqlite3WalBeginReadTransaction(pPager->pWal, &changed);
  if( rc!=SQLITE_OK || changed ){
    pager_reset(pPager);
    if( pPager->bUseFetch ) sqlite3OsUnfetch(pPager->fd, 0, 0);
  }

  return rc;
}
#endif

/*
................................................................................
    *ppPage = p = pPager->pFree;
    pPager->pFree = p->pDirty;
    p->pDirty = 0;
    memset(p->pExtra, 0, pPager->nExtra);
  }else{
    *ppPage = p = (PgHdr *)sqlite3MallocZero(sizeof(PgHdr) + pPager->nExtra);
    if( p==0 ){
      sqlite3OsUnfetch(pPager->fd, (i64)(pgno-1) * pPager->pageSize, pData);
      return SQLITE_NOMEM;
    }
    p->pExtra = (void *)&p[1];
    p->flags = PGHDR_MMAP;
    p->nRef = 1;
    p->pPager = pPager;
  }
................................................................................
static void pagerReleaseMapPage(PgHdr *pPg){
  Pager *pPager = pPg->pPager;
  pPager->nMmapOut--;
  pPg->pDirty = pPager->pFree;
  pPager->pFree = pPg;

  assert( pPager->fd->pMethods->iVersion>=3 );
  sqlite3OsUnfetch(pPager->fd, (i64)(pPg->pgno-1)*pPager->pageSize, pPg->pData);
}

/*
** Free all PgHdr objects stored in the Pager.pFree list.
*/
static void pagerFreeMapHdrs(Pager *pPager){
  PgHdr *p;
................................................................................
        /* Unmap the database file. It is possible that external processes
        ** may have truncated the database file and then extended it back
        ** to its original size while this process was not holding a lock.
        ** In this case there may exist a Pager.pMap mapping that appears
        ** to be the right size but is not actually valid. Avoid this
        ** possibility by unmapping the db here. */
        if( pPager->bUseFetch ){
          sqlite3OsUnfetch(pPager->fd, 0, 0);
        }
      }
    }

    /* If there is a WAL file in the file-system, open this database in WAL
    ** mode. Otherwise, the following function call is a no-op.
    */
................................................................................
      if( rc==SQLITE_OK && pData ){
        if( pPager->eState>PAGER_READER ){
          (void)sqlite3PcacheFetch(pPager->pPCache, pgno, 0, &pPg);
        }
        if( pPg==0 ){
          rc = pagerAcquireMapPage(pPager, pgno, pData, &pPg);
        }else{
          sqlite3OsUnfetch(pPager->fd, (i64)(pgno-1)*pPager->pageSize, pData);
        }
        if( pPg ){
          assert( rc==SQLITE_OK );
          *ppPage = pPg;
          return SQLITE_OK;
        }
      }

Changes to src/sqlite.h.in.

726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
  /* Methods above are valid for version 1 */
  int (*xShmMap)(sqlite3_file*, int iPg, int pgsz, int, void volatile**);
  int (*xShmLock)(sqlite3_file*, int offset, int n, int flags);
  void (*xShmBarrier)(sqlite3_file*);
  int (*xShmUnmap)(sqlite3_file*, int deleteFlag);
  /* Methods above are valid for version 2 */
  int (*xFetch)(sqlite3_file*, sqlite3_int64 iOfst, int iAmt, void **pp);
  int (*xUnfetch)(sqlite3_file*, void *p);
  /* Methods above are valid for version 3 */
  /* Additional methods may be added in future releases */
};

/*
** CAPI3REF: Standard File Control Opcodes
**







|







726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
  /* Methods above are valid for version 1 */
  int (*xShmMap)(sqlite3_file*, int iPg, int pgsz, int, void volatile**);
  int (*xShmLock)(sqlite3_file*, int offset, int n, int flags);
  void (*xShmBarrier)(sqlite3_file*);
  int (*xShmUnmap)(sqlite3_file*, int deleteFlag);
  /* Methods above are valid for version 2 */
  int (*xFetch)(sqlite3_file*, sqlite3_int64 iOfst, int iAmt, void **pp);
  int (*xUnfetch)(sqlite3_file*, sqlite3_int64 iOfst, void *p);
  /* Methods above are valid for version 3 */
  /* Additional methods may be added in future releases */
};

/*
** CAPI3REF: Standard File Control Opcodes
**