/ Changes On Branch winDisableMmap
Login

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

Changes In Branch winDisableMmap Excluding Merge-Ins

This is equivalent to a diff from f1b524b9d9 to daa168f3da

2013-04-12
01:04
In mptester: improve the way that child processes are dispatched. Pass the --vfs option through to children. Log the command used to start child processes when the tracing level is high enough. (check-in: 55718ae346 user: drh tags: trunk)
2013-04-11
22:52
Expand scope of the SQLITE_DISABLE_MMAP define for the Win32 VFS. (Closed-Leaf check-in: daa168f3da user: mistachkin tags: winDisableMmap)
21:13
For the multi-process tester on Win32, make use of the GetCurrentProcessId API. (check-in: f1b524b9d9 user: mistachkin tags: trunk)
18:28
Fix the xCheckReservedLock() method on the windows VFS so that it cannot return a false positive when two or more processes use it at the same time on the same file. Ticket [7ff3120e4fa54abb55] (check-in: dd3510bb20 user: drh tags: trunk)

Changes to src/os_win.c.

146
147
148
149
150
151
152

153
154
155
156
157
158

159
160
161
162
163
164
165
#if SQLITE_OS_WINCE
  LPWSTR zDeleteOnClose;  /* Name of file to delete when closing */
  HANDLE hMutex;          /* Mutex used to control access to shared lock */  
  HANDLE hShared;         /* Shared memory segment used for locking */
  winceLock local;        /* Locks obtained by this instance of winFile */
  winceLock *shared;      /* Global shared lock memory for the file  */
#endif

  int nFetchOut;               /* Number of outstanding xFetch references */
  HANDLE hMap;                 /* Handle for accessing memory mapping */
  void *pMapRegion;            /* Area memory mapped */
  sqlite3_int64 mmapSize;      /* Usable size of mapped region */
  sqlite3_int64 mmapOrigsize;  /* Actual size of mapped region */
  sqlite3_int64 mmapLimit;     /* Configured FCNTL_MMAP_LIMIT value */

};

/*
** Allowed values for winFile.ctrlFlags
*/
#define WINFILE_RDONLY          0x02   /* Connection is read only */
#define WINFILE_PERSIST_WAL     0x04   /* Persistent WAL mode */







>






>







146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
#if SQLITE_OS_WINCE
  LPWSTR zDeleteOnClose;  /* Name of file to delete when closing */
  HANDLE hMutex;          /* Mutex used to control access to shared lock */  
  HANDLE hShared;         /* Shared memory segment used for locking */
  winceLock local;        /* Locks obtained by this instance of winFile */
  winceLock *shared;      /* Global shared lock memory for the file  */
#endif
#if !defined(SQLITE_DISABLE_MMAP)
  int nFetchOut;               /* Number of outstanding xFetch references */
  HANDLE hMap;                 /* Handle for accessing memory mapping */
  void *pMapRegion;            /* Area memory mapped */
  sqlite3_int64 mmapSize;      /* Usable size of mapped region */
  sqlite3_int64 mmapOrigsize;  /* Actual size of mapped region */
  sqlite3_int64 mmapLimit;     /* Configured FCNTL_MMAP_LIMIT value */
#endif
};

/*
** Allowed values for winFile.ctrlFlags
*/
#define WINFILE_RDONLY          0x02   /* Connection is read only */
#define WINFILE_PERSIST_WAL     0x04   /* Persistent WAL mode */
2089
2090
2091
2092
2093
2094
2095

2096
2097

2098
2099
2100
2101
2102
2103
2104
  assert( id!=0 );
#ifndef SQLITE_OMIT_WAL
  assert( pFile->pShm==0 );
#endif
  OSTRACE(("CLOSE %d\n", pFile->h));
  assert( pFile->h!=NULL && pFile->h!=INVALID_HANDLE_VALUE );


  rc = winUnmapfile(pFile);
  if( rc!=SQLITE_OK ) return rc;


  do{
    rc = osCloseHandle(pFile->h);
    /* SimulateIOError( rc=0; cnt=MX_CLOSE_ATTEMPT; ); */
  }while( rc==0 && ++cnt < MX_CLOSE_ATTEMPT && (sqlite3_win32_sleep(100), 1) );
#if SQLITE_OS_WINCE
#define WINCE_DELETION_ATTEMPTS 3







>


>







2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103
2104
2105
2106
2107
2108
  assert( id!=0 );
#ifndef SQLITE_OMIT_WAL
  assert( pFile->pShm==0 );
#endif
  OSTRACE(("CLOSE %d\n", pFile->h));
  assert( pFile->h!=NULL && pFile->h!=INVALID_HANDLE_VALUE );

#if !defined(SQLITE_DISABLE_MMAP)
  rc = winUnmapfile(pFile);
  if( rc!=SQLITE_OK ) return rc;
#endif

  do{
    rc = osCloseHandle(pFile->h);
    /* SimulateIOError( rc=0; cnt=MX_CLOSE_ATTEMPT; ); */
  }while( rc==0 && ++cnt < MX_CLOSE_ATTEMPT && (sqlite3_win32_sleep(100), 1) );
#if SQLITE_OS_WINCE
#define WINCE_DELETION_ATTEMPTS 3
2838
2839
2840
2841
2842
2843
2844

2845
2846
2847
2848
2849
2850

2851
2852
2853
2854
2855
2856
2857
      char *zTFile = sqlite3MallocZero( pFile->pVfs->mxPathname );
      if( zTFile ){
        getTempname(pFile->pVfs->mxPathname, zTFile);
        *(char**)pArg = zTFile;
      }
      return SQLITE_OK;
    }

    case SQLITE_FCNTL_MMAP_LIMIT: {
      i64 newLimit = *(i64*)pArg;
      *(i64*)pArg = pFile->mmapLimit;
      if( newLimit>=0 ) pFile->mmapLimit = newLimit;
      return SQLITE_OK;
    }

  }
  return SQLITE_NOTFOUND;
}

/*
** Return the sector size in bytes of the underlying block device for
** the specified file. This is almost always 512 bytes, but may be







>






>







2842
2843
2844
2845
2846
2847
2848
2849
2850
2851
2852
2853
2854
2855
2856
2857
2858
2859
2860
2861
2862
2863
      char *zTFile = sqlite3MallocZero( pFile->pVfs->mxPathname );
      if( zTFile ){
        getTempname(pFile->pVfs->mxPathname, zTFile);
        *(char**)pArg = zTFile;
      }
      return SQLITE_OK;
    }
#if !defined(SQLITE_DISABLE_MMAP)
    case SQLITE_FCNTL_MMAP_LIMIT: {
      i64 newLimit = *(i64*)pArg;
      *(i64*)pArg = pFile->mmapLimit;
      if( newLimit>=0 ) pFile->mmapLimit = newLimit;
      return SQLITE_OK;
    }
#endif
  }
  return SQLITE_NOTFOUND;
}

/*
** Return the sector size in bytes of the underlying block device for
** the specified file. This is almost always 512 bytes, but may be
3517
3518
3519
3520
3521
3522
3523

3524
3525
3526
3527
3528
3529
3530
3531
3532
3533
3534
3535
3536
3537
3538
3539
3540
3541
3542
3543
3544
3545
3546
3547
3548
3549
3550
3551
3552
3553
3554
3555
3556
# define winShmBarrier 0
# define winShmUnmap   0
#endif /* #ifndef SQLITE_OMIT_WAL */

/*
** Cleans up the mapped region of the specified file, if any.
*/

static int winUnmapfile(winFile *pFile){
  assert( pFile!=0 );
#if !defined(SQLITE_DISABLE_MMAP)
  if( pFile->pMapRegion ){
    if( !osUnmapViewOfFile(pFile->pMapRegion) ){
      pFile->lastErrno = osGetLastError();
      return winLogError(SQLITE_IOERR_MMAP, pFile->lastErrno,
                         "winUnmap1", pFile->zPath);
    }
    pFile->pMapRegion = 0;
    pFile->mmapSize = 0;
    pFile->mmapOrigsize = 0;
  }
  if( pFile->hMap!=NULL ){
    if( !osCloseHandle(pFile->hMap) ){
      pFile->lastErrno = osGetLastError();
      return winLogError(SQLITE_IOERR_MMAP, pFile->lastErrno,
                         "winUnmap2", pFile->zPath);
    }
    pFile->hMap = NULL;
  }
#endif
  return SQLITE_OK;
}

#if !defined(SQLITE_DISABLE_MMAP)
/*
** Memory map or remap the file opened by file-descriptor pFd (if the file
** is already mapped, the existing mapping is replaced by the new). Or, if 
** there already exists a mapping for this file, and there are still 
** outstanding xFetch() references to it, this function is a no-op.
**
** If parameter nByte is non-negative, then it is the requested size of 







>


<


















<



<







3523
3524
3525
3526
3527
3528
3529
3530
3531
3532

3533
3534
3535
3536
3537
3538
3539
3540
3541
3542
3543
3544
3545
3546
3547
3548
3549
3550

3551
3552
3553

3554
3555
3556
3557
3558
3559
3560
# define winShmBarrier 0
# define winShmUnmap   0
#endif /* #ifndef SQLITE_OMIT_WAL */

/*
** Cleans up the mapped region of the specified file, if any.
*/
#if !defined(SQLITE_DISABLE_MMAP)
static int winUnmapfile(winFile *pFile){
  assert( pFile!=0 );

  if( pFile->pMapRegion ){
    if( !osUnmapViewOfFile(pFile->pMapRegion) ){
      pFile->lastErrno = osGetLastError();
      return winLogError(SQLITE_IOERR_MMAP, pFile->lastErrno,
                         "winUnmap1", pFile->zPath);
    }
    pFile->pMapRegion = 0;
    pFile->mmapSize = 0;
    pFile->mmapOrigsize = 0;
  }
  if( pFile->hMap!=NULL ){
    if( !osCloseHandle(pFile->hMap) ){
      pFile->lastErrno = osGetLastError();
      return winLogError(SQLITE_IOERR_MMAP, pFile->lastErrno,
                         "winUnmap2", pFile->zPath);
    }
    pFile->hMap = NULL;
  }

  return SQLITE_OK;
}


/*
** Memory map or remap the file opened by file-descriptor pFd (if the file
** is already mapped, the existing mapping is replaced by the new). Or, if 
** there already exists a mapping for this file, and there are still 
** outstanding xFetch() references to it, this function is a no-op.
**
** If parameter nByte is non-negative, then it is the requested size of 
3645
3646
3647
3648
3649
3650
3651

3652

3653
3654
3655
3656
3657
3658
3659
** Finally, if an error does occur, return an SQLite error code. The final
** value of *pp is undefined in this case.
**
** If this function does return a pointer, the caller must eventually 
** release the reference by calling unixUnfetch().
*/
static int winFetch(sqlite3_file *fd, i64 iOff, int nAmt, void **pp){

  winFile *pFd = (winFile*)fd;   /* The underlying database file */

  *pp = 0;

#if !defined(SQLITE_DISABLE_MMAP)
  if( pFd->mmapLimit>0 ){
    if( pFd->pMapRegion==0 ){
      int rc = winMapfile(pFd, -1);
      if( rc!=SQLITE_OK ) return rc;







>

>







3649
3650
3651
3652
3653
3654
3655
3656
3657
3658
3659
3660
3661
3662
3663
3664
3665
** Finally, if an error does occur, return an SQLite error code. The final
** value of *pp is undefined in this case.
**
** If this function does return a pointer, the caller must eventually 
** release the reference by calling unixUnfetch().
*/
static int winFetch(sqlite3_file *fd, i64 iOff, int nAmt, void **pp){
#if !defined(SQLITE_DISABLE_MMAP)
  winFile *pFd = (winFile*)fd;   /* The underlying database file */
#endif
  *pp = 0;

#if !defined(SQLITE_DISABLE_MMAP)
  if( pFd->mmapLimit>0 ){
    if( pFd->pMapRegion==0 ){
      int rc = winMapfile(pFd, -1);
      if( rc!=SQLITE_OK ) return rc;
3674
3675
3676
3677
3678
3679
3680

3681
3682
3683
3684
3685
3686
3687
** 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 winUnfetch(sqlite3_file *fd, i64 iOff, void *p){

  winFile *pFd = (winFile*)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) );








>







3680
3681
3682
3683
3684
3685
3686
3687
3688
3689
3690
3691
3692
3693
3694
** 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 winUnfetch(sqlite3_file *fd, i64 iOff, void *p){
#if !defined(SQLITE_DISABLE_MMAP)
  winFile *pFd = (winFile*)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) );

3695
3696
3697
3698
3699
3700
3701

3702
3703
3704
3705
3706
3707
3708
    ** file while a mapping is held, then the following winUnmapfile() call
    ** is unnecessary can can be omitted - potentially improving
    ** performance.  */
    winUnmapfile(pFd);
  }

  assert( pFd->nFetchOut>=0 );

  return SQLITE_OK;
}

/*
** Here ends the implementation of all sqlite3_file methods.
**
********************** End sqlite3_file Methods *******************************







>







3702
3703
3704
3705
3706
3707
3708
3709
3710
3711
3712
3713
3714
3715
3716
    ** file while a mapping is held, then the following winUnmapfile() call
    ** is unnecessary can can be omitted - potentially improving
    ** performance.  */
    winUnmapfile(pFd);
  }

  assert( pFd->nFetchOut>=0 );
#endif
  return SQLITE_OK;
}

/*
** Here ends the implementation of all sqlite3_file methods.
**
********************** End sqlite3_file Methods *******************************
4122
4123
4124
4125
4126
4127
4128

4129
4130
4131
4132
4133

4134
4135
4136
4137
4138
4139
4140
    pFile->ctrlFlags |= WINFILE_RDONLY;
  }
  if( sqlite3_uri_boolean(zName, "psow", SQLITE_POWERSAFE_OVERWRITE) ){
    pFile->ctrlFlags |= WINFILE_PSOW;
  }
  pFile->lastErrno = NO_ERROR;
  pFile->zPath = zName;

  pFile->hMap = NULL;
  pFile->pMapRegion = 0;
  pFile->mmapSize = 0;
  pFile->mmapOrigsize = 0;
  pFile->mmapLimit = sqlite3GlobalConfig.mxMmap;


  OpenCounter(+1);
  return rc;
}

/*
** Delete the named file.







>





>







4130
4131
4132
4133
4134
4135
4136
4137
4138
4139
4140
4141
4142
4143
4144
4145
4146
4147
4148
4149
4150
    pFile->ctrlFlags |= WINFILE_RDONLY;
  }
  if( sqlite3_uri_boolean(zName, "psow", SQLITE_POWERSAFE_OVERWRITE) ){
    pFile->ctrlFlags |= WINFILE_PSOW;
  }
  pFile->lastErrno = NO_ERROR;
  pFile->zPath = zName;
#if !defined(SQLITE_DISABLE_MMAP)
  pFile->hMap = NULL;
  pFile->pMapRegion = 0;
  pFile->mmapSize = 0;
  pFile->mmapOrigsize = 0;
  pFile->mmapLimit = sqlite3GlobalConfig.mxMmap;
#endif

  OpenCounter(+1);
  return rc;
}

/*
** Delete the named file.