]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Changes so that the xShmOpen VFS method is no longer required. Its job can be done...
authordan <dan@noemail.net>
Tue, 13 Jul 2010 18:44:03 +0000 (18:44 +0000)
committerdan <dan@noemail.net>
Tue, 13 Jul 2010 18:44:03 +0000 (18:44 +0000)
FossilOrigin-Name: f4780bde62c6c19146d2723c101540b8db898d38

14 files changed:
manifest
manifest.uuid
src/os.c
src/os.h
src/os_unix.c
src/os_win.c
src/pager.c
src/sqlite.h.in
src/test6.c
src/test_devsym.c
src/test_onefile.c
src/test_osinst.c
src/test_vfs.c
src/wal.c

index 6b441a550ff66251a68c0daa97a93de488143d40..e33c01a84f22e48232dd9b4a74cae3531716bb9a 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,8 +1,5 @@
------BEGIN PGP SIGNED MESSAGE-----
-Hash: SHA1
-
-C Improved\sdocumentation\sfor\sthe\sSQLITE_ACCESS_*\sconstants\sthat\sare\sused\nwith\sthe\sxAccess()\smethod\sof\sthe\sVFS.
-D 2010-07-13T14:48:27
+C Changes\sso\sthat\sthe\sxShmOpen\sVFS\smethod\sis\sno\slonger\srequired.\sIts\sjob\scan\sbe\sdone\sby\sthe\sfirst\scall\sto\sxShmMap.\sRename\sxShmClose\sto\sxShmUnmap.
+D 2010-07-13T18:44:04
 F Makefile.arm-wince-mingw32ce-gcc fcd5e9cd67fe88836360bb4f9ef4cb7f8e2fb5a0
 F Makefile.in ec08dc838fd8110fe24c92e5130bcd91cbb1ff2e
 F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654
@@ -153,13 +150,13 @@ F src/mutex_os2.c 6a62583e374ba3ac1a3fcc0da2bfdac7d3942689
 F src/mutex_unix.c cf84466b4fdd2baa0d5a10bb19f08b2abc1ce42e
 F src/mutex_w32.c 1fe0e735897be20e09dd6f53c3fb516c6b48c0eb
 F src/notify.c cbfa66a836da3a51567209636e6a94059c137930
-F src/os.c c34882169b2f8ee0942c4f6aff9ee705e6110cdf
-F src/os.h d7775504a51e6e0d40315aa427b3e229ff9ff9ca
+F src/os.c a45484100b8e86718eb117d92feae082ac2530f8
+F src/os.h 93cb145b93bd971055cf4d55ac44eaaa51e148fc
 F src/os_common.h a8f95b81eca8a1ab8593d23e94f8a35f35d4078f
 F src/os_os2.c 665876d5eec7585226b0a1cf5e18098de2b2da19
-F src/os_unix.c c6112f0ae34f23ae5ca0189a685e084befbdcf26
-F src/os_win.c 04c8828e4c5c2e7d5abcb9ce170ae6bfb02aa98d
-F src/pager.c 1d42e2cdaa9b1765f7df8e350509318917cd651d
+F src/os_unix.c abefe4129fe19f03232ecdbcf67f7cfa1d58e2a2
+F src/os_win.c 3bb7e081045aa4c811197ead66febdf8d6209275
+F src/pager.c 78ca1e1f3315c8227431c403c04d791dccf242fb
 F src/pager.h 879fdde5a102d2f21a3135d6f647530b21c2796c
 F src/parse.y ace5c7a125d9f2a410e431ee3209034105045f7e
 F src/pcache.c 1e9aa2dbc0845b52e1b51cc39753b6d1e041cb07
@@ -173,7 +170,7 @@ F src/resolve.c 1c0f32b64f8e3f555fe1f732f9d6f501a7f05706
 F src/rowset.c 69afa95a97c524ba6faf3805e717b5b7ae85a697
 F src/select.c 4903ff1bbd08b55cbce00ea43c645530de41b362
 F src/shell.c fd4ccdb37c3b68de0623eb938a649e0990710714
-F src/sqlite.h.in abe351b1a4c32b140b2db0a68224e85690ea5e60
+F src/sqlite.h.in b82b926ef9c10ca12373c2ecc8bbd2f5a9aad1dc
 F src/sqlite3ext.h 69dfb8116af51b84a029cddb3b35062354270c89
 F src/sqliteInt.h 8eb5d1c63fff70ed30f4b861aeaf8485e663129c
 F src/sqliteLimit.h 196e2f83c3b444c4548fc1874f52f84fdbda40f3
@@ -185,7 +182,7 @@ F src/test2.c e3f564ab1e9fd0b47b0c9e23e7054e38bf0836cf
 F src/test3.c 4c21700c73a890a47fc685c1097bfb661346ac94
 F src/test4.c ad03bb987ddedce928f4258c1e7fa4109a73497d
 F src/test5.c cc55900118fa4add8ec9cf69fc4225a4662f76b1
-F src/test6.c a1217a210fd6e2bcd11ddff4ad2484ec65998043
+F src/test6.c e328b5047ef9b7a8c2d64617625855ae38639708
 F src/test7.c 3f2d63e4ccf97f8c2cf1a7fa0a3c8e2e2a354e6e
 F src/test8.c f959db9a22d882013b64c92753fa793b2ce3bdea
 F src/test9.c bea1e8cf52aa93695487badedd6e1886c321ea60
@@ -195,7 +192,7 @@ F src/test_backup.c c129c91127e9b46e335715ae2e75756e25ba27de
 F src/test_btree.c 47cd771250f09cdc6e12dda5bc71bc0b3abc96e2
 F src/test_config.c 5a11c51af2156e2d07186930b36f2b8239a4393f
 F src/test_demovfs.c da81a5f7785bb352bda7911c332a983ec4f17f27
-F src/test_devsym.c 5a99203fb7ff43047d7e493d1b159585983d4ea6
+F src/test_devsym.c 85286d641bda3f9ecd0e34fcc0b884de198a83b5
 F src/test_func.c 13b582345fb1185a93e46c53310fae8547dcce20
 F src/test_hexio.c 1237f000ec7a491009b1233f5c626ea71bce1ea2
 F src/test_init.c 5d624ffd0409d424cf9adbfe1f056b200270077c
@@ -205,15 +202,15 @@ F src/test_journal.c 424a334cdfdc8a6f975abe3641440147bded3185
 F src/test_loadext.c df586c27176e3c2cb2e099c78da67bf14379a56e
 F src/test_malloc.c 4ab85f2b8ae3a237f4e6557b0a641181a19ffab1
 F src/test_mutex.c ce06b59aca168cd8c520b77159a24352a7469bd3
-F src/test_onefile.c 701553cecc466c13fbebdb27cc7022839512f7bd
-F src/test_osinst.c 700a39f4b7d3959fb65b1a97a5503a9b6d952c6b
+F src/test_onefile.c 01e7a0b0cf27cc974de3b2f825eca5a22185437a
+F src/test_osinst.c f408c6a181f2fb04c56273afd5c3e1e82f60392c
 F src/test_pcache.c 7bf828972ac0d2403f5cfa4cd14da41f8ebe73d8
 F src/test_schema.c 8c06ef9ddb240c7a0fcd31bc221a6a2aade58bf0
 F src/test_server.c bbba05c144b5fc4b52ff650a4328027b3fa5fcc6
 F src/test_stat.c 6ebaf2a86d01ccda24e49c148f1d33e8badda06e
 F src/test_tclvar.c f4dc67d5f780707210d6bb0eb6016a431c04c7fa
 F src/test_thread.c bedd05cad673dba53326f3aa468cc803038896c0
-F src/test_vfs.c bea0f0bdee9b033a62d057bf3451c25760b0414d
+F src/test_vfs.c 7e291f85256516ebde6633bc381ff7eedfa30234
 F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9
 F src/tokenize.c 25ceb0f0a746ea1d0f9553787f3f0a56853cfaeb
 F src/trigger.c 67e95c76d625b92d43409ace771c8e0d02a09ac2
@@ -230,7 +227,7 @@ F src/vdbeblob.c 258a6010ba7a82b72b327fb24c55790655689256
 F src/vdbemem.c 5e579abf6532001dfbee0e640dc34eae897a9807
 F src/vdbetrace.c 864cef96919323482ebd9986f2132435115e9cc2
 F src/vtab.c a0f8a40274e4261696ef57aa806de2776ab72cda
-F src/wal.c c1783e405f0ac19923fd1743ff7a3b29cb27709c
+F src/wal.c 1a63156c661ff22c4c5fc2e6e3ee054017ea8493
 F src/wal.h 906c85760598b18584921fe08008435aa4eeeeb2
 F src/walker.c 3112bb3afe1d85dc52317cb1d752055e9a781f8f
 F src/where.c 926c83c6394e132a1c62b6b12ceeba7d55a34c19
@@ -837,14 +834,7 @@ F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff
 F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224
 F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e
 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f
-P 52577bb5e723d8de4fc609286666b581f8d9c746
-R c858da9982d7ccbc52ee004b587c3119
-U drh
-Z 9b0064c7115f9f6527e0f36107e7bcea
------BEGIN PGP SIGNATURE-----
-Version: GnuPG v1.4.6 (GNU/Linux)
-
-iD8DBQFMPHy+oxKgR168RlERAi4kAJwIB0nNqDnT2kidWrwZhTF/FIEmHgCfZcxg
-GY3yVCZFLW50/Dz5D0SGQsc=
-=vRcP
------END PGP SIGNATURE-----
+P 3d4bb65f10ed0297f38e732ce57e5440cba8deef
+R dddad50687797f0e228c401381867528
+U dan
+Z 1a8aae2f2d97f7f97b0d409af0e6f96f
index 9dff117cbf394e08a7257c91cfe39132e5eadc98..0af99ad77e33a8e6006eacf6669ce4a93c112e9c 100644 (file)
@@ -1 +1 @@
-3d4bb65f10ed0297f38e732ce57e5440cba8deef
\ No newline at end of file
+f4780bde62c6c19146d2723c101540b8db898d38
\ No newline at end of file
index 2c59d66cd470fc7b6328fa38b403321bcfbbb734..63b2b04d23edc8251a70ba7c4c9847d4a5f08a3a 100644 (file)
--- a/src/os.c
+++ b/src/os.c
@@ -100,9 +100,6 @@ int sqlite3OsSectorSize(sqlite3_file *id){
 int sqlite3OsDeviceCharacteristics(sqlite3_file *id){
   return id->pMethods->xDeviceCharacteristics(id);
 }
-int sqlite3OsShmOpen(sqlite3_file *id){
-  return id->pMethods->xShmOpen(id);
-}
 int sqlite3OsShmLock(sqlite3_file *id, int offset, int n, int flags){
   return id->pMethods->xShmLock(id, offset, n, flags);
 }
@@ -110,16 +107,16 @@ void sqlite3OsShmBarrier(sqlite3_file *id){
   id->pMethods->xShmBarrier(id);
 }
 int sqlite3OsShmClose(sqlite3_file *id, int deleteFlag){
-  return id->pMethods->xShmClose(id, deleteFlag);
+  return id->pMethods->xShmUnmap(id, deleteFlag);
 }
 int sqlite3OsShmMap(
-  sqlite3_file *id, 
-  int iPage, 
-  int pgsz, 
-  int isWrite, 
-  void volatile **pp
+  sqlite3_file *id,               /* Database file handle */
+  int iPage,
+  int pgsz,
+  int bExtend,                    /* True to extend file if necessary */
+  void volatile **pp              /* OUT: Pointer to mapping */
 ){
-  return id->pMethods->xShmMap(id, iPage, pgsz, isWrite, pp);
+  return id->pMethods->xShmMap(id, iPage, pgsz, bExtend, pp);
 }
 
 /*
index d51eec3abcb5134b70cb5a142624ca3c92eb4f61..d5ffa17745df343b3b7133a749edd149c4fc75a1 100644 (file)
--- a/src/os.h
+++ b/src/os.h
@@ -247,11 +247,10 @@ int sqlite3OsFileControl(sqlite3_file*,int,void*);
 #define SQLITE_FCNTL_DB_UNCHANGED 0xca093fa0
 int sqlite3OsSectorSize(sqlite3_file *id);
 int sqlite3OsDeviceCharacteristics(sqlite3_file *id);
-int sqlite3OsShmOpen(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 sqlite3OsShmClose(sqlite3_file *id, int);
-int sqlite3OsShmMap(sqlite3_file *,int,int,int,void volatile **);
 
 /* 
 ** Functions for accessing sqlite3_vfs methods 
index 23b558b09c88d1f090a43cb9b3a758df3fb9ed99..e3fafca084da7c44cf91438f5ef66c2d4c175a0a 100644 (file)
@@ -3275,7 +3275,7 @@ static void unixShmPurge(unixFile *pFd){
 }
 
 /*
-** Open a shared-memory area associated with open database file fd.  
+** Open a shared-memory area associated with open database file pDbFd.  
 ** This particular implementation uses mmapped files.
 **
 ** The file used to implement shared-memory is in the same directory
@@ -3294,27 +3294,22 @@ static void unixShmPurge(unixFile *pFd){
 ** file are currently open, in this process or in other processes, then
 ** the file must be truncated to zero length or have its header cleared.
 */
-static int unixShmOpen(
-  sqlite3_file *fd      /* The file descriptor of the associated database */
-){
-  struct unixShm *p = 0;             /* The connection to be opened */
-  struct unixShmNode *pShmNode = 0;  /* The underlying mmapped file */
-  int rc;                            /* Result code */
-  struct unixFile *pDbFd;            /* Underlying database file */
-  unixInodeInfo *pInode;             /* The inode of fd */
-  char *zShmFilename;                /* Name of the file used for SHM */
-  int nShmFilename;                  /* Size of the SHM filename in bytes */
-
-  /* Allocate space for the new sqlite3_shm object.
-  */
+static int unixOpenSharedMemory(unixFile *pDbFd){
+  struct unixShm *p = 0;          /* The connection to be opened */
+  struct unixShmNode *pShmNode;   /* The underlying mmapped file */
+  int rc;                         /* Result code */
+  unixInodeInfo *pInode;          /* The inode of fd */
+  char *zShmFilename;             /* Name of the file used for SHM */
+  int nShmFilename;               /* Size of the SHM filename in bytes */
+
+  /* Allocate space for the new unixShm object. */
   p = sqlite3_malloc( sizeof(*p) );
   if( p==0 ) return SQLITE_NOMEM;
   memset(p, 0, sizeof(*p));
-  pDbFd = (struct unixFile*)fd;
   assert( pDbFd->pShm==0 );
 
-  /* Check to see if a unixShmNode object already exists.  Reuse an existing
-  ** one if present.  Create a new one if necessary.
+  /* Check to see if a unixShmNode object already exists. Reuse an existing
+  ** one if present. Create a new one if necessary.
   */
   unixEnterMutex();
   pInode = pDbFd->pInode;
@@ -3380,49 +3375,107 @@ shm_open_err:
 }
 
 /*
-** Close a connection to shared-memory.  Delete the underlying 
-** storage if deleteFlag is true.
+** 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.
+**
+** If an error occurs, an error code is returned and *pp is set to NULL.
+**
+** Otherwise, if the bExtend 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 
+** bExtend 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 unixShmClose(
-  sqlite3_file *fd,          /* The underlying database file */
-  int deleteFlag             /* Delete shared-memory if true */
+static int unixShmMap(
+  sqlite3_file *fd,               /* Handle open on database file */
+  int iRegion,                    /* Region to retrieve */
+  int szRegion,                   /* Size of regions */
+  int bExtend,                    /* True to extend file if necessary */
+  void volatile **pp              /* OUT: Mapped memory */
 ){
-  unixShm *p;            /* The connection to be closed */
-  unixShmNode *pShmNode; /* The underlying shared-memory file */
-  unixShm **pp;          /* For looping over sibling connections */
-  unixFile *pDbFd;       /* The underlying database file */
+  unixFile *pDbFd = (unixFile*)fd;
+  unixShm *p;
+  unixShmNode *pShmNode;
+  int rc = SQLITE_OK;
+
+  /* If the shared-memory file has not yet been opened, open it now. */
+  if( pDbFd->pShm==0 ){
+    rc = unixOpenSharedMemory(pDbFd);
+    if( rc!=SQLITE_OK ) return rc;
+  }
 
-  pDbFd = (unixFile*)fd;
   p = pDbFd->pShm;
-  if( p==0 ) return SQLITE_OK;
   pShmNode = p->pShmNode;
+  sqlite3_mutex_enter(pShmNode->mutex);
+  assert( szRegion==pShmNode->szRegion || pShmNode->nRegion==0 );
 
-  assert( pShmNode==pDbFd->pInode->pShmNode );
-  assert( pShmNode->pInode==pDbFd->pInode );
+  if( pShmNode->nRegion<=iRegion ){
+    char **apNew;                      /* New apRegion[] array */
+    int nByte = (iRegion+1)*szRegion;  /* Minimum required file size */
+    struct stat sStat;                 /* Used by fstat() */
 
-  /* Remove connection p from the set of connections associated
-  ** with pShmNode */
-  sqlite3_mutex_enter(pShmNode->mutex);
-  for(pp=&pShmNode->pFirst; (*pp)!=p; pp = &(*pp)->pNext){}
-  *pp = p->pNext;
+    pShmNode->szRegion = szRegion;
 
-  /* Free the connection p */
-  sqlite3_free(p);
-  pDbFd->pShm = 0;
-  sqlite3_mutex_leave(pShmNode->mutex);
+    /* 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).
+    */
+    if( fstat(pShmNode->h, &sStat) ){
+      rc = SQLITE_IOERR_SHMSIZE;
+      goto shmpage_out;
+    }
 
-  /* If pShmNode->nRef has reached 0, then close the underlying
-  ** shared-memory file, too */
-  unixEnterMutex();
-  assert( pShmNode->nRef>0 );
-  pShmNode->nRef--;
-  if( pShmNode->nRef==0 ){
-    if( deleteFlag ) unlink(pShmNode->zFilename);
-    unixShmPurge(pDbFd);
+    if( sStat.st_size<nByte ){
+      /* The requested memory region does not exist. If bExtend is set to
+      ** false, exit early. *pp will be set to NULL and SQLITE_OK returned.
+      **
+      ** Alternatively, if bExtend is true, use ftruncate() to allocate
+      ** the requested memory region.
+      */
+      if( !bExtend ) goto shmpage_out;
+      if( ftruncate(pShmNode->h, nByte) ){
+        rc = SQLITE_IOERR_SHMSIZE;
+        goto shmpage_out;
+      }
+    }
+
+    /* Map the requested memory region into this processes address space. */
+    apNew = (char **)sqlite3_realloc(
+        pShmNode->apRegion, (iRegion+1)*sizeof(char *)
+    );
+    if( !apNew ){
+      rc = SQLITE_IOERR_NOMEM;
+      goto shmpage_out;
+    }
+    pShmNode->apRegion = apNew;
+    while(pShmNode->nRegion<=iRegion){
+      void *pMem = mmap(0, szRegion, PROT_READ|PROT_WRITE, 
+          MAP_SHARED, pShmNode->h, iRegion*szRegion
+      );
+      if( pMem==MAP_FAILED ){
+        rc = SQLITE_IOERR;
+        goto shmpage_out;
+      }
+      pShmNode->apRegion[pShmNode->nRegion] = pMem;
+      pShmNode->nRegion++;
+    }
   }
-  unixLeaveMutex();
 
-  return SQLITE_OK;
+shmpage_out:
+  if( pShmNode->nRegion>iRegion ){
+    *pp = pShmNode->apRegion[iRegion];
+  }else{
+    *pp = 0;
+  }
+  sqlite3_mutex_leave(pShmNode->mutex);
+  return rc;
 }
 
 /*
@@ -3552,107 +3605,57 @@ static void unixShmBarrier(
 }
 
 /*
-** 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.
-**
-** If an error occurs, an error code is returned and *pp is set to NULL.
-**
-** 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.
+** Close a connection to shared-memory.  Delete the underlying 
+** storage if deleteFlag is true.
 */
-static int unixShmMap(
-  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 */
+static int unixShmUnmap(
+  sqlite3_file *fd,               /* The underlying database file */
+  int deleteFlag                  /* Delete shared-memory if true */
 ){
-  unixFile *pDbFd = (unixFile*)fd;
-  unixShm *p = pDbFd->pShm;
-  unixShmNode *pShmNode = p->pShmNode;
-  int rc = SQLITE_OK;
-
-  sqlite3_mutex_enter(pShmNode->mutex);
-  assert( szRegion==pShmNode->szRegion || pShmNode->nRegion==0 );
+  unixShm *p;                     /* The connection to be closed */
+  unixShmNode *pShmNode;          /* The underlying shared-memory file */
+  unixShm **pp;                   /* For looping over sibling connections */
+  unixFile *pDbFd;                /* The underlying database file */
 
-  if( pShmNode->nRegion<=iRegion ){
-    char **apNew;                      /* New apRegion[] array */
-    int nByte = (iRegion+1)*szRegion;  /* Minimum required file size */
-    struct stat sStat;                 /* Used by fstat() */
+  pDbFd = (unixFile*)fd;
+  p = pDbFd->pShm;
+  if( p==0 ) return SQLITE_OK;
+  pShmNode = p->pShmNode;
 
-    pShmNode->szRegion = szRegion;
+  assert( pShmNode==pDbFd->pInode->pShmNode );
+  assert( pShmNode->pInode==pDbFd->pInode );
 
-    /* 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).
-    */
-    if( fstat(pShmNode->h, &sStat) ){
-      rc = SQLITE_IOERR_SHMSIZE;
-      goto shmpage_out;
-    }
+  /* Remove connection p from the set of connections associated
+  ** with pShmNode */
+  sqlite3_mutex_enter(pShmNode->mutex);
+  for(pp=&pShmNode->pFirst; (*pp)!=p; pp = &(*pp)->pNext){}
+  *pp = p->pNext;
 
-    if( sStat.st_size<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;
-      if( ftruncate(pShmNode->h, nByte) ){
-        rc = SQLITE_IOERR_SHMSIZE;
-        goto shmpage_out;
-      }  
-    }
+  /* Free the connection p */
+  sqlite3_free(p);
+  pDbFd->pShm = 0;
+  sqlite3_mutex_leave(pShmNode->mutex);
 
-    /* Map the requested memory region into this processes address space. */
-    apNew = (char **)sqlite3_realloc(
-        pShmNode->apRegion, (iRegion+1)*sizeof(char *)
-    );
-    if( !apNew ){
-      rc = SQLITE_IOERR_NOMEM;
-      goto shmpage_out;
-    }
-    pShmNode->apRegion = apNew;
-    while(pShmNode->nRegion<=iRegion){
-      void *pMem = mmap(0, szRegion, PROT_READ|PROT_WRITE, 
-          MAP_SHARED, pShmNode->h, iRegion*szRegion
-      );
-      if( pMem==MAP_FAILED ){
-        rc = SQLITE_IOERR;
-        goto shmpage_out;
-      }
-      pShmNode->apRegion[pShmNode->nRegion] = pMem;
-      pShmNode->nRegion++;
-    }
+  /* If pShmNode->nRef has reached 0, then close the underlying
+  ** shared-memory file, too */
+  unixEnterMutex();
+  assert( pShmNode->nRef>0 );
+  pShmNode->nRef--;
+  if( pShmNode->nRef==0 ){
+    if( deleteFlag ) unlink(pShmNode->zFilename);
+    unixShmPurge(pDbFd);
   }
+  unixLeaveMutex();
 
-shmpage_out:
-  if( pShmNode->nRegion>iRegion ){
-    *pp = pShmNode->apRegion[iRegion];
-  }else{
-    *pp = 0;
-  }
-  sqlite3_mutex_leave(pShmNode->mutex);
-  return rc;
+  return SQLITE_OK;
 }
 
+
 #else
-# define unixShmOpen    0
-# define unixShmLock    0
 # define unixShmMap     0
+# define unixShmLock    0
 # define unixShmBarrier 0
-# define unixShmClose   0
+# define unixShmUnmap   0
 #endif /* #ifndef SQLITE_OMIT_WAL */
 
 /*
@@ -3710,11 +3713,10 @@ static const sqlite3_io_methods METHOD = {                                   \
    unixFileControl,            /* xFileControl */                            \
    unixSectorSize,             /* xSectorSize */                             \
    unixDeviceCharacteristics,  /* xDeviceCapabilities */                     \
-   unixShmOpen,                /* xShmOpen */                                \
-   unixShmLock,                /* xShmLock */                                \
    unixShmMap,                 /* xShmMap */                                 \
+   unixShmLock,                /* xShmLock */                                \
    unixShmBarrier,             /* xShmBarrier */                             \
-   unixShmClose                /* xShmClose */                               \
+   unixShmUnmap                /* xShmUnmap */                               \
 };                                                                           \
 static const sqlite3_io_methods *FINDER##Impl(const char *z, unixFile *p){   \
   UNUSED_PARAMETER(z); UNUSED_PARAMETER(p);                                  \
index 74ac9c89b25197f7f18e7913c8fefe7af50438e7..9349c458836bfc6f6d53186f269475eacd94f913 100644 (file)
@@ -1374,31 +1374,19 @@ static void winShmPurge(sqlite3_vfs *pVfs, int deleteFlag){
 }
 
 /*
-** Open a shared-memory area.  This particular implementation uses
-** mmapped files.
-**
-** zName is a filename used to identify the shared-memory area.  The
-** implementation does not (and perhaps should not) use this name
-** directly, but rather use it as a template for finding an appropriate
-** name for the shared-memory storage.  In this implementation, the
-** string "-index" is appended to zName and used as the name of the
-** mmapped file.
+** Open the shared-memory area associated with database file pDbFd.
 **
 ** When opening a new shared-memory file, if no other instances of that
 ** file are currently open, in this process or in other processes, then
 ** the file must be truncated to zero length or have its header cleared.
 */
-static int winShmOpen(
-  sqlite3_file *fd      /* The file to which to attach shared memory */
-){
-  struct winFile *pDbFd;             /* Database to which to attach SHM */
+static int winOpenSharedMemory(winFile *pDbFd){
   struct winShm *p;                  /* The connection to be opened */
   struct winShmNode *pShmNode = 0;   /* The underlying mmapped file */
   int rc;                            /* Result code */
   struct winShmNode *pNew;           /* Newly allocated winShmNode */
   int nName;                         /* Size of zName in bytes */
 
-  pDbFd = (winFile*)fd;
   assert( pDbFd->pShm==0 );    /* Not previously opened */
 
   /* Allocate space for the new sqlite3_shm object.  Also speculatively
@@ -1680,9 +1668,16 @@ static int winShmMap(
 ){
   winFile *pDbFd = (winFile*)fd;
   winShm *p = pDbFd->pShm;
-  winShmNode *pShmNode = p->pShmNode;
+  winShmNode *pShmNode;
   int rc = SQLITE_OK;
 
+  if( !p ){
+    rc = winOpenSharedMemory(pDbFd);
+    if( rc!=SQLITE_OK ) return rc;
+    p = pDbFd->pShm;
+  }
+  pShmNode = p->pShmNode;
+
   sqlite3_mutex_enter(pShmNode->mutex);
   assert( szRegion==pShmNode->szRegion || pShmNode->nRegion==0 );
 
@@ -1765,9 +1760,8 @@ shmpage_out:
 }
 
 #else
-# define winShmOpen    0
-# define winShmLock    0
 # define winShmMap     0
+# define winShmLock    0
 # define winShmBarrier 0
 # define winShmClose   0
 #endif /* #ifndef SQLITE_OMIT_WAL */
@@ -1783,24 +1777,23 @@ shmpage_out:
 ** sqlite3_file for win32.
 */
 static const sqlite3_io_methods winIoMethod = {
-  2,                        /* iVersion */
-  winClose,
-  winRead,
-  winWrite,
-  winTruncate,
-  winSync,
-  winFileSize,
-  winLock,
-  winUnlock,
-  winCheckReservedLock,
-  winFileControl,
-  winSectorSize,
-  winDeviceCharacteristics,
-  winShmOpen,              /* xShmOpen */
-  winShmLock,              /* xShmLock */
-  winShmMap,               /* xShmMap */
-  winShmBarrier,           /* xShmBarrier */
-  winShmClose              /* xShmClose */
+  2,                              /* iVersion */
+  winClose,                       /* xClose */
+  winRead,                        /* xRead */
+  winWrite,                       /* xWrite */
+  winTruncate,                    /* xTruncate */
+  winSync,                        /* xSync */
+  winFileSize,                    /* xFileSize */
+  winLock,                        /* xLock */
+  winUnlock,                      /* xUnlock */
+  winCheckReservedLock,           /* xCheckReservedLock */
+  winFileControl,                 /* xFileControl */
+  winSectorSize,                  /* xSectorSize */
+  winDeviceCharacteristics,       /* xDeviceCharacteristics */
+  winShmMap,                      /* xShmMap */
+  winShmLock,                     /* xShmLock */
+  winShmBarrier,                  /* xShmBarrier */
+  winShmClose                     /* xShmClose */
 };
 
 /****************************************************************************
index c972440df6c90d1fe2c250d3ea688996694c0dad..dfb29e3df70308123f2fcad5477fe746d9d6531c 100644 (file)
@@ -6023,7 +6023,7 @@ int sqlite3PagerWalCallback(Pager *pPager){
 */
 int sqlite3PagerWalSupported(Pager *pPager){
   const sqlite3_io_methods *pMethods = pPager->fd->pMethods;
-  return pMethods->iVersion>=2 && pMethods->xShmOpen!=0;
+  return pMethods->iVersion>=2 && pMethods->xShmMap!=0;
 }
 
 /*
index 5d29de26b9f6bb5522e9bfabfa24e415d7cbc218..4545a91faa18bb112d3605b8db42b1b3c2c8033d 100644 (file)
@@ -660,7 +660,7 @@ struct sqlite3_io_methods {
   int (*xSectorSize)(sqlite3_file*);
   int (*xDeviceCharacteristics)(sqlite3_file*);
   /* Methods above are valid for version 1 */
-  int (*xShmMap)(sqlite3_file*, int iPg, int pgsz, int, int*, void volatile**);
+  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);
index e5cfa0e99ba7beb648c970676a0148a907bfe74f..cb87cf23c9d77f669d77bd02268fc039adf56d8d 100644 (file)
@@ -523,9 +523,6 @@ static int cfDeviceCharacteristics(sqlite3_file *pFile){
 /*
 ** Pass-throughs for WAL support.
 */
-static int cfShmOpen(sqlite3_file *pFile){
-  return sqlite3OsShmOpen(((CrashFile*)pFile)->pRealFile);
-}
 static int cfShmLock(sqlite3_file *pFile, int ofst, int n, int flags){
   return sqlite3OsShmLock(((CrashFile*)pFile)->pRealFile, ofst, n, flags);
 }
@@ -559,9 +556,8 @@ static const sqlite3_io_methods CrashFileVtab = {
   cfFileControl,                /* xFileControl */
   cfSectorSize,                 /* xSectorSize */
   cfDeviceCharacteristics,      /* xDeviceCharacteristics */
-  cfShmOpen,                    /* xShmOpen */
-  cfShmLock,                    /* xShmLock */
   cfShmMap,                     /* xShmMap */
+  cfShmLock,                    /* xShmLock */
   cfShmBarrier,                 /* xShmBarrier */
   cfShmClose                    /* xShmClose */
 };
index f2b91f03c197e27971430718bb71f2c5910ca75f..b2ebd885aa6f0d466713fbb319926695f858b258 100644 (file)
@@ -50,7 +50,6 @@ static int devsymCheckReservedLock(sqlite3_file*, int *);
 static int devsymFileControl(sqlite3_file*, int op, void *pArg);
 static int devsymSectorSize(sqlite3_file*);
 static int devsymDeviceCharacteristics(sqlite3_file*);
-static int devsymShmOpen(sqlite3_file*);
 static int devsymShmLock(sqlite3_file*,int,int,int);
 static int devsymShmMap(sqlite3_file*,int,int,int, void volatile **);
 static void devsymShmBarrier(sqlite3_file*);
@@ -116,9 +115,8 @@ static sqlite3_io_methods devsym_io_methods = {
   devsymFileControl,                /* xFileControl */
   devsymSectorSize,                 /* xSectorSize */
   devsymDeviceCharacteristics,      /* xDeviceCharacteristics */
-  devsymShmOpen,                    /* xShmOpen */
-  devsymShmLock,                    /* xShmLock */
   devsymShmMap,                     /* xShmMap */
+  devsymShmLock,                    /* xShmLock */
   devsymShmBarrier,                 /* xShmBarrier */
   devsymShmClose                    /* xShmClose */
 };
@@ -237,10 +235,6 @@ static int devsymDeviceCharacteristics(sqlite3_file *pFile){
 /*
 ** Shared-memory methods are all pass-thrus.
 */
-static int devsymShmOpen(sqlite3_file *pFile){
-  devsym_file *p = (devsym_file *)pFile;
-  return sqlite3OsShmOpen(p->pReal);
-}
 static int devsymShmLock(sqlite3_file *pFile, int ofst, int n, int flags){
   devsym_file *p = (devsym_file *)pFile;
   return sqlite3OsShmLock(p->pReal, ofst, n, flags);
index 65c6b7afdbf294ae37e7e86a2ad4b27b49a9ed9f..64d5a66a351aa79d6a147c82e112fa2a5a2dfa2c 100644 (file)
@@ -219,9 +219,8 @@ static sqlite3_io_methods fs_io_methods = {
   fsFileControl,                /* xFileControl */
   fsSectorSize,                 /* xSectorSize */
   fsDeviceCharacteristics,      /* xDeviceCharacteristics */
-  0,                            /* xShmOpen */
-  0,                            /* xShmLock */
   0,                            /* xShmMap */
+  0,                            /* xShmLock */
   0,                            /* xShmBarrier */
   0                             /* xShmClose */
 };
@@ -241,9 +240,8 @@ static sqlite3_io_methods tmp_io_methods = {
   tmpFileControl,               /* xFileControl */
   tmpSectorSize,                /* xSectorSize */
   tmpDeviceCharacteristics,     /* xDeviceCharacteristics */
-  0,                            /* xShmOpen */
-  0,                            /* xShmLock */
   0,                            /* xShmMap */
+  0,                            /* xShmLock */
   0,                            /* xShmBarrier */
   0                             /* xShmClose */
 };
index d77eeafa56ed09908134d1ab13560caa53fc3f99..25e9bcbfb0ab4a3b9848dbddca63672f3bd47e7d 100644 (file)
@@ -98,8 +98,7 @@
 #define OS_TRUNCATE          18
 #define OS_UNLOCK            19
 #define OS_WRITE             20
-#define OS_SHMOPEN           21
-#define OS_SHMCLOSE          22
+#define OS_SHMUNMAP          22
 #define OS_SHMMAP            23
 #define OS_SHMLOCK           25
 #define OS_SHMBARRIER        26
@@ -149,11 +148,10 @@ static int vfslogFileControl(sqlite3_file*, int op, void *pArg);
 static int vfslogSectorSize(sqlite3_file*);
 static int vfslogDeviceCharacteristics(sqlite3_file*);
 
-static int vfslogShmOpen(sqlite3_file *pFile);
 static int vfslogShmLock(sqlite3_file *pFile, int ofst, int n, int flags);
 static int vfslogShmMap(sqlite3_file *pFile,int,int,int,volatile void **);
 static void vfslogShmBarrier(sqlite3_file*);
-static int vfslogShmClose(sqlite3_file *pFile, int deleteFlag);
+static int vfslogShmUnmap(sqlite3_file *pFile, int deleteFlag);
 
 /*
 ** Method declarations for vfslog_vfs.
@@ -209,11 +207,10 @@ static sqlite3_io_methods vfslog_io_methods = {
   vfslogFileControl,              /* xFileControl */
   vfslogSectorSize,               /* xSectorSize */
   vfslogDeviceCharacteristics,    /* xDeviceCharacteristics */
-  vfslogShmOpen,                  /* xShmOpen */
-  vfslogShmLock,                  /* xShmLock */
   vfslogShmMap,                   /* xShmMap */
+  vfslogShmLock,                  /* xShmLock */
   vfslogShmBarrier,               /* xShmBarrier */
-  vfslogShmClose                  /* xShmClose */
+  vfslogShmUnmap                  /* xShmUnmap */
 };
 
 #if defined(SQLITE_OS_UNIX) && !defined(NO_GETTOD)
@@ -423,16 +420,6 @@ static int vfslogDeviceCharacteristics(sqlite3_file *pFile){
   return rc;
 }
 
-static int vfslogShmOpen(sqlite3_file *pFile){
-  int rc;
-  sqlite3_uint64 t;
-  VfslogFile *p = (VfslogFile *)pFile;
-  t = vfslog_time();
-  rc = p->pReal->pMethods->xShmOpen(p->pReal);
-  t = vfslog_time() - t;
-  vfslog_call(p->pVfslog, OS_SHMOPEN, p->iFileId, t, rc, 0, 0);
-  return rc;
-}
 static int vfslogShmLock(sqlite3_file *pFile, int ofst, int n, int flags){
   int rc;
   sqlite3_uint64 t;
@@ -467,14 +454,14 @@ static void vfslogShmBarrier(sqlite3_file *pFile){
   t = vfslog_time() - t;
   vfslog_call(p->pVfslog, OS_SHMBARRIER, p->iFileId, t, SQLITE_OK, 0, 0);
 }
-static int vfslogShmClose(sqlite3_file *pFile, int deleteFlag){
+static int vfslogShmUnmap(sqlite3_file *pFile, int deleteFlag){
   int rc;
   sqlite3_uint64 t;
   VfslogFile *p = (VfslogFile *)pFile;
   t = vfslog_time();
-  rc = p->pReal->pMethods->xShmClose(p->pReal, deleteFlag);
+  rc = p->pReal->pMethods->xShmUnmap(p->pReal, deleteFlag);
   t = vfslog_time() - t;
-  vfslog_call(p->pVfslog, OS_SHMCLOSE, p->iFileId, t, rc, 0, 0);
+  vfslog_call(p->pVfslog, OS_SHMUNMAP, p->iFileId, t, rc, 0, 0);
   return rc;
 }
 
@@ -794,8 +781,7 @@ static const char *vfslog_eventname(int eEvent){
     case OS_SLEEP:             zEvent = "xSleep"; break;
     case OS_CURRENTTIME:       zEvent = "xCurrentTime"; break;
 
-    case OS_SHMCLOSE:          zEvent = "xShmClose"; break;
-    case OS_SHMOPEN:           zEvent = "xShmOpen"; break;
+    case OS_SHMUNMAP:          zEvent = "xShmUnmap"; break;
     case OS_SHMLOCK:           zEvent = "xShmLock"; break;
     case OS_SHMBARRIER:        zEvent = "xShmBarrier"; break;
     case OS_SHMMAP:            zEvent = "xShmMap"; break;
index 1b5bd59fb6f7b46a59439c0cf8ba260956007f9c..f577bf5106a8a21d7cab8b7d42c8fb69cad3839e 100644 (file)
@@ -187,7 +187,7 @@ static int tvfsShmOpen(sqlite3_file*);
 static int tvfsShmLock(sqlite3_file*, int , int, int);
 static int tvfsShmMap(sqlite3_file*,int,int,int, void volatile **);
 static void tvfsShmBarrier(sqlite3_file*);
-static int tvfsShmClose(sqlite3_file*, int);
+static int tvfsShmUnmap(sqlite3_file*, int);
 
 static sqlite3_io_methods tvfs_io_methods = {
   2,                              /* iVersion */
@@ -203,11 +203,10 @@ static sqlite3_io_methods tvfs_io_methods = {
   tvfsFileControl,                /* xFileControl */
   tvfsSectorSize,                 /* xSectorSize */
   tvfsDeviceCharacteristics,      /* xDeviceCharacteristics */
-  tvfsShmOpen,                    /* xShmOpen */
-  tvfsShmLock,                    /* xShmLock */
   tvfsShmMap,                     /* xShmMap */
+  tvfsShmLock,                    /* xShmLock */
   tvfsShmBarrier,                 /* xShmBarrier */
-  tvfsShmClose                    /* xShmClose */
+  tvfsShmUnmap                    /* xShmUnmap */
 };
 
 static int tvfsResultCode(Testvfs *p, int *pRc){
@@ -580,15 +579,14 @@ static int tvfsOpen(
     if( pVfs->iVersion>1 ){
       nByte = sizeof(sqlite3_io_methods);
     }else{
-      nByte = offsetof(sqlite3_io_methods, xShmOpen);
+      nByte = offsetof(sqlite3_io_methods, xShmMap);
     }
 
     pMethods = (sqlite3_io_methods *)ckalloc(nByte);
     memcpy(pMethods, &tvfs_io_methods, nByte);
     pMethods->iVersion = pVfs->iVersion;
     if( pVfs->iVersion>1 && ((Testvfs *)pVfs->pAppData)->isNoshm ){
-      pMethods->xShmOpen = 0;
-      pMethods->xShmClose = 0;
+      pMethods->xShmUnmap = 0;
       pMethods->xShmLock = 0;
       pMethods->xShmBarrier = 0;
       pMethods->xShmMap = 0;
@@ -789,6 +787,13 @@ static int tvfsShmMap(
   TestvfsFd *pFd = tvfsGetFd(pFile);
   Testvfs *p = (Testvfs *)(pFd->pVfs->pAppData);
 
+  if( 0==pFd->pShm ){
+    rc = tvfsShmOpen(pFile);
+    if( rc!=SQLITE_OK ){
+      return rc;
+    }
+  }
+
   if( p->pScript && p->mask&TESTVFS_SHMMAP_MASK ){
     Tcl_Obj *pArg = Tcl_NewObj();
     Tcl_IncrRefCount(pArg);
@@ -888,7 +893,7 @@ static void tvfsShmBarrier(sqlite3_file *pFile){
   }
 }
 
-static int tvfsShmClose(
+static int tvfsShmUnmap(
   sqlite3_file *pFile,
   int deleteFlag
 ){
@@ -898,10 +903,11 @@ static int tvfsShmClose(
   TestvfsBuffer *pBuffer = pFd->pShm;
   TestvfsFd **ppFd;
 
+  if( !pBuffer ) return SQLITE_OK;
   assert( pFd->pShmId && pFd->pShm );
 
   if( p->pScript && p->mask&TESTVFS_SHMCLOSE_MASK ){
-    tvfsExecTcl(p, "xShmClose", 
+    tvfsExecTcl(p, "xShmUnmap", 
         Tcl_NewStringObj(pFd->pShm->zFile, -1), pFd->pShmId, 0
     );
     tvfsResultCode(p, &rc);
@@ -1023,7 +1029,7 @@ static int testvfs_obj_cmd(
         { "xShmOpen",    TESTVFS_SHMOPEN_MASK },
         { "xShmLock",    TESTVFS_SHMLOCK_MASK },
         { "xShmBarrier", TESTVFS_SHMBARRIER_MASK },
-        { "xShmClose",   TESTVFS_SHMCLOSE_MASK },
+        { "xShmUnmap",   TESTVFS_SHMCLOSE_MASK },
         { "xShmMap",     TESTVFS_SHMMAP_MASK },
         { "xSync",       TESTVFS_SYNC_MASK },
         { "xDelete",     TESTVFS_DELETE_MASK },
index b5d122cb3bd49eafa1fd7f59a03fce0b13ed97e1..a6bc7c121b4c5cc15e4e175750300f6fc3c83391 100644 (file)
--- a/src/wal.c
+++ b/src/wal.c
@@ -413,7 +413,6 @@ struct Wal {
   u16 szPage;                /* Database page size */
   i16 readLock;              /* Which read lock is being held.  -1 for none */
   u8 exclusiveMode;          /* Non-zero if connection is in exclusive mode */
-  u8 isWIndexOpen;           /* True if ShmOpen() called on pDbFd */
   u8 writeLock;              /* True if in a write transaction */
   u8 ckptLock;               /* True if holding a checkpoint lock */
   WalIndexHdr hdr;           /* Wal-index header for current transaction */
@@ -1168,10 +1167,7 @@ recovery_error:
 ** Close an open wal-index.
 */
 static void walIndexClose(Wal *pWal, int isDelete){
-  if( pWal->isWIndexOpen ){
-    sqlite3OsShmClose(pWal->pDbFd, isDelete);
-    pWal->isWIndexOpen = 0;
-  }
+  sqlite3OsShmClose(pWal->pDbFd, isDelete);
 }
 
 /* 
@@ -1226,14 +1222,10 @@ int sqlite3WalOpen(
   pRet->pDbFd = pDbFd;
   pRet->readLock = -1;
   pRet->zWalName = zWalName;
-  rc = sqlite3OsShmOpen(pDbFd);
 
   /* Open file handle on the write-ahead log file. */
-  if( rc==SQLITE_OK ){
-    pRet->isWIndexOpen = 1;
-    flags = (SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE|SQLITE_OPEN_MAIN_JOURNAL);
-    rc = sqlite3OsOpen(pVfs, zWalName, pRet->pWalFd, flags, &flags);
-  }
+  flags = (SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE|SQLITE_OPEN_MAIN_JOURNAL);
+  rc = sqlite3OsOpen(pVfs, zWalName, pRet->pWalFd, flags, &flags);
 
   if( rc!=SQLITE_OK ){
     walIndexClose(pRet, 0);
@@ -2204,8 +2196,10 @@ int sqlite3WalBeginWriteTransaction(Wal *pWal){
 ** routine merely releases the lock.
 */
 int sqlite3WalEndWriteTransaction(Wal *pWal){
-  walUnlockExclusive(pWal, WAL_WRITE_LOCK, 1);
-  pWal->writeLock = 0;
+  if( pWal->writeLock ){
+    walUnlockExclusive(pWal, WAL_WRITE_LOCK, 1);
+    pWal->writeLock = 0;
+  }
   return SQLITE_OK;
 }