]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Implement xUnlink, xShmMap, and xShmUnmap for lsm1 on Win32. lsm-vtab
authormistachkin <mistachkin@noemail.net>
Thu, 29 Jun 2017 12:54:58 +0000 (12:54 +0000)
committermistachkin <mistachkin@noemail.net>
Thu, 29 Jun 2017 12:54:58 +0000 (12:54 +0000)
FossilOrigin-Name: 680cc064c9e809ddc643074b5e65677f484d904b3d52826f6def480ddaa8f0ab

ext/lsm1/lsm_win32.c
manifest
manifest.uuid

index af581766095ab63def755f96a4eb9c6dd021f3a2..88b275f8e960eece0463c22af61c9c942ff8b2e0 100644 (file)
@@ -41,8 +41,9 @@ struct Win32File {
   HANDLE hMap;                    /* File handle for mapping */
   LPVOID pMap;                    /* Pointer to mapping of file fd */
   size_t nMap;                    /* Size of mapping at pMap in bytes */
-  int nShm;                       /* Number of entries in array apShm[] */
-  void **apShm;                   /* Array of 32K shared memory segments */
+  int nShm;                       /* Number of entries in ahShm[]/apShm[] */
+  LPHANDLE ahShm;                 /* Array of handles for shared mappings */
+  LPVOID *apShm;                  /* Array of 32K shared memory segments */
 };
 
 static char *win32ShmFile(Win32File *p){
@@ -187,6 +188,57 @@ static char *win32UnicodeToUtf8(lsm_env *pEnv, LPCWSTR zWideText){
                             ((a)==ERROR_PATH_NOT_FOUND))
 #endif
 
+static int win32Open(
+  lsm_env *pEnv,
+  const char *zFile,
+  int flags,
+  LPHANDLE phFile
+){
+  int rc;
+  LPWSTR zConverted;
+
+  zConverted = win32Utf8ToUnicode(pEnv, zFile);
+  if( zConverted==0 ){
+    rc = LSM_NOMEM_BKPT;
+  }else{
+    int bReadonly = (flags & LSM_OPEN_READONLY);
+    DWORD dwDesiredAccess;
+    DWORD dwShareMode = FILE_SHARE_READ | FILE_SHARE_WRITE;
+    DWORD dwCreationDisposition;
+    DWORD dwFlagsAndAttributes = FILE_ATTRIBUTE_NORMAL;
+    HANDLE hFile;
+    int nRetry = 0;
+    if( bReadonly ){
+      dwDesiredAccess = GENERIC_READ;
+      dwCreationDisposition = OPEN_EXISTING;
+    }else{
+      dwDesiredAccess = GENERIC_READ | GENERIC_WRITE;
+      dwCreationDisposition = OPEN_ALWAYS;
+    }
+    while( (hFile = CreateFileW((LPCWSTR)zConverted,
+                                dwDesiredAccess,
+                                dwShareMode, NULL,
+                                dwCreationDisposition,
+                                dwFlagsAndAttributes,
+                                NULL))==INVALID_HANDLE_VALUE &&
+                                win32RetryIoerr(pEnv, &nRetry) ){
+      /* Noop */
+    }
+    lsmFree(pEnv, zConverted);
+    if( hFile!=INVALID_HANDLE_VALUE ){
+      *phFile = hFile;
+      rc = LSM_OK;
+    }else{
+      if( win32IsNotFound(GetLastError()) ){
+        rc = lsmErrorBkpt(LSM_IOERR_NOENT);
+      }else{
+        rc = LSM_IOERR_BKPT;
+      }
+    }
+  }
+  return rc;
+}
+
 static int lsmWin32OsOpen(
   lsm_env *pEnv,
   const char *zFile,
@@ -200,51 +252,16 @@ static int lsmWin32OsOpen(
   if( pWin32File==0 ){
     rc = LSM_NOMEM_BKPT;
   }else{
-    LPWSTR zConverted;
-    int bReadonly = (flags & LSM_OPEN_READONLY);
-    DWORD dwDesiredAccess;
-    DWORD dwShareMode = FILE_SHARE_READ | FILE_SHARE_WRITE;
-    DWORD dwCreationDisposition;
-    DWORD dwFlagsAndAttributes = FILE_ATTRIBUTE_NORMAL;
     HANDLE hFile;
 
-    zConverted = win32Utf8ToUnicode(pEnv, zFile);
-    if( zConverted==0 ){
+    rc = win32Open(pEnv, zFile, flags, &hFile);
+    if( rc==LSM_OK ){
+      pWin32File->pEnv = pEnv;
+      pWin32File->zName = zFile;
+      pWin32File->hFile = hFile;
+    }else{
       lsmFree(pEnv, pWin32File);
       pWin32File = 0;
-      rc = LSM_NOMEM_BKPT;
-    }else{
-      int nRetry = 0;
-      if( bReadonly ){
-        dwDesiredAccess = GENERIC_READ;
-        dwCreationDisposition = OPEN_EXISTING;
-      }else{
-        dwDesiredAccess = GENERIC_READ | GENERIC_WRITE;
-        dwCreationDisposition = OPEN_ALWAYS;
-      }
-      while( (hFile = CreateFileW((LPCWSTR)zConverted,
-                                  dwDesiredAccess,
-                                  dwShareMode, NULL,
-                                  dwCreationDisposition,
-                                  dwFlagsAndAttributes,
-                                  NULL))==INVALID_HANDLE_VALUE &&
-                                  win32RetryIoerr(pEnv, &nRetry) ){
-        /* Noop */
-      }
-      lsmFree(pEnv, zConverted);
-      if( hFile!=INVALID_HANDLE_VALUE ){
-        pWin32File->pEnv = pEnv;
-        pWin32File->zName = zFile;
-        pWin32File->hFile = hFile;
-      }else{
-        lsmFree(pEnv, pWin32File);
-        pWin32File = 0;
-        if( win32IsNotFound(GetLastError()) ){
-          rc = lsmErrorBkpt(LSM_IOERR_NOENT);
-        }else{
-          rc = LSM_IOERR_BKPT;
-        }
-      }
     }
   }
   *ppFile = (lsm_file *)pWin32File;
@@ -286,23 +303,29 @@ static int lsmWin32OsWrite(
   return LSM_OK;
 }
 
-static int lsmWin32OsTruncate(
-  lsm_file *pFile, /* File to write to */
-  lsm_i64 nSize    /* Size to truncate file to */
+static int win32Truncate(
+  HANDLE hFile,
+  lsm_i64 nSize
 ){
-  Win32File *pWin32File = (Win32File *)pFile;
   LARGE_INTEGER offset;
-
   offset.QuadPart = nSize;
-  if( !SetFilePointerEx(pWin32File->hFile, offset, 0, FILE_BEGIN) ){
+  if( !SetFilePointerEx(hFile, offset, 0, FILE_BEGIN) ){
     return LSM_IOERR_BKPT;
   }
-  if (!SetEndOfFile(pWin32File->hFile) ){
+  if (!SetEndOfFile(hFile) ){
     return LSM_IOERR_BKPT;
   }
   return LSM_OK;
 }
 
+static int lsmWin32OsTruncate(
+  lsm_file *pFile, /* File to write to */
+  lsm_i64 nSize    /* Size to truncate file to */
+){
+  Win32File *pWin32File = (Win32File *)pFile;
+  return win32Truncate(pWin32File->hFile, nSize);
+}
+
 static int lsmWin32OsRead(
   lsm_file *pFile, /* File to read from */
   lsm_i64 iOff,    /* Offset to read from */
@@ -508,8 +531,47 @@ static int lsmWin32OsFileid(
   return LSM_OK;
 }
 
+static int win32Delete(
+  lsm_env *pEnv,
+  const char *zFile
+){
+  int rc;
+  LPWSTR zConverted;
+
+  zConverted = win32Utf8ToUnicode(pEnv, zFile);
+  if( zConverted==0 ){
+    rc = LSM_NOMEM_BKPT;
+  }else{
+    int nRetry = 0;
+    DWORD attr;
+    DWORD lastErrno;
+
+    do {
+      attr = GetFileAttributesW(zConverted);
+      if ( attr==INVALID_FILE_ATTRIBUTES ){
+        rc = LSM_IOERR_BKPT;
+        break;
+      }
+      if ( attr&FILE_ATTRIBUTE_DIRECTORY ){
+        rc = LSM_IOERR_BKPT; /* Files only. */
+        break;
+      }
+      if ( DeleteFileW(zConverted) ){
+        rc = LSM_OK; /* Deleted OK. */
+        break;
+      }
+      if ( !win32RetryIoerr(pEnv, &nRetry) ){
+        rc = LSM_IOERR_BKPT; /* No more retries. */
+        break;
+      }
+    }while( 1 );
+  }
+  lsmFree(pEnv, zConverted);
+  return rc;
+}
+
 static int lsmWin32OsUnlink(lsm_env *pEnv, const char *zFile){
-  return LSM_ERROR;
+  return win32Delete(pEnv, zFile);
 }
 
 int lsmWin32OsLock(lsm_file *pFile, int iLock, int eType){
@@ -569,7 +631,73 @@ int lsmWin32OsTestLock(lsm_file *pFile, int iLock, int nLock, int eType){
 }
 
 int lsmWin32OsShmMap(lsm_file *pFile, int iChunk, int sz, void **ppShm){
-  return LSM_ERROR;
+  int rc;
+  Win32File *pWin32File = (Win32File *)pFile;
+
+  *ppShm = NULL;
+  assert( sz>=0 );
+  assert( sz==LSM_SHM_CHUNK_SIZE );
+  if( iChunk>=pWin32File->nShm ){
+    int i;
+    void **apNew;
+    int nNew = iChunk+1;
+    lsm_i64 nReq = nNew * sz;
+    LARGE_INTEGER fileSize;
+
+    /* If the shared-memory file has not been opened, open it now. */
+    if( pWin32File->hShmFile==NULL ){
+      char *zShm = win32ShmFile(pWin32File);
+      if( !zShm ) return LSM_NOMEM_BKPT;
+      rc = win32Open(pWin32File->pEnv, zShm, 0, &pWin32File->hShmFile);
+      lsmFree(pWin32File->pEnv, zShm);
+      if( rc!=LSM_OK ){
+        return rc;
+      }
+    }
+
+    /* If the shared-memory file is not large enough to contain the
+    ** requested chunk, cause it to grow.  */
+    memset(&fileSize, 0, sizeof(LARGE_INTEGER));
+    if( !GetFileSizeEx(pWin32File->hShmFile, &fileSize) ){
+      return LSM_IOERR_BKPT;
+    }
+    assert( fileSize.QuadPart>=0 );
+    if( fileSize.QuadPart<nReq ){
+      rc = win32Truncate(pWin32File->hShmFile, nReq);
+      if( rc!=LSM_OK ){
+        return rc;
+      }
+    }
+
+    apNew = (void **)lsmRealloc(pWin32File->pEnv, pWin32File->apShm,
+                                sizeof(LPVOID) * nNew);
+    if( !apNew ) return LSM_NOMEM_BKPT;
+    for(i=pWin32File->nShm; i<nNew; i++){
+      apNew[i] = NULL;
+    }
+    pWin32File->apShm = apNew;
+    pWin32File->nShm = nNew;
+  }
+
+  if( pWin32File->apShm[iChunk]==NULL ){
+    HANDLE hMap;
+    LPVOID pMap;
+    hMap = CreateFileMappingW(pWin32File->hShmFile, NULL, PAGE_READWRITE, 0,
+                              (DWORD)sz, NULL);
+    if( hMap==NULL ){
+      return LSM_IOERR_BKPT;
+    }
+    pWin32File->ahShm[iChunk] = hMap;
+    pMap = MapViewOfFile(hMap, FILE_MAP_WRITE | FILE_MAP_READ, 0, 0,
+                         (SIZE_T)sz);
+    if( pMap==NULL ){
+      return LSM_IOERR_BKPT;
+    }
+    pWin32File->apShm[iChunk] = pMap;
+    pWin32File->nMap = (SIZE_T)sz;
+  }
+  *ppShm = pWin32File->apShm[iChunk];
+  return LSM_OK;
 }
 
 void lsmWin32OsShmBarrier(void){
@@ -577,7 +705,29 @@ void lsmWin32OsShmBarrier(void){
 }
 
 int lsmWin32OsShmUnmap(lsm_file *pFile, int bDelete){
-  return LSM_ERROR;
+  Win32File *pWin32File = (Win32File *)pFile;
+
+  if( pWin32File->hShmFile!=NULL ){
+    int i;
+    for(i=0; i<pWin32File->nShm; i++){
+      if( pWin32File->apShm[i]!=NULL ){
+        UnmapViewOfFile(pWin32File->apShm[i]);
+        pWin32File->apShm[i] = NULL;
+      }
+      if( pWin32File->ahShm[i]!=NULL ){
+        CloseHandle(pWin32File->ahShm[i]);
+        pWin32File->ahShm[i] = NULL;
+      }
+    }
+    CloseHandle(pWin32File->hShmFile);
+    pWin32File->hShmFile = 0;
+    if( bDelete ){
+      char *zShm = win32ShmFile(pWin32File);
+      if( zShm ){ win32Delete(pWin32File->pEnv, zShm); }
+      lsmFree(pWin32File->pEnv, zShm);
+    }
+  }
+  return LSM_OK;
 }
 
 #define MX_CLOSE_ATTEMPT 3
index 6fee259a7a9a42ef68d386105d38c0332ea8859c..7973b1262a243b746260d6b024a70896412cfecb 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Implement\sxRemap\sfor\slsm1\son\sWin32.\s\sAlso,\szero\sfile\shandle\swhen\sclosing\sit.
-D 2017-06-29T00:20:42.289
+C Implement\sxUnlink,\sxShmMap,\sand\sxShmUnmap\sfor\slsm1\son\sWin32.
+D 2017-06-29T12:54:58.254
 F Makefile.in 1cc758ce3374a32425e4d130c2fe7b026b20de5b8843243de75f087c0a2661fb
 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434
 F Makefile.msc d389c6fb3344ea6887b386d56784a6d8a5c85107294448aeda50ac404285a1ef
@@ -249,7 +249,7 @@ F ext/lsm1/lsm_tree.c 5d9fb2bc58a1a70c75126bd8d7198f7b627e165b
 F ext/lsm1/lsm_unix.c ee0201dff10ce2008ef13a65f52a6ea348f287e795270f651596f812fcfccdcc
 F ext/lsm1/lsm_varint.c b19ae9bd26b5a1e8402fb8a564b25d9542338a41
 F ext/lsm1/lsm_vtab.c fff303ce03168eca9e333add3c1429b3471674b0
-F ext/lsm1/lsm_win32.c 4896cd8af7a65dcd2b2dacca81455be896130b23ca19cf4a7e3f6eed5442d812
+F ext/lsm1/lsm_win32.c bd3f7e82ec71ad09a1487d5b64fbc03e99398dc7e8ec0160b9cd0deb3ce4421c
 F ext/misc/README.md 8e008c8d2b02e09096b31dfba033253ac27c6c06a18aa5826e299fa7601d90b2
 F ext/misc/amatch.c 6db4607cb17c54b853a2d7c7c36046d004853f65b9b733e6f019d543d5dfae87
 F ext/misc/anycollseq.c 5ffdfde9829eeac52219136ad6aa7cd9a4edb3b15f4f2532de52f4a22525eddb
@@ -1624,7 +1624,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93
 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
 F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
 F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
-P 9112117dad8085c385aa614cd982b307f5822761607ba358f34df7848c549134
-R 887ca9ca211e19ac7f1bf925dfe592df
+P 93c9aa7d9aea46b331c53ff579ef704e88ce90f96600b69479a87a4bb4ca2a91
+R c37c412a3ae97e64852f2f71114bfb03
 U mistachkin
-Z 2dc70b160b5c8095c4a09a655916e2c6
+Z 58e908e3128eb99a98afbb7831a85730
index 63f7e3d038e04e17f35d17511d7aff4abe8dcd6e..f40f6d75a851a81b79742dd83e9615d91e1a2ec3 100644 (file)
@@ -1 +1 @@
-93c9aa7d9aea46b331c53ff579ef704e88ce90f96600b69479a87a4bb4ca2a91
\ No newline at end of file
+680cc064c9e809ddc643074b5e65677f484d904b3d52826f6def480ddaa8f0ab
\ No newline at end of file