]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Add the new xShmMap (formerly xShmPage) to os_win.c.
authordan <dan@noemail.net>
Mon, 14 Jun 2010 16:16:33 +0000 (16:16 +0000)
committerdan <dan@noemail.net>
Mon, 14 Jun 2010 16:16:33 +0000 (16:16 +0000)
FossilOrigin-Name: 13e7a8242206bca4b5bf356ef074e66474d39609

manifest
manifest.uuid
src/os_unix.c
src/os_win.c

index b211bcfee42bf041f18ae8a8e579a1006eaa8715..86656a4e33e158f81545f22495b2487b9b0cac05 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Remove\sxShmGet/Size/Release\sfrom\sthe\ssqlite3_vfs\sstructure.\sChange\sthe\sname\sof\sxShmPage\sto\sxShmMap.\sRemove\ssome\scode\sthat\sis\snow\sunused\sfrom\sos_unix.c\sand\ssome\sof\sthe\stest\sVFS\simplementations.
-D 2010-06-14T14:07:51
+C Add\sthe\snew\sxShmMap\s(formerly\sxShmPage)\sto\sos_win.c.
+D 2010-06-14T16:16:34
 F Makefile.arm-wince-mingw32ce-gcc fcd5e9cd67fe88836360bb4f9ef4cb7f8e2fb5a0
 F Makefile.in a5cad1f8f3e021356bfcc6c77dc16f6f1952bbc3
 F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654
@@ -154,8 +154,8 @@ F src/os.c 9c4a2f82a50306a33907678ec0187b6ad1486bfe
 F src/os.h d7775504a51e6e0d40315aa427b3e229ff9ff9ca
 F src/os_common.h a8f95b81eca8a1ab8593d23e94f8a35f35d4078f
 F src/os_os2.c 665876d5eec7585226b0a1cf5e18098de2b2da19
-F src/os_unix.c 0a57b86241011ca25f2fb83e4825b7af7fe6d920
-F src/os_win.c 0cf1f571546f165001e2391b5d4a4a16d86977d3
+F src/os_unix.c 710418915cc3b59e596ee7ae916deca5dc740ca7
+F src/os_win.c 3d761e33687cb24645fe66e5efd11244390e8e9c
 F src/pager.c 2964185d4356d0dc159b8340e52d2538d32394e5
 F src/pager.h ca1f23c0cf137ac26f8908df2427c8b308361efd
 F src/parse.y ace5c7a125d9f2a410e431ee3209034105045f7e
@@ -820,7 +820,7 @@ F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff
 F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224
 F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e
 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f
-P 1ce9c92bffa5d7f8431c005b29d698b0f5b95875
-R 8ee76bbe532e6db3f47bf2104ddf1a48
+P fc0cabc15c97dde6a852b4f07df6d30f1d2c04bc
+R 25e35232d2e784a0633c25f463199a04
 U dan
-Z 95a9a1111fae03b142846d91ecde0c57
+Z 06f3bcfd0aba7d97df7e9b4406c194ab
index 6a3db6fb58a11279600597710b48e4a0b3b1b012..13f5f78d56537a238edb0d36906b4e898967de3f 100644 (file)
@@ -1 +1 @@
-fc0cabc15c97dde6a852b4f07df6d30f1d2c04bc
\ No newline at end of file
+13e7a8242206bca4b5bf356ef074e66474d39609
\ No newline at end of file
index 22c9a92826784aff0ca432b1da169567d89898e0..fcccead725354ee62c9f66390975dcf2d12552b1 100644 (file)
@@ -3573,7 +3573,7 @@ static void unixShmBarrier(
 ** address space (if it is not already), *pp is set to point to the mapped 
 ** memory and SQLITE_OK returned.
 */
-static int unixShmPage(
+static int unixShmMap(
   sqlite3_file *fd,               /* Handle open on database file */
   int iRegion,                    /* Region to retrieve */
   int szRegion,                   /* Size of regions */
@@ -3655,7 +3655,7 @@ shmpage_out:
 # define unixShmLock    0
 # define unixShmBarrier 0
 # define unixShmClose   0
-# define unixShmPage    0
+# define unixShmMap     0
 #endif /* #ifndef SQLITE_OMIT_WAL */
 
 /*
@@ -3717,7 +3717,7 @@ static const sqlite3_io_methods METHOD = {                                   \
    unixShmLock,                /* xShmLock */                                \
    unixShmBarrier,             /* xShmBarrier */                             \
    unixShmClose,               /* xShmClose */                               \
-   unixShmPage                 /* xShmPage */                                \
+   unixShmMap                  /* xShmMap */                                 \
 };                                                                           \
 static const sqlite3_io_methods *FINDER##Impl(const char *z, unixFile *p){   \
   UNUSED_PARAMETER(z); UNUSED_PARAMETER(p);                                  \
index 1a9994b08dc50eab242a4b7c1c5e6489861b7819..3a6b47771a373db26953307ad51127d8c03468a4 100644 (file)
@@ -1216,13 +1216,17 @@ static int winShmMutexHeld(void) {
 */
 struct winShmNode {
   sqlite3_mutex *mutex;      /* Mutex to access this object */
-  sqlite3_mutex *mutexBuf;   /* Mutex to access zBuf[] */
   char *zFilename;           /* Name of the file */
   winFile hFile;             /* File handle from winOpen */
-  HANDLE hMap;               /* File handle from CreateFileMapping */
+
+  int szRegion;              /* Size of shared-memory regions */
+  int nRegion;               /* Size of array apRegion */
+  struct ShmRegion {
+    HANDLE hMap;             /* File handle from CreateFileMapping */
+    void *pMap;
+  } *aRegion;
   DWORD lastErrno;           /* The Windows errno from the last I/O error */
-  int szMap;                 /* Size of the mapping of file into memory */
-  char *pMMapBuf;            /* Where currently mmapped().  NULL if unmapped */
+
   int nRef;                  /* Number of winShm objects pointing to this */
   winShm *pFirst;            /* All winShm objects pointing to this */
   winShmNode *pNext;         /* Next in list of all winShmNode objects */
@@ -1325,19 +1329,18 @@ static void winShmPurge(sqlite3_vfs *pVfs, int deleteFlag){
   pp = &winShmNodeList;
   while( (p = *pp)!=0 ){
     if( p->nRef==0 ){
+      int i;
       if( p->mutex ) sqlite3_mutex_free(p->mutex);
-      if( p->mutexBuf ) sqlite3_mutex_free(p->mutexBuf);
-      if( p->pMMapBuf ){
-        UnmapViewOfFile(p->pMMapBuf);
-      }
-      if( INVALID_HANDLE_VALUE != p->hMap ){
-        CloseHandle(p->hMap);
+      for(i=0; i<p->nRegion; i++){
+        UnmapViewOfFile(p->aRegion[i].pMap);
+        CloseHandle(p->aRegion[i].hMap);
       }
       if( p->hFile.h != INVALID_HANDLE_VALUE ) {
         winClose((sqlite3_file *)&p->hFile);
       }
       if( deleteFlag ) winDelete(pVfs, p->zFilename, 0);
       *pp = p->pNext;
+      sqlite3_free(p->aRegion);
       sqlite3_free(p);
     }else{
       pp = &p->pNext;
@@ -1404,8 +1407,6 @@ static int winShmOpen(
   }else{
     pShmNode = pNew;
     pNew = 0;
-    pShmNode->pMMapBuf = NULL;
-    pShmNode->hMap = INVALID_HANDLE_VALUE;
     ((winFile*)(&pShmNode->hFile))->h = INVALID_HANDLE_VALUE;
     pShmNode->pNext = winShmNodeList;
     winShmNodeList = pShmNode;
@@ -1415,11 +1416,6 @@ static int winShmOpen(
       rc = SQLITE_NOMEM;
       goto shm_open_err;
     }
-    pShmNode->mutexBuf = sqlite3_mutex_alloc(SQLITE_MUTEX_FAST);
-    if( pShmNode->mutexBuf==0 ){
-      rc = SQLITE_NOMEM;
-      goto shm_open_err;
-    }
     rc = winOpen(pDbFd->pVfs,
                  pShmNode->zFilename,             /* Name of the file (UTF-8) */
                  (sqlite3_file*)&pShmNode->hFile,  /* File handle here */
@@ -1507,171 +1503,113 @@ static int winShmClose(
 }
 
 /*
-** Increase the size of the underlying storage for a shared-memory segment.
+** This function is called to obtain a pointer to region iRegion of the 
+** shared-memory associated with the database file fd. Shared-memory regions 
+** are numbered starting from zero. Each shared-memory region is szRegion 
+** bytes in size.
 **
-** The reqSize parameter is the new requested minimum size of the underlying
-** shared memory.  This routine may choose to make the shared memory larger
-** than this value (for example to round the shared memory size up to an
-** operating-system dependent page size.)
+** If an error occurs, an error code is returned and *pp is set to NULL.
 **
-** This routine will only grow the size of shared memory.  A request for
-** a smaller size is a no-op.
-*/
-static int winShmSize(
-  sqlite3_file *fd,         /* Database holding the shared memory */
-  int reqSize,              /* Requested size.  -1 for query only */
-  int *pNewSize             /* Write new size here */
+** Otherwise, if the isWrite parameter is 0 and the requested shared-memory
+** region has not been allocated (by any client, including one running in a
+** separate process), then *pp is set to NULL and SQLITE_OK returned. If 
+** isWrite is non-zero and the requested shared-memory region has not yet 
+** been allocated, it is allocated by this function.
+**
+** If the shared-memory region has already been allocated or is allocated by
+** this call as described above, then it is mapped into this processes 
+** address space (if it is not already), *pp is set to point to the mapped 
+** memory and SQLITE_OK returned.
+*/
+static int winShmMap(
+  sqlite3_file *fd,               /* Handle open on database file */
+  int iRegion,                    /* Region to retrieve */
+  int szRegion,                   /* Size of regions */
+  int isWrite,                    /* True to extend file if necessary */
+  void volatile **pp              /* OUT: Mapped memory */
 ){
   winFile *pDbFd = (winFile*)fd;
   winShm *p = pDbFd->pShm;
   winShmNode *pShmNode = p->pShmNode;
   int rc = SQLITE_OK;
 
-  *pNewSize = 0;
-  if( reqSize>=0 ){
-    sqlite3_int64 sz;
-    rc = winFileSize((sqlite3_file *)&pShmNode->hFile, &sz);
-    if( SQLITE_OK==rc && reqSize>sz ){
-      rc = winTruncate((sqlite3_file *)&pShmNode->hFile, reqSize);
-    }
-  }
-  if( SQLITE_OK==rc ){
-    sqlite3_int64 sz;
+  sqlite3_mutex_enter(pShmNode->mutex);
+  assert( szRegion==pShmNode->szRegion || pShmNode->nRegion==0 );
+
+  if( pShmNode->nRegion<=iRegion ){
+    struct ShmRegion *apNew;           /* New aRegion[] array */
+    int nByte = (iRegion+1)*szRegion;  /* Minimum required file size */
+    sqlite3_int64 sz;                  /* Current size of wal-index file */
+
+    pShmNode->szRegion = szRegion;
+
+    /* The requested region is not mapped into this processes address space.
+    ** Check to see if it has been allocated (i.e. if the wal-index file is
+    ** large enough to contain the requested region).
+    */
     rc = winFileSize((sqlite3_file *)&pShmNode->hFile, &sz);
-    if( SQLITE_OK==rc ){
-      *pNewSize = (int)sz;
-    }else{
-      rc = SQLITE_IOERR;
+    if( rc!=SQLITE_OK ){
+      goto shmpage_out;
     }
-  }
-  return rc;
-}
 
+    if( sz<nByte ){
+      /* The requested memory region does not exist. If isWrite is set to
+      ** zero, exit early. *pp will be set to NULL and SQLITE_OK returned.
+      **
+      ** Alternatively, if isWrite is non-zero, use ftruncate() to allocate
+      ** the requested memory region.
+      */
+      if( !isWrite ) goto shmpage_out;
+      rc = winTruncate((sqlite3_file *)&pShmNode->hFile, nByte);
+      if( rc!=SQLITE_OK ){
+        goto shmpage_out;
+      }
+    }
 
-/*
-** Map the shared storage into memory.  The minimum size of the
-** mapping should be reqMapSize if reqMapSize is positive.  If
-** reqMapSize is zero or negative, the implementation can choose
-** whatever mapping size is convenient.
-**
-** *ppBuf is made to point to the memory which is a mapping of the
-** underlying storage.  A mutex is acquired to prevent other threads
-** from running while *ppBuf is in use in order to prevent other threads
-** remapping *ppBuf out from under this thread.  The winShmRelease()
-** call will release the mutex.  However, if the lock state is CHECKPOINT,
-** the mutex is not acquired because CHECKPOINT will never remap the
-** buffer.  RECOVER might remap, though, so CHECKPOINT will acquire
-** the mutex if and when it promotes to RECOVER.
-**
-** RECOVER needs to be atomic.  The same mutex that prevents *ppBuf from
-** being remapped also prevents more than one thread from being in
-** RECOVER at a time.  But, RECOVER sometimes wants to remap itself.
-** To prevent RECOVER from losing its lock while remapping, the
-** mutex is not released by winShmRelease() when in RECOVER.
-**
-** *pNewMapSize is set to the size of the mapping.
-**
-** *ppBuf and *pNewMapSize might be NULL and zero if no space has
-** yet been allocated to the underlying storage.
-*/
-static int winShmGet(
-  sqlite3_file *fd,        /* The database file holding the shared memory */
-  int reqMapSize,          /* Requested size of mapping. -1 means don't care */
-  int *pNewMapSize,        /* Write new size of mapping here */
-  void volatile **ppBuf    /* Write mapping buffer origin here */
-){
-  winFile *pDbFd = (winFile*)fd;
-  winShm *p = pDbFd->pShm;
-  winShmNode *pShmNode = p->pShmNode;
-  int rc = SQLITE_OK;
-
-  if( p->hasMutexBuf==0 ){
-    assert( sqlite3_mutex_notheld(pShmNode->mutex) );
-    sqlite3_mutex_enter(pShmNode->mutexBuf);
-    p->hasMutexBuf = 1;
-  }
-  sqlite3_mutex_enter(pShmNode->mutex);
-  if( pShmNode->szMap==0 || reqMapSize>pShmNode->szMap ){
-    int actualSize;
-    if( winShmSize(fd, -1, &actualSize)==SQLITE_OK
-     && reqMapSize<actualSize
-    ){
-      reqMapSize = actualSize;
+    /* Map the requested memory region into this processes address space. */
+    apNew = (struct ShmRegion *)sqlite3_realloc(
+        pShmNode->aRegion, (iRegion+1)*sizeof(apNew[0])
+    );
+    if( !apNew ){
+      rc = SQLITE_IOERR_NOMEM;
+      goto shmpage_out;
     }
-    if( pShmNode->pMMapBuf ){
-      if( !UnmapViewOfFile(pShmNode->pMMapBuf) ){
+    pShmNode->aRegion = apNew;
+
+    while( pShmNode->nRegion<=iRegion ){
+      HANDLE hMap;                /* file-mapping handle */
+      void *pMap = 0;             /* Mapped memory region */
+     
+      hMap = CreateFileMapping(pShmNode->hFile.h, 
+          NULL, PAGE_READWRITE, 0, nByte, NULL
+      );
+      if( hMap ){
+        pMap = MapViewOfFile(hMap, FILE_MAP_WRITE | FILE_MAP_READ,
+            0, 0, nByte
+        );
+      }
+      if( !pMap ){
         pShmNode->lastErrno = GetLastError();
         rc = SQLITE_IOERR;
+        if( hMap ) CloseHandle(hMap);
+        goto shmpage_out;
       }
-      CloseHandle(pShmNode->hMap);
-      pShmNode->hMap = INVALID_HANDLE_VALUE;
-    }
-    if( SQLITE_OK == rc ){
-      pShmNode->pMMapBuf = 0;
-      if( reqMapSize == 0 ){
-        /* can't create 0 byte file mapping in Windows */
-        pShmNode->szMap = 0;
-      }else{
-        /* create the file mapping object */
-        if( INVALID_HANDLE_VALUE == pShmNode->hMap ){
-          /* TBD provide an object name to each file
-          ** mapping so it can be re-used across processes.
-          */
-          pShmNode->hMap = CreateFileMapping(pShmNode->hFile.h,
-                                          NULL,
-                                          PAGE_READWRITE,
-                                          0,
-                                          reqMapSize,
-                                          NULL);
-        }
-        if( NULL==pShmNode->hMap ){
-          pShmNode->lastErrno = GetLastError();
-          rc = SQLITE_IOERR;
-          pShmNode->szMap = 0;
-          pShmNode->hMap = INVALID_HANDLE_VALUE;
-        }else{
-          pShmNode->pMMapBuf = MapViewOfFile(pShmNode->hMap,
-                                          FILE_MAP_WRITE | FILE_MAP_READ,
-                                          0,
-                                          0,
-                                          reqMapSize);
-          if( !pShmNode->pMMapBuf ){
-            pShmNode->lastErrno = GetLastError();
-            rc = SQLITE_IOERR;
-            pShmNode->szMap = 0;
-          }else{
-            pShmNode->szMap = reqMapSize;
-          }
-        }
-      }
+
+      pShmNode->aRegion[pShmNode->nRegion].pMap = pMap;
+      pShmNode->aRegion[pShmNode->nRegion].hMap = hMap;
+      pShmNode->nRegion++;
     }
   }
-  *pNewMapSize = pShmNode->szMap;
-  *ppBuf = pShmNode->pMMapBuf;
-  sqlite3_mutex_leave(pShmNode->mutex);
-  return rc;
-}
 
-/*
-** Release the lock held on the shared memory segment so that other
-** threads are free to resize it if necessary.
-**
-** If the lock is not currently held, this routine is a harmless no-op.
-**
-** If the shared-memory object is in lock state RECOVER, then we do not
-** really want to release the lock, so in that case too, this routine
-** is a no-op.
-*/
-static int winShmRelease(sqlite3_file *fd){
-  winFile *pDbFd = (winFile*)fd;
-  winShm *p = pDbFd->pShm;
-  if( p->hasMutexBuf ){
-    winShmNode *pShmNode = p->pShmNode;
-    assert( sqlite3_mutex_notheld(pShmNode->mutex) );
-    sqlite3_mutex_leave(pShmNode->mutexBuf);
-    p->hasMutexBuf = 0;
+shmpage_out:
+  if( pShmNode->nRegion>iRegion ){
+    char *p = (char *)pShmNode->aRegion[iRegion].pMap;
+    *pp = (void *)&p[iRegion*szRegion];
+  }else{
+    *pp = 0;
   }
-  return SQLITE_OK;
+  sqlite3_mutex_leave(pShmNode->mutex);
+  return rc;
 }
 
 /*
@@ -1756,12 +1694,10 @@ static const sqlite3_io_methods winIoMethod = {
   winSectorSize,
   winDeviceCharacteristics,
   winShmOpen,              /* xShmOpen */
-  winShmSize,              /* xShmSize */
-  winShmGet,               /* xShmGet */
-  winShmRelease,           /* xShmRelease */
   winShmLock,              /* xShmLock */
   winShmBarrier,           /* xShmBarrier */
-  winShmClose              /* xShmClose */
+  winShmClose,             /* xShmClose */
+  winShmMap                /* xShmMap */
 };
 
 /***************************************************************************