/ Check-in [fc0cabc1]
Login

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

Overview
Comment:Remove xShmGet/Size/Release from the sqlite3_vfs structure. Change the name of xShmPage to xShmMap. Remove some code that is now unused from os_unix.c and some of the test VFS implementations.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | experimental
Files: files | file ages | folders
SHA1: fc0cabc15c97dde6a852b4f07df6d30f1d2c04bc
User & Date: dan 2010-06-14 14:07:51
Context
2010-06-14
16:16
Add the new xShmMap (formerly xShmPage) to os_win.c. check-in: 13e7a824 user: dan tags: experimental
14:07
Remove xShmGet/Size/Release from the sqlite3_vfs structure. Change the name of xShmPage to xShmMap. Remove some code that is now unused from os_unix.c and some of the test VFS implementations. check-in: fc0cabc1 user: dan tags: experimental
11:49
Update some comments in wal.c. No code changes. check-in: 1ce9c92b user: dan tags: experimental
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to src/os.c.

    97     97   }
    98     98   int sqlite3OsDeviceCharacteristics(sqlite3_file *id){
    99     99     return id->pMethods->xDeviceCharacteristics(id);
   100    100   }
   101    101   int sqlite3OsShmOpen(sqlite3_file *id){
   102    102     return id->pMethods->xShmOpen(id);
   103    103   }
   104         -int sqlite3OsShmSize(sqlite3_file *id, int reqSize, int *pNewSize){
   105         -  return id->pMethods->xShmSize(id, reqSize, pNewSize);
   106         -}
   107         -int sqlite3OsShmGet(sqlite3_file *id,int reqSize,int *pSize,void volatile **pp){
   108         -  return id->pMethods->xShmGet(id, reqSize, pSize, pp);
   109         -}
   110         -int sqlite3OsShmRelease(sqlite3_file *id){
   111         -  return id->pMethods->xShmRelease(id);
   112         -}
   113    104   int sqlite3OsShmLock(sqlite3_file *id, int offset, int n, int flags){
   114    105     return id->pMethods->xShmLock(id, offset, n, flags);
   115    106   }
   116    107   void sqlite3OsShmBarrier(sqlite3_file *id){
   117    108     id->pMethods->xShmBarrier(id);
   118    109   }
   119    110   int sqlite3OsShmClose(sqlite3_file *id, int deleteFlag){
   120    111     return id->pMethods->xShmClose(id, deleteFlag);
   121    112   }
   122         -int sqlite3OsShmPage(
          113  +int sqlite3OsShmMap(
   123    114     sqlite3_file *id, 
   124    115     int iPage, 
   125    116     int pgsz, 
   126    117     int isWrite, 
   127    118     void volatile **pp
   128    119   ){
   129         -  return id->pMethods->xShmPage(id, iPage, pgsz, isWrite, pp);
          120  +  return id->pMethods->xShmMap(id, iPage, pgsz, isWrite, pp);
   130    121   }
   131    122   
   132    123   /*
   133    124   ** The next group of routines are convenience wrappers around the
   134    125   ** VFS methods.
   135    126   */
   136    127   int sqlite3OsOpen(

Changes to src/os.h.

   244    244   int sqlite3OsUnlock(sqlite3_file*, int);
   245    245   int sqlite3OsCheckReservedLock(sqlite3_file *id, int *pResOut);
   246    246   int sqlite3OsFileControl(sqlite3_file*,int,void*);
   247    247   #define SQLITE_FCNTL_DB_UNCHANGED 0xca093fa0
   248    248   int sqlite3OsSectorSize(sqlite3_file *id);
   249    249   int sqlite3OsDeviceCharacteristics(sqlite3_file *id);
   250    250   int sqlite3OsShmOpen(sqlite3_file *id);
   251         -int sqlite3OsShmSize(sqlite3_file *id, int, int*);
   252         -int sqlite3OsShmGet(sqlite3_file *id, int, int*, void volatile**);
   253         -int sqlite3OsShmRelease(sqlite3_file *id);
   254    251   int sqlite3OsShmLock(sqlite3_file *id, int, int, int);
   255    252   void sqlite3OsShmBarrier(sqlite3_file *id);
   256    253   int sqlite3OsShmClose(sqlite3_file *id, int);
   257         -int sqlite3OsShmPage(sqlite3_file *,int,int,int,void volatile **);
          254  +int sqlite3OsShmMap(sqlite3_file *,int,int,int,void volatile **);
   258    255   
   259    256   /* 
   260    257   ** Functions for accessing sqlite3_vfs methods 
   261    258   */
   262    259   int sqlite3OsOpen(sqlite3_vfs *, const char *, sqlite3_file*, int, int *);
   263    260   int sqlite3OsDelete(sqlite3_vfs *, const char *, int);
   264    261   int sqlite3OsAccess(sqlite3_vfs *, const char *, int, int *pResOut);

Changes to src/os_unix.c.

  3124   3124   ** 
  3125   3125   **      fid
  3126   3126   **      zFilename
  3127   3127   **
  3128   3128   ** Either unixShmNode.mutex must be held or unixShmNode.nRef==0 and
  3129   3129   ** unixMutexHeld() is true when reading or writing any other field
  3130   3130   ** in this structure.
  3131         -**
  3132         -** To avoid deadlocks, mutex and mutexBuf are always released in the
  3133         -** reverse order that they are acquired.  mutexBuf is always acquired
  3134         -** first and released last.  This invariant is check by asserting
  3135         -** sqlite3_mutex_notheld() on mutex whenever mutexBuf is acquired or
  3136         -** released.
  3137   3131   */
  3138   3132   struct unixShmNode {
  3139   3133     unixInodeInfo *pInode;     /* unixInodeInfo that owns this SHM node */
  3140   3134     sqlite3_mutex *mutex;      /* Mutex to access this object */
  3141         -  sqlite3_mutex *mutexBuf;   /* Mutex to access zBuf[] */
  3142   3135     char *zFilename;           /* Name of the mmapped file */
  3143   3136     int h;                     /* Open file descriptor */
  3144         -
  3145         -  int szMap;                 /* Size of the mapping into memory */
  3146         -  char *pMMapBuf;            /* Where currently mmapped().  NULL if unmapped */
  3147         -
  3148         -  int pgsz;                  /* Size of shared-memory pages */
  3149         -  int nPage;                 /* Size of array apPage */
  3150         -  char **apPage;             /* Array of mapped shared-memory pages */
  3151         -
         3137  +  int szRegion;              /* Size of shared-memory regions */
         3138  +  int nRegion;               /* Size of array apRegion */
         3139  +  char **apRegion;           /* Array of mapped shared-memory regions */
  3152   3140     int nRef;                  /* Number of unixShm objects pointing to this */
  3153   3141     unixShm *pFirst;           /* All unixShm objects pointing to this */
  3154   3142   #ifdef SQLITE_DEBUG
  3155   3143     u8 exclMask;               /* Mask of exclusive locks held */
  3156   3144     u8 sharedMask;             /* Mask of shared locks held */
  3157   3145     u8 nextShmId;              /* Next available unixShm.id value */
  3158   3146   #endif
................................................................................
  3171   3159   ** All other fields are read/write.  The unixShm.pFile->mutex must be held
  3172   3160   ** while accessing any read/write fields.
  3173   3161   */
  3174   3162   struct unixShm {
  3175   3163     unixShmNode *pShmNode;     /* The underlying unixShmNode object */
  3176   3164     unixShm *pNext;            /* Next unixShm with the same unixShmNode */
  3177   3165     u8 hasMutex;               /* True if holding the unixShmNode mutex */
  3178         -  u8 hasMutexBuf;            /* True if holding pFile->mutexBuf */
  3179   3166     u16 sharedMask;            /* Mask of shared locks held */
  3180   3167     u16 exclMask;              /* Mask of exclusive locks held */
  3181   3168   #ifdef SQLITE_DEBUG
  3182   3169     u8 id;                     /* Id of this connection within its unixShmNode */
  3183   3170   #endif
  3184   3171   };
  3185   3172   
................................................................................
  3271   3258   static void unixShmPurge(unixFile *pFd){
  3272   3259     unixShmNode *p = pFd->pInode->pShmNode;
  3273   3260     assert( unixMutexHeld() );
  3274   3261     if( p && p->nRef==0 ){
  3275   3262       int i;
  3276   3263       assert( p->pInode==pFd->pInode );
  3277   3264       if( p->mutex ) sqlite3_mutex_free(p->mutex);
  3278         -    if( p->mutexBuf ) sqlite3_mutex_free(p->mutexBuf);
  3279         -    if( p->pMMapBuf ) munmap(p->pMMapBuf, p->szMap);
  3280         -    for(i=0; i<p->nPage; i++){
  3281         -      munmap(p->apPage[i], p->pgsz);
         3265  +    for(i=0; i<p->nRegion; i++){
         3266  +      munmap(p->apRegion[i], p->szRegion);
  3282   3267       }
  3283         -    sqlite3_free(p->apPage);
         3268  +    sqlite3_free(p->apRegion);
  3284   3269       if( p->h>=0 ) close(p->h);
  3285   3270       p->pInode->pShmNode = 0;
  3286   3271       sqlite3_free(p);
  3287   3272     }
  3288   3273   }
  3289   3274   
  3290   3275   /* Forward reference */
................................................................................
  3352   3337       pDbFd->pInode->pShmNode = pShmNode;
  3353   3338       pShmNode->pInode = pDbFd->pInode;
  3354   3339       pShmNode->mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_FAST);
  3355   3340       if( pShmNode->mutex==0 ){
  3356   3341         rc = SQLITE_NOMEM;
  3357   3342         goto shm_open_err;
  3358   3343       }
  3359         -    pShmNode->mutexBuf = sqlite3_mutex_alloc(SQLITE_MUTEX_FAST);
  3360         -    if( pShmNode->mutexBuf==0 ){
  3361         -      rc = SQLITE_NOMEM;
  3362         -      goto shm_open_err;
  3363         -    }
  3364   3344   
  3365   3345       pShmNode->h = open(pShmNode->zFilename, O_RDWR|O_CREAT, 0664);
  3366   3346       if( pShmNode->h<0 ){
  3367   3347         rc = SQLITE_CANTOPEN_BKPT;
  3368   3348         goto shm_open_err;
  3369   3349       }
  3370   3350   
................................................................................
  3427   3407     /* Remove connection p from the set of connections associated
  3428   3408     ** with pShmNode */
  3429   3409     sqlite3_mutex_enter(pShmNode->mutex);
  3430   3410     for(pp=&pShmNode->pFirst; (*pp)!=p; pp = &(*pp)->pNext){}
  3431   3411     *pp = p->pNext;
  3432   3412   
  3433   3413     /* Free the connection p */
  3434         -  assert( p->hasMutexBuf==0 );
  3435   3414     sqlite3_free(p);
  3436   3415     pDbFd->pShm = 0;
  3437   3416     sqlite3_mutex_leave(pShmNode->mutex);
  3438   3417   
  3439   3418     /* If pShmNode->nRef has reached 0, then close the underlying
  3440   3419     ** shared-memory file, too */
  3441   3420     unixEnterMutex();
................................................................................
  3445   3424       if( deleteFlag ) unlink(pShmNode->zFilename);
  3446   3425       unixShmPurge(pDbFd);
  3447   3426     }
  3448   3427     unixLeaveMutex();
  3449   3428   
  3450   3429     return SQLITE_OK;
  3451   3430   }
  3452         -
  3453         -/*
  3454         -** Changes the size of the underlying storage for  a shared-memory segment.
  3455         -**
  3456         -** The reqSize parameter is the new requested size of the shared memory.
  3457         -** This implementation is free to increase the shared memory size to
  3458         -** any amount greater than or equal to reqSize.  If the shared memory is
  3459         -** already as big or bigger as reqSize, this routine is a no-op.
  3460         -**
  3461         -** The reqSize parameter is the minimum size requested.  The implementation
  3462         -** is free to expand the storage to some larger amount if it chooses.
  3463         -*/
  3464         -static int unixShmSize(
  3465         -  sqlite3_file *fd,         /* The open database file holding SHM */
  3466         -  int reqSize,              /* Requested size.  -1 for query only */
  3467         -  int *pNewSize             /* Write new size here */
  3468         -){
  3469         -  unixFile *pDbFd = (unixFile*)fd;
  3470         -  unixShm *p = pDbFd->pShm;
  3471         -  unixShmNode *pShmNode = p->pShmNode;
  3472         -  int rc = SQLITE_OK;
  3473         -  struct stat sStat;
  3474         -
  3475         -  assert( pShmNode==pDbFd->pInode->pShmNode );
  3476         -  assert( pShmNode->pInode==pDbFd->pInode );
  3477         -
  3478         -  while( 1 ){
  3479         -    if( fstat(pShmNode->h, &sStat)==0 ){
  3480         -      *pNewSize = (int)sStat.st_size;
  3481         -      if( reqSize<=(int)sStat.st_size ) break;
  3482         -    }else{
  3483         -      *pNewSize = 0;
  3484         -      rc = SQLITE_IOERR_SHMSIZE;
  3485         -      break;
  3486         -    }
  3487         -    rc = ftruncate(pShmNode->h, reqSize);
  3488         -    reqSize = -1;
  3489         -  }
  3490         -  return rc;
  3491         -}
  3492         -
  3493         -/*
  3494         -** Release the lock held on the shared memory segment to that other
  3495         -** threads are free to resize it if necessary.
  3496         -**
  3497         -** If the lock is not currently held, this routine is a harmless no-op.
  3498         -**
  3499         -** If the shared-memory object is in lock state RECOVER, then we do not
  3500         -** really want to release the lock, so in that case too, this routine
  3501         -** is a no-op.
  3502         -*/
  3503         -static int unixShmRelease(sqlite3_file *fd){
  3504         -  unixFile *pDbFd = (unixFile*)fd;
  3505         -  unixShm *p = pDbFd->pShm;
  3506         -
  3507         -  if( p->hasMutexBuf ){
  3508         -    assert( sqlite3_mutex_notheld(p->pShmNode->mutex) );
  3509         -    sqlite3_mutex_leave(p->pShmNode->mutexBuf);
  3510         -    p->hasMutexBuf = 0;
  3511         -  }
  3512         -  return SQLITE_OK;
  3513         -}
  3514         -
  3515         -/*
  3516         -** Map the shared storage into memory. 
  3517         -**
  3518         -** If reqMapSize is positive, then an attempt is made to make the
  3519         -** mapping at least reqMapSize bytes in size.  However, the mapping
  3520         -** will never be larger than the size of the underlying shared memory
  3521         -** as set by prior calls to xShmSize().  
  3522         -**
  3523         -** *ppBuf is made to point to the memory which is a mapping of the
  3524         -** underlying storage.  A mutex is acquired to prevent other threads
  3525         -** from running while *ppBuf is in use in order to prevent other threads
  3526         -** remapping *ppBuf out from under this thread.  The unixShmRelease()
  3527         -** call will release the mutex.  However, if the lock state is CHECKPOINT,
  3528         -** the mutex is not acquired because CHECKPOINT will never remap the
  3529         -** buffer.  RECOVER might remap, though, so CHECKPOINT will acquire
  3530         -** the mutex if and when it promotes to RECOVER.
  3531         -**
  3532         -** RECOVER needs to be atomic.  The same mutex that prevents *ppBuf from
  3533         -** being remapped also prevents more than one thread from being in
  3534         -** RECOVER at a time.  But, RECOVER sometimes wants to remap itself.
  3535         -** To prevent RECOVER from losing its lock while remapping, the
  3536         -** mutex is not released by unixShmRelease() when in RECOVER.
  3537         -**
  3538         -** *pNewMapSize is set to the size of the mapping.  Usually *pNewMapSize
  3539         -** will be reqMapSize or larger, though it could be smaller if the
  3540         -** underlying shared memory has never been enlarged to reqMapSize bytes
  3541         -** by prior calls to xShmSize().
  3542         -**
  3543         -** *ppBuf might be NULL and zero if no space has
  3544         -** yet been allocated to the underlying storage.
  3545         -*/
  3546         -static int unixShmGet(
  3547         -  sqlite3_file *fd,        /* Database file holding shared memory */
  3548         -  int reqMapSize,          /* Requested size of mapping. -1 means don't care */
  3549         -  int *pNewMapSize,        /* Write new size of mapping here */
  3550         -  void volatile **ppBuf    /* Write mapping buffer origin here */
  3551         -){
  3552         -  unixFile *pDbFd = (unixFile*)fd;
  3553         -  unixShm *p = pDbFd->pShm;
  3554         -  unixShmNode *pShmNode = p->pShmNode;
  3555         -  int rc = SQLITE_OK;
  3556         -
  3557         -  assert( pShmNode==pDbFd->pInode->pShmNode );
  3558         -  assert( pShmNode->pInode==pDbFd->pInode );
  3559         -
  3560         -  if( p->hasMutexBuf==0 ){
  3561         -    assert( sqlite3_mutex_notheld(pShmNode->mutex) );
  3562         -    sqlite3_mutex_enter(pShmNode->mutexBuf);
  3563         -    p->hasMutexBuf = 1;
  3564         -  }
  3565         -  sqlite3_mutex_enter(pShmNode->mutex);
  3566         -  if( pShmNode->szMap==0 || reqMapSize>pShmNode->szMap ){
  3567         -    int actualSize;
  3568         -    if( unixShmSize(fd, -1, &actualSize)!=SQLITE_OK ){
  3569         -      actualSize = 0;
  3570         -    }
  3571         -    reqMapSize = actualSize;
  3572         -    if( pShmNode->pMMapBuf || reqMapSize<=0 ){
  3573         -      munmap(pShmNode->pMMapBuf, pShmNode->szMap);
  3574         -    }
  3575         -    if( reqMapSize>0 ){
  3576         -      pShmNode->pMMapBuf = mmap(0, reqMapSize, PROT_READ|PROT_WRITE, MAP_SHARED,
  3577         -                             pShmNode->h, 0);
  3578         -      pShmNode->szMap = pShmNode->pMMapBuf ? reqMapSize : 0;
  3579         -    }else{
  3580         -      pShmNode->pMMapBuf = 0;
  3581         -      pShmNode->szMap = 0;
  3582         -    }
  3583         -  }
  3584         -  *pNewMapSize = pShmNode->szMap;
  3585         -  *ppBuf = pShmNode->pMMapBuf;
  3586         -  sqlite3_mutex_leave(pShmNode->mutex);
  3587         -  if( *ppBuf==0 ){
  3588         -    /* Do not hold the mutex if a NULL pointer is being returned. */
  3589         -    unixShmRelease(fd);
  3590         -  }
  3591         -  return rc;
  3592         -}
  3593         -
  3594   3431   
  3595   3432   /*
  3596   3433   ** Change the lock state for a shared-memory segment.
  3597   3434   **
  3598   3435   ** Note that the relationship between SHAREd and EXCLUSIVE locks is a little
  3599   3436   ** different here than in posix.  In xShmLock(), one can go from unlocked
  3600   3437   ** to shared and back or from unlocked to exclusive and back.  But one may
................................................................................
  3707   3544   /*
  3708   3545   ** Implement a memory barrier or memory fence on shared memory.  
  3709   3546   **
  3710   3547   ** All loads and stores begun before the barrier must complete before
  3711   3548   ** any load or store begun after the barrier.
  3712   3549   */
  3713   3550   static void unixShmBarrier(
  3714         -  sqlite3_file *fd           /* Database file holding the shared memory */
         3551  +  sqlite3_file *fd                /* Database file holding the shared memory */
  3715   3552   ){
  3716   3553     unixEnterMutex();
  3717   3554     unixLeaveMutex();
  3718   3555   }
  3719   3556   
         3557  +/*
         3558  +** This function is called to obtain a pointer to region iRegion of the 
         3559  +** shared-memory associated with the database file fd. Shared-memory regions 
         3560  +** are numbered starting from zero. Each shared-memory region is szRegion 
         3561  +** bytes in size.
         3562  +**
         3563  +** If an error occurs, an error code is returned and *pp is set to NULL.
         3564  +**
         3565  +** Otherwise, if the isWrite parameter is 0 and the requested shared-memory
         3566  +** region has not been allocated (by any client, including one running in a
         3567  +** separate process), then *pp is set to NULL and SQLITE_OK returned. If 
         3568  +** isWrite is non-zero and the requested shared-memory region has not yet 
         3569  +** been allocated, it is allocated by this function.
         3570  +**
         3571  +** If the shared-memory region has already been allocated or is allocated by
         3572  +** this call as described above, then it is mapped into this processes 
         3573  +** address space (if it is not already), *pp is set to point to the mapped 
         3574  +** memory and SQLITE_OK returned.
         3575  +*/
  3720   3576   static int unixShmPage(
  3721   3577     sqlite3_file *fd,               /* Handle open on database file */
  3722         -  int iPage,                      /* Page to retrieve */
  3723         -  int pgsz,                       /* Size of pages */
         3578  +  int iRegion,                    /* Region to retrieve */
         3579  +  int szRegion,                   /* Size of regions */
  3724   3580     int isWrite,                    /* True to extend file if necessary */
  3725   3581     void volatile **pp              /* OUT: Mapped memory */
  3726   3582   ){
  3727   3583     unixFile *pDbFd = (unixFile*)fd;
  3728   3584     unixShm *p = pDbFd->pShm;
  3729   3585     unixShmNode *pShmNode = p->pShmNode;
  3730   3586     int rc = SQLITE_OK;
  3731   3587   
  3732         -  assert( p->hasMutexBuf==0 );
  3733         -  sqlite3_mutex_enter(pShmNode->mutexBuf);
  3734         -  assert( pgsz==pShmNode->pgsz || pShmNode->nPage==0 );
         3588  +  sqlite3_mutex_enter(pShmNode->mutex);
         3589  +  assert( szRegion==pShmNode->szRegion || pShmNode->nRegion==0 );
  3735   3590   
  3736         -  if( pShmNode->nPage<=iPage ){
  3737         -    char **apNew;                 /* New apPage[] array */
  3738         -    int nByte = (iPage+1)*pgsz;   /* Minimum required file size */
  3739         -    struct stat sStat;
         3591  +  if( pShmNode->nRegion<=iRegion ){
         3592  +    char **apNew;                      /* New apRegion[] array */
         3593  +    int nByte = (iRegion+1)*szRegion;  /* Minimum required file size */
         3594  +    struct stat sStat;                 /* Used by fstat() */
  3740   3595   
  3741         -    pShmNode->pgsz = pgsz;
         3596  +    pShmNode->szRegion = szRegion;
  3742   3597   
  3743         -    /* Make sure the underlying file is large enough (or fail) */
         3598  +    /* The requested region is not mapped into this processes address space.
         3599  +    ** Check to see if it has been allocated (i.e. if the wal-index file is
         3600  +    ** large enough to contain the requested region).
         3601  +    */
  3744   3602       if( fstat(pShmNode->h, &sStat) ){
  3745   3603         rc = SQLITE_IOERR_SHMSIZE;
  3746   3604         goto shmpage_out;
  3747         -    }else if( sStat.st_size<nByte ){
         3605  +    }
         3606  +
         3607  +    if( sStat.st_size<nByte ){
         3608  +      /* The requested memory region does not exist. If isWrite is set to
         3609  +      ** zero, exit early. *pp will be set to NULL and SQLITE_OK returned.
         3610  +      **
         3611  +      ** Alternatively, if isWrite is non-zero, use ftruncate() to allocate
         3612  +      ** the requested memory region.
         3613  +      */
  3748   3614         if( !isWrite ) goto shmpage_out;
  3749   3615         if( ftruncate(pShmNode->h, nByte) ){
  3750   3616           rc = SQLITE_IOERR_SHMSIZE;
  3751   3617           goto shmpage_out;
  3752   3618         }  
  3753   3619       }
  3754   3620   
  3755         -    apNew = (char**)sqlite3_realloc(pShmNode->apPage, (iPage+1)*sizeof(char *));
         3621  +    /* Map the requested memory region into this processes address space. */
         3622  +    apNew = (char **)sqlite3_realloc(
         3623  +        pShmNode->apRegion, (iRegion+1)*sizeof(char *)
         3624  +    );
  3756   3625       if( !apNew ){
  3757   3626         rc = SQLITE_IOERR_NOMEM;
  3758   3627         goto shmpage_out;
  3759   3628       }
  3760         -    pShmNode->apPage = apNew;
  3761         -
  3762         -    while(pShmNode->nPage<=iPage){
  3763         -      void *pMem = mmap(
  3764         -          0, pgsz, PROT_READ|PROT_WRITE, MAP_SHARED, pShmNode->h, iPage*pgsz
         3629  +    pShmNode->apRegion = apNew;
         3630  +    while(pShmNode->nRegion<=iRegion){
         3631  +      void *pMem = mmap(0, szRegion, PROT_READ|PROT_WRITE, 
         3632  +          MAP_SHARED, pShmNode->h, iRegion*szRegion
  3765   3633         );
  3766   3634         if( pMem==MAP_FAILED ){
  3767         -        assert(0);
  3768   3635           rc = SQLITE_IOERR;
  3769   3636           goto shmpage_out;
  3770   3637         }
  3771         -      pShmNode->apPage[pShmNode->nPage] = pMem;
  3772         -      pShmNode->nPage++;
         3638  +      pShmNode->apRegion[pShmNode->nRegion] = pMem;
         3639  +      pShmNode->nRegion++;
  3773   3640       }
  3774   3641     }
  3775   3642   
  3776   3643   shmpage_out:
  3777         -  if( pShmNode->nPage>iPage ){
  3778         -    *pp = pShmNode->apPage[iPage];
         3644  +  if( pShmNode->nRegion>iRegion ){
         3645  +    *pp = pShmNode->apRegion[iRegion];
  3779   3646     }else{
  3780   3647       *pp = 0;
  3781   3648     }
  3782         -  sqlite3_mutex_leave(pShmNode->mutexBuf);
         3649  +  sqlite3_mutex_leave(pShmNode->mutex);
  3783   3650     return rc;
  3784   3651   }
  3785   3652   
  3786   3653   #else
  3787   3654   # define unixShmOpen    0
  3788         -# define unixShmSize    0
  3789         -# define unixShmGet     0
  3790         -# define unixShmRelease 0
  3791   3655   # define unixShmLock    0
  3792   3656   # define unixShmBarrier 0
  3793   3657   # define unixShmClose   0
  3794   3658   # define unixShmPage    0
  3795   3659   #endif /* #ifndef SQLITE_OMIT_WAL */
  3796   3660   
  3797   3661   /*
................................................................................
  3846   3710      LOCK,                       /* xLock */                                   \
  3847   3711      UNLOCK,                     /* xUnlock */                                 \
  3848   3712      CKLOCK,                     /* xCheckReservedLock */                      \
  3849   3713      unixFileControl,            /* xFileControl */                            \
  3850   3714      unixSectorSize,             /* xSectorSize */                             \
  3851   3715      unixDeviceCharacteristics,  /* xDeviceCapabilities */                     \
  3852   3716      unixShmOpen,                /* xShmOpen */                                \
  3853         -   unixShmSize,                /* xShmSize */                                \
  3854         -   unixShmGet,                 /* xShmGet */                                 \
  3855         -   unixShmRelease,             /* xShmRelease */                             \
  3856   3717      unixShmLock,                /* xShmLock */                                \
  3857   3718      unixShmBarrier,             /* xShmBarrier */                             \
  3858   3719      unixShmClose,               /* xShmClose */                               \
  3859   3720      unixShmPage                 /* xShmPage */                                \
  3860   3721   };                                                                           \
  3861   3722   static const sqlite3_io_methods *FINDER##Impl(const char *z, unixFile *p){   \
  3862   3723     UNUSED_PARAMETER(z); UNUSED_PARAMETER(p);                                  \

Changes to src/sqlite.h.in.

   656    656     int (*xUnlock)(sqlite3_file*, int);
   657    657     int (*xCheckReservedLock)(sqlite3_file*, int *pResOut);
   658    658     int (*xFileControl)(sqlite3_file*, int op, void *pArg);
   659    659     int (*xSectorSize)(sqlite3_file*);
   660    660     int (*xDeviceCharacteristics)(sqlite3_file*);
   661    661     /* Methods above are valid for version 1 */
   662    662     int (*xShmOpen)(sqlite3_file*);
   663         -  int (*xShmSize)(sqlite3_file*, int reqSize, int *pNewSize);
   664         -  int (*xShmGet)(sqlite3_file*, int reqSize, int *pSize, void volatile**);
   665         -  int (*xShmRelease)(sqlite3_file*);
   666    663     int (*xShmLock)(sqlite3_file*, int offset, int n, int flags);
   667    664     void (*xShmBarrier)(sqlite3_file*);
   668    665     int (*xShmClose)(sqlite3_file*, int deleteFlag);
   669         -  int (*xShmPage)(sqlite3_file*, int iPage, int pgsz, int, void volatile**);
          666  +  int (*xShmMap)(sqlite3_file*, int iPage, int pgsz, int, void volatile**);
   670    667     /* Methods above are valid for version 2 */
   671    668     /* Additional methods may be added in future releases */
   672    669   };
   673    670   
   674    671   /*
   675    672   ** CAPI3REF: Standard File Control Opcodes
   676    673   **

Changes to src/test6.c.

   522    522   
   523    523   /*
   524    524   ** Pass-throughs for WAL support.
   525    525   */
   526    526   static int cfShmOpen(sqlite3_file *pFile){
   527    527     return sqlite3OsShmOpen(((CrashFile*)pFile)->pRealFile);
   528    528   }
   529         -static int cfShmSize(sqlite3_file *pFile, int reqSize, int *pNew){
   530         -  return sqlite3OsShmSize(((CrashFile*)pFile)->pRealFile, reqSize, pNew);
   531         -}
   532         -static int cfShmGet(
   533         -  sqlite3_file *pFile,
   534         -  int reqSize,
   535         -  int *pSize,
   536         -  void volatile **pp
   537         -){
   538         -  return sqlite3OsShmGet(((CrashFile*)pFile)->pRealFile, reqSize, pSize, pp);
   539         -}
   540         -static int cfShmRelease(sqlite3_file *pFile){
   541         -  return sqlite3OsShmRelease(((CrashFile*)pFile)->pRealFile);
   542         -}
   543    529   static int cfShmLock(sqlite3_file *pFile, int ofst, int n, int flags){
   544    530     return sqlite3OsShmLock(((CrashFile*)pFile)->pRealFile, ofst, n, flags);
   545    531   }
   546    532   static void cfShmBarrier(sqlite3_file *pFile){
   547    533     sqlite3OsShmBarrier(((CrashFile*)pFile)->pRealFile);
   548    534   }
   549    535   static int cfShmClose(sqlite3_file *pFile, int delFlag){
   550    536     return sqlite3OsShmClose(((CrashFile*)pFile)->pRealFile, delFlag);
   551    537   }
   552         -static int cfShmPage(
          538  +static int cfShmMap(
   553    539     sqlite3_file *pFile,            /* Handle open on database file */
   554         -  int iPage,                      /* Page to retrieve */
   555         -  int pgsz,                       /* Size of pages */
          540  +  int iRegion,                    /* Region to retrieve */
          541  +  int sz,                         /* Size of regions */
   556    542     int w,                          /* True to extend file if necessary */
   557    543     void volatile **pp              /* OUT: Mapped memory */
   558    544   ){
   559         -  return sqlite3OsShmPage(((CrashFile*)pFile)->pRealFile, iPage, pgsz, w, pp);
          545  +  return sqlite3OsShmMap(((CrashFile*)pFile)->pRealFile, iRegion, sz, w, pp);
   560    546   }
   561         -
   562    547   
   563    548   static const sqlite3_io_methods CrashFileVtab = {
   564    549     2,                            /* iVersion */
   565    550     cfClose,                      /* xClose */
   566    551     cfRead,                       /* xRead */
   567    552     cfWrite,                      /* xWrite */
   568    553     cfTruncate,                   /* xTruncate */
................................................................................
   571    556     cfLock,                       /* xLock */
   572    557     cfUnlock,                     /* xUnlock */
   573    558     cfCheckReservedLock,          /* xCheckReservedLock */
   574    559     cfFileControl,                /* xFileControl */
   575    560     cfSectorSize,                 /* xSectorSize */
   576    561     cfDeviceCharacteristics,      /* xDeviceCharacteristics */
   577    562     cfShmOpen,                    /* xShmOpen */
   578         -  cfShmSize,                    /* xShmSize */
   579         -  cfShmGet,                     /* xShmGet */
   580         -  cfShmRelease,                 /* xShmRelease */
   581    563     cfShmLock,                    /* xShmLock */
   582    564     cfShmBarrier,                 /* xShmBarrier */
   583    565     cfShmClose,                   /* xShmClose */
   584         -  cfShmPage                     /* xShmPage */
          566  +  cfShmMap                      /* xShmMap */
   585    567   };
   586    568   
   587    569   /*
   588    570   ** Application data for the crash VFS
   589    571   */
   590    572   struct crashAppData {
   591    573     sqlite3_vfs *pOrig;                   /* Wrapped vfs structure */

Changes to src/test_devsym.c.

    47     47   static int devsymLock(sqlite3_file*, int);
    48     48   static int devsymUnlock(sqlite3_file*, int);
    49     49   static int devsymCheckReservedLock(sqlite3_file*, int *);
    50     50   static int devsymFileControl(sqlite3_file*, int op, void *pArg);
    51     51   static int devsymSectorSize(sqlite3_file*);
    52     52   static int devsymDeviceCharacteristics(sqlite3_file*);
    53     53   static int devsymShmOpen(sqlite3_file*);
    54         -static int devsymShmSize(sqlite3_file*,int,int*);
    55         -static int devsymShmGet(sqlite3_file*,int,int*,volatile void**);
    56         -static int devsymShmRelease(sqlite3_file*);
    57     54   static int devsymShmLock(sqlite3_file*,int,int,int);
    58     55   static void devsymShmBarrier(sqlite3_file*);
    59     56   static int devsymShmClose(sqlite3_file*,int);
    60         -static int devsymShmPage(sqlite3_file*,int,int,int, void volatile **);
           57  +static int devsymShmMap(sqlite3_file*,int,int,int, void volatile **);
    61     58   
    62     59   /*
    63     60   ** Method declarations for devsym_vfs.
    64     61   */
    65     62   static int devsymOpen(sqlite3_vfs*, const char *, sqlite3_file*, int , int *);
    66     63   static int devsymDelete(sqlite3_vfs*, const char *zName, int syncDir);
    67     64   static int devsymAccess(sqlite3_vfs*, const char *zName, int flags, int *);
................................................................................
   117    114     devsymLock,                       /* xLock */
   118    115     devsymUnlock,                     /* xUnlock */
   119    116     devsymCheckReservedLock,          /* xCheckReservedLock */
   120    117     devsymFileControl,                /* xFileControl */
   121    118     devsymSectorSize,                 /* xSectorSize */
   122    119     devsymDeviceCharacteristics,      /* xDeviceCharacteristics */
   123    120     devsymShmOpen,                    /* xShmOpen */
   124         -  devsymShmSize,                    /* xShmSize */
   125         -  devsymShmGet,                     /* xShmGet */
   126         -  devsymShmRelease,                 /* xShmRelease */
   127    121     devsymShmLock,                    /* xShmLock */
   128    122     devsymShmBarrier,                 /* xShmBarrier */
   129    123     devsymShmClose,                   /* xShmClose */
   130         -  devsymShmPage                     /* xShmPage */
          124  +  devsymShmMap                     /* xShmMap */
   131    125   };
   132    126   
   133    127   struct DevsymGlobal {
   134    128     sqlite3_vfs *pVfs;
   135    129     int iDeviceChar;
   136    130     int iSectorSize;
   137    131   };
................................................................................
   244    238   /*
   245    239   ** Shared-memory methods are all pass-thrus.
   246    240   */
   247    241   static int devsymShmOpen(sqlite3_file *pFile){
   248    242     devsym_file *p = (devsym_file *)pFile;
   249    243     return sqlite3OsShmOpen(p->pReal);
   250    244   }
   251         -static int devsymShmSize(sqlite3_file *pFile, int reqSize, int *pSize){
   252         -  devsym_file *p = (devsym_file *)pFile;
   253         -  return sqlite3OsShmSize(p->pReal, reqSize, pSize);
   254         -}
   255         -static int devsymShmGet(
   256         -  sqlite3_file *pFile,
   257         -  int reqSz,
   258         -  int *pSize,
   259         -  void volatile **pp
   260         -){
   261         -  devsym_file *p = (devsym_file *)pFile;
   262         -  return sqlite3OsShmGet(p->pReal, reqSz, pSize, pp);
   263         -}
   264         -static int devsymShmRelease(sqlite3_file *pFile){
   265         -  devsym_file *p = (devsym_file *)pFile;
   266         -  return sqlite3OsShmRelease(p->pReal);
   267         -}
   268    245   static int devsymShmLock(sqlite3_file *pFile, int ofst, int n, int flags){
   269    246     devsym_file *p = (devsym_file *)pFile;
   270    247     return sqlite3OsShmLock(p->pReal, ofst, n, flags);
   271    248   }
   272    249   static void devsymShmBarrier(sqlite3_file *pFile){
   273    250     devsym_file *p = (devsym_file *)pFile;
   274    251     sqlite3OsShmBarrier(p->pReal);
   275    252   }
   276    253   static int devsymShmClose(sqlite3_file *pFile, int delFlag){
   277    254     devsym_file *p = (devsym_file *)pFile;
   278    255     return sqlite3OsShmClose(p->pReal, delFlag);
   279    256   }
   280         -static int devsymShmPage(
          257  +static int devsymShmMap(
   281    258     sqlite3_file *pFile, 
   282         -  int iPage, 
   283         -  int pgsz, 
          259  +  int iRegion, 
          260  +  int szRegion, 
   284    261     int isWrite, 
   285    262     void volatile **pp
   286    263   ){
   287    264     devsym_file *p = (devsym_file *)pFile;
   288         -  return sqlite3OsShmPage(p->pReal, iPage, pgsz, isWrite, pp);
          265  +  return sqlite3OsShmMap(p->pReal, iRegion, szRegion, isWrite, pp);
   289    266   }
   290    267   
   291    268   
   292    269   
   293    270   /*
   294    271   ** Open an devsym file handle.
   295    272   */

Changes to src/test_osinst.c.

    96     96   #define OS_SLEEP             16
    97     97   #define OS_SYNC              17
    98     98   #define OS_TRUNCATE          18
    99     99   #define OS_UNLOCK            19
   100    100   #define OS_WRITE             20
   101    101   #define OS_SHMOPEN           21
   102    102   #define OS_SHMCLOSE          22
   103         -#define OS_SHMGET            23
   104         -#define OS_SHMRELEASE        24
          103  +#define OS_SHMMAP            23
   105    104   #define OS_SHMLOCK           25
   106    105   #define OS_SHMBARRIER        26
   107         -#define OS_SHMSIZE           27
   108    106   #define OS_ANNOTATE          28
   109    107   
   110    108   #define OS_NUMEVENTS         29
   111    109   
   112    110   #define VFSLOG_BUFFERSIZE 8192
   113    111   
   114    112   typedef struct VfslogVfs VfslogVfs;
................................................................................
   148    146   static int vfslogUnlock(sqlite3_file*, int);
   149    147   static int vfslogCheckReservedLock(sqlite3_file*, int *pResOut);
   150    148   static int vfslogFileControl(sqlite3_file*, int op, void *pArg);
   151    149   static int vfslogSectorSize(sqlite3_file*);
   152    150   static int vfslogDeviceCharacteristics(sqlite3_file*);
   153    151   
   154    152   static int vfslogShmOpen(sqlite3_file *pFile);
   155         -static int vfslogShmSize(sqlite3_file *pFile, int reqSize, int *pNewSize);
   156         -static int vfslogShmGet(sqlite3_file *pFile, int,int*,volatile void **);
   157         -static int vfslogShmRelease(sqlite3_file *pFile);
   158    153   static int vfslogShmLock(sqlite3_file *pFile, int ofst, int n, int flags);
   159    154   static void vfslogShmBarrier(sqlite3_file*);
   160    155   static int vfslogShmClose(sqlite3_file *pFile, int deleteFlag);
          156  +static int vfslogShmMap(sqlite3_file *pFile,int,int,int,volatile void **);
   161    157   
   162    158   /*
   163    159   ** Method declarations for vfslog_vfs.
   164    160   */
   165    161   static int vfslogOpen(sqlite3_vfs*, const char *, sqlite3_file*, int , int *);
   166    162   static int vfslogDelete(sqlite3_vfs*, const char *zName, int syncDir);
   167    163   static int vfslogAccess(sqlite3_vfs*, const char *zName, int flags, int *);
................................................................................
   212    208     vfslogLock,                     /* xLock */
   213    209     vfslogUnlock,                   /* xUnlock */
   214    210     vfslogCheckReservedLock,        /* xCheckReservedLock */
   215    211     vfslogFileControl,              /* xFileControl */
   216    212     vfslogSectorSize,               /* xSectorSize */
   217    213     vfslogDeviceCharacteristics,    /* xDeviceCharacteristics */
   218    214     vfslogShmOpen,                  /* xShmOpen */
   219         -  vfslogShmSize,                  /* xShmSize */
   220         -  vfslogShmGet,                   /* xShmGet */
   221         -  vfslogShmRelease,               /* xShmRelease */
   222    215     vfslogShmLock,                  /* xShmLock */
   223    216     vfslogShmBarrier,               /* xShmBarrier */
   224         -  vfslogShmClose                  /* xShmClose */
          217  +  vfslogShmClose,                 /* xShmClose */
          218  +  vfslogShmMap                    /* xShmMap */
   225    219   };
   226    220   
   227    221   #if defined(SQLITE_OS_UNIX) && !defined(NO_GETTOD)
   228    222   #include <sys/time.h>
   229    223   static sqlite3_uint64 vfslog_time(){
   230    224     struct timeval sTime;
   231    225     gettimeofday(&sTime, 0);
................................................................................
   437    431     VfslogFile *p = (VfslogFile *)pFile;
   438    432     t = vfslog_time();
   439    433     rc = p->pReal->pMethods->xShmOpen(p->pReal);
   440    434     t = vfslog_time() - t;
   441    435     vfslog_call(p->pVfslog, OS_SHMOPEN, p->iFileId, t, rc, 0, 0);
   442    436     return rc;
   443    437   }
   444         -static int vfslogShmSize(sqlite3_file *pFile, int reqSize, int *pNewSize){
   445         -  int rc;
   446         -  sqlite3_uint64 t;
   447         -  VfslogFile *p = (VfslogFile *)pFile;
   448         -  t = vfslog_time();
   449         -  rc = p->pReal->pMethods->xShmSize(p->pReal, reqSize, pNewSize);
   450         -  t = vfslog_time() - t;
   451         -  vfslog_call(p->pVfslog, OS_SHMSIZE, p->iFileId, t, rc, 0, 0);
   452         -  return rc;
   453         -}
   454         -static int vfslogShmGet(
   455         -  sqlite3_file *pFile,
   456         -  int req,
   457         -  int *pSize,
   458         -  volatile void **pp
   459         -){
   460         -  int rc;
   461         -  sqlite3_uint64 t;
   462         -  VfslogFile *p = (VfslogFile *)pFile;
   463         -  t = vfslog_time();
   464         -  rc = p->pReal->pMethods->xShmGet(p->pReal, req, pSize, pp);
   465         -  t = vfslog_time() - t;
   466         -  vfslog_call(p->pVfslog, OS_SHMGET, p->iFileId, t, rc, 0, 0);
   467         -  return rc;
   468         -}
   469         -static int vfslogShmRelease(sqlite3_file *pFile){
   470         -  int rc;
   471         -  sqlite3_uint64 t;
   472         -  VfslogFile *p = (VfslogFile *)pFile;
   473         -  t = vfslog_time();
   474         -  rc = p->pReal->pMethods->xShmRelease(p->pReal);
   475         -  t = vfslog_time() - t;
   476         -  vfslog_call(p->pVfslog, OS_SHMRELEASE, p->iFileId, t, rc, 0, 0);
   477         -  return rc;
   478         -}
   479    438   static int vfslogShmLock(sqlite3_file *pFile, int ofst, int n, int flags){
   480    439     int rc;
   481    440     sqlite3_uint64 t;
   482    441     VfslogFile *p = (VfslogFile *)pFile;
   483    442     t = vfslog_time();
   484    443     rc = p->pReal->pMethods->xShmLock(p->pReal, ofst, n, flags);
   485    444     t = vfslog_time() - t;
................................................................................
   499    458     sqlite3_uint64 t;
   500    459     VfslogFile *p = (VfslogFile *)pFile;
   501    460     t = vfslog_time();
   502    461     rc = p->pReal->pMethods->xShmClose(p->pReal, deleteFlag);
   503    462     t = vfslog_time() - t;
   504    463     vfslog_call(p->pVfslog, OS_SHMCLOSE, p->iFileId, t, rc, 0, 0);
   505    464     return rc;
          465  +}
          466  +static int vfslogShmMap(
          467  +  sqlite3_file *pFile, 
          468  +  int iRegion, 
          469  +  int szRegion, 
          470  +  int isWrite, 
          471  +  volatile void **pp
          472  +){
          473  +  int rc;
          474  +  sqlite3_uint64 t;
          475  +  VfslogFile *p = (VfslogFile *)pFile;
          476  +  t = vfslog_time();
          477  +  rc = p->pReal->pMethods->xShmMap(p->pReal, iRegion, szRegion, isWrite, pp);
          478  +  t = vfslog_time() - t;
          479  +  vfslog_call(p->pVfslog, OS_SHMMAP, p->iFileId, t, rc, 0, 0);
          480  +  return rc;
   506    481   }
   507    482   
   508    483   
   509    484   /*
   510    485   ** Open an vfslog file handle.
   511    486   */
   512    487   static int vfslogOpen(
................................................................................
   822    797       case OS_FULLPATHNAME:      zEvent = "xFullPathname"; break;
   823    798       case OS_RANDOMNESS:        zEvent = "xRandomness"; break;
   824    799       case OS_SLEEP:             zEvent = "xSleep"; break;
   825    800       case OS_CURRENTTIME:       zEvent = "xCurrentTime"; break;
   826    801   
   827    802       case OS_SHMCLOSE:          zEvent = "xShmClose"; break;
   828    803       case OS_SHMOPEN:           zEvent = "xShmOpen"; break;
   829         -    case OS_SHMGET:            zEvent = "xShmGet"; break;
   830         -    case OS_SHMSIZE:           zEvent = "xShmSize"; break;
   831         -    case OS_SHMRELEASE:        zEvent = "xShmRelease"; break;
   832    804       case OS_SHMLOCK:           zEvent = "xShmLock"; break;
   833    805       case OS_SHMBARRIER:        zEvent = "xShmBarrier"; break;
          806  +    case OS_SHMMAP:            zEvent = "xShmMap"; break;
   834    807   
   835    808       case OS_ANNOTATE:          zEvent = "annotation"; break;
   836    809     }
   837    810   
   838    811     return zEvent;
   839    812   }
   840    813   

Changes to src/test_vfs.c.

    65     65   ** If a bit is clear in Testvfs.mask, then calls made by SQLite to the 
    66     66   ** corresponding VFS method is ignored for purposes of:
    67     67   **
    68     68   **   + Simulating IO errors, and
    69     69   **   + Invoking the Tcl callback script.
    70     70   */
    71     71   #define TESTVFS_SHMOPEN_MASK    0x00000001
    72         -#define TESTVFS_SHMSIZE_MASK    0x00000002
    73         -#define TESTVFS_SHMGET_MASK     0x00000004
    74         -#define TESTVFS_SHMRELEASE_MASK 0x00000008
    75     72   #define TESTVFS_SHMLOCK_MASK    0x00000010
    76     73   #define TESTVFS_SHMBARRIER_MASK 0x00000020
    77     74   #define TESTVFS_SHMCLOSE_MASK   0x00000040
    78     75   #define TESTVFS_SHMPAGE_MASK    0x00000080
    79     76   
    80     77   #define TESTVFS_OPEN_MASK       0x00000100
    81     78   #define TESTVFS_SYNC_MASK       0x00000200
................................................................................
   133    130   static void tvfsDlClose(sqlite3_vfs*, void*);
   134    131   #endif /* SQLITE_OMIT_LOAD_EXTENSION */
   135    132   static int tvfsRandomness(sqlite3_vfs*, int nByte, char *zOut);
   136    133   static int tvfsSleep(sqlite3_vfs*, int microseconds);
   137    134   static int tvfsCurrentTime(sqlite3_vfs*, double*);
   138    135   
   139    136   static int tvfsShmOpen(sqlite3_file*);
   140         -static int tvfsShmSize(sqlite3_file*, int , int *);
   141         -static int tvfsShmGet(sqlite3_file*, int , int *, volatile void **);
   142         -static int tvfsShmRelease(sqlite3_file*);
   143    137   static int tvfsShmLock(sqlite3_file*, int , int, int);
   144    138   static void tvfsShmBarrier(sqlite3_file*);
   145    139   static int tvfsShmClose(sqlite3_file*, int);
   146    140   static int tvfsShmPage(sqlite3_file*,int,int,int, void volatile **);
   147    141   
   148    142   static sqlite3_io_methods tvfs_io_methods = {
   149    143     2,                            /* iVersion */
................................................................................
   156    150     tvfsLock,                       /* xLock */
   157    151     tvfsUnlock,                     /* xUnlock */
   158    152     tvfsCheckReservedLock,          /* xCheckReservedLock */
   159    153     tvfsFileControl,                /* xFileControl */
   160    154     tvfsSectorSize,                 /* xSectorSize */
   161    155     tvfsDeviceCharacteristics,      /* xDeviceCharacteristics */
   162    156     tvfsShmOpen,                    /* xShmOpen */
   163         -  tvfsShmSize,                    /* xShmSize */
   164         -  tvfsShmGet,                     /* xShmGet */
   165         -  tvfsShmRelease,                 /* xShmRelease */
   166    157     tvfsShmLock,                    /* xShmLock */
   167    158     tvfsShmBarrier,                 /* xShmBarrier */
   168    159     tvfsShmClose,                   /* xShmClose */
   169    160     tvfsShmPage                     /* xShmPage */
   170    161   };
   171    162   
   172    163   static int tvfsResultCode(Testvfs *p, int *pRc){
................................................................................
   445    436     rc = sqlite3OsOpen(PARENTVFS(pVfs), zName, pFd->pReal, flags, pOutFlags);
   446    437     if( pFd->pReal->pMethods ){
   447    438       sqlite3_io_methods *pMethods;
   448    439       pMethods = (sqlite3_io_methods *)ckalloc(sizeof(sqlite3_io_methods));
   449    440       memcpy(pMethods, &tvfs_io_methods, sizeof(sqlite3_io_methods));
   450    441       if( ((Testvfs *)pVfs->pAppData)->isNoshm ){
   451    442         pMethods->xShmOpen = 0;
   452         -      pMethods->xShmGet = 0;
   453         -      pMethods->xShmSize = 0;
   454         -      pMethods->xShmRelease = 0;
   455    443         pMethods->xShmClose = 0;
   456    444         pMethods->xShmLock = 0;
   457    445         pMethods->xShmBarrier = 0;
          446  +      pMethods->xShmMap = 0;
   458    447       }
   459    448       pFile->pMethods = pMethods;
   460    449     }
   461    450   
   462    451     return rc;
   463    452   }
   464    453   
................................................................................
   608    597       p->pBuffer = pBuffer;
   609    598     }
   610    599   
   611    600     /* Connect the TestvfsBuffer to the new TestvfsShm handle and return. */
   612    601     pFd->pNext = pBuffer->pFile;
   613    602     pBuffer->pFile = pFd;
   614    603     pFd->pShm = pBuffer;
   615         -  return SQLITE_OK;
   616         -}
   617         -
   618         -static int tvfsShmSize(
   619         -  sqlite3_file *pFile,
   620         -  int reqSize,
   621         -  int *pNewSize
   622         -){
   623         -  assert(0);
   624         -  return SQLITE_OK;
   625         -}
   626         -static int tvfsShmGet(
   627         -  sqlite3_file *pFile, 
   628         -  int reqMapSize, 
   629         -  int *pMapSize, 
   630         -  volatile void **pp
   631         -){
   632         -  assert(0);
   633         -  return SQLITE_OK;
   634         -}
   635         -static int tvfsShmRelease(sqlite3_file *pFile){
   636         -  assert(0);
   637    604     return SQLITE_OK;
   638    605   }
   639    606   
   640    607   static void tvfsAllocPage(TestvfsBuffer *p, int iPage, int pgsz){
   641    608     assert( iPage<TESTVFS_MAX_PAGES );
   642    609     if( p->aPage[iPage]==0 ){
   643    610       p->aPage[iPage] = (u8 *)ckalloc(pgsz);
................................................................................
   867    834   
   868    835       case CMD_FILTER: {
   869    836         static struct VfsMethod {
   870    837           char *zName;
   871    838           int mask;
   872    839         } vfsmethod [] = {
   873    840           { "xShmOpen",    TESTVFS_SHMOPEN_MASK },
   874         -        { "xShmSize",    TESTVFS_SHMSIZE_MASK },
   875         -        { "xShmGet",     TESTVFS_SHMGET_MASK },
   876         -        { "xShmRelease", TESTVFS_SHMRELEASE_MASK },
   877    841           { "xShmLock",    TESTVFS_SHMLOCK_MASK },
   878    842           { "xShmBarrier", TESTVFS_SHMBARRIER_MASK },
   879    843           { "xShmClose",   TESTVFS_SHMCLOSE_MASK },
   880    844           { "xShmPage",    TESTVFS_SHMPAGE_MASK },
   881    845           { "xSync",       TESTVFS_SYNC_MASK },
   882    846           { "xOpen",       TESTVFS_OPEN_MASK },
   883    847         };

Changes to src/wal.c.

   479    479       memset(&apNew[pWal->nWiData], 0, sizeof(u32 *)*(iPage+1-pWal->nWiData));
   480    480       pWal->apWiData = apNew;
   481    481       pWal->nWiData = iPage+1;
   482    482     }
   483    483   
   484    484     /* Request a pointer to the required page from the VFS */
   485    485     if( pWal->apWiData[iPage]==0 ){
   486         -    rc = sqlite3OsShmPage(pWal->pDbFd, iPage, WALINDEX_PGSZ, 
          486  +    rc = sqlite3OsShmMap(pWal->pDbFd, iPage, WALINDEX_PGSZ, 
   487    487           pWal->writeLock, (void volatile **)&pWal->apWiData[iPage]
   488    488       );
   489    489     }
   490    490   
   491    491     *ppPage = pWal->apWiData[iPage];
   492    492     assert( iPage==0 || *ppPage || rc!=SQLITE_OK );
   493    493     return rc;