]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Work in progress porting lsm1 to Win32.
authormistachkin <mistachkin@noemail.net>
Tue, 27 Jun 2017 05:59:47 +0000 (05:59 +0000)
committermistachkin <mistachkin@noemail.net>
Tue, 27 Jun 2017 05:59:47 +0000 (05:59 +0000)
FossilOrigin-Name: 2017636e93cf810fe4d1247c18de9f316fca037035a026f77c4588563d7bf0cc

Makefile.msc
ext/lsm1/Makefile.msc [new file with mode: 0644]
ext/lsm1/lsmInt.h
ext/lsm1/lsm_file.c
ext/lsm1/lsm_unix.c
ext/lsm1/lsm_win32.c
manifest
manifest.uuid

index 8b8d28d1f21e0e808687f8bdac765571bd470722..3d23ad510ad7e7e81fa04cc1d0795fb52b750b9a 100644 (file)
@@ -2242,6 +2242,9 @@ rbu.exe:  $(TOP)\ext\rbu\rbu.c $(TOP)\ext\rbu\sqlite3rbu.c $(SQLITE3C) $(SQLITE3H
        $(LTLINK) $(NO_WARN) -DSQLITE_ENABLE_RBU \
                $(TOP)\ext\rbu\rbu.c $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS)
 
+LSMDIR=$(TOP)\ext\lsm1
+!INCLUDE $(LSMDIR)\Makefile.msc
+
 moreclean:     clean
        del /Q $(SQLITE3C) $(SQLITE3H) 2>NUL
 # <</mark>>
diff --git a/ext/lsm1/Makefile.msc b/ext/lsm1/Makefile.msc
new file mode 100644 (file)
index 0000000..633404a
--- /dev/null
@@ -0,0 +1,93 @@
+#
+# This Makefile is designed for use with main.mk in the root directory of
+# this project. After including main.mk, the users makefile should contain:
+#
+#    LSMDIR=$(TOP)\ext\lsm1\
+#    include $(LSMDIR)\Makefile.msc
+#
+# The most useful targets are [lsmtest.exe] and [lsm.dll].
+#
+
+LSMOBJ    = \
+  lsm_ckpt.lo \
+  lsm_file.lo \
+  lsm_log.lo \
+  lsm_main.lo \
+  lsm_mem.lo \
+  lsm_mutex.lo \
+  lsm_shared.lo \
+  lsm_sorted.lo \
+  lsm_str.lo \
+  lsm_tree.lo \
+  lsm_unix.lo \
+  lsm_win32.lo \
+  lsm_varint.lo \
+  lsm_vtab.lo
+
+LSMHDR   = \
+  $(LSMDIR)\lsm.h \
+  $(LSMDIR)\lsmInt.h
+
+LSMTESTSRC = $(LSMDIR)\lsm-test\lsmtest1.c $(LSMDIR)\lsm-test\lsmtest2.c     \
+             $(LSMDIR)\lsm-test\lsmtest3.c $(LSMDIR)\lsm-test\lsmtest4.c     \
+             $(LSMDIR)\lsm-test\lsmtest5.c $(LSMDIR)\lsm-test\lsmtest6.c     \
+             $(LSMDIR)\lsm-test\lsmtest7.c $(LSMDIR)\lsm-test\lsmtest8.c     \
+             $(LSMDIR)\lsm-test\lsmtest9.c                                   \
+             $(LSMDIR)\lsm-test\lsmtest_datasource.c \
+             $(LSMDIR)\lsm-test\lsmtest_func.c $(LSMDIR)\lsm-test\lsmtest_io.c  \
+             $(LSMDIR)\lsm-test\lsmtest_main.c $(LSMDIR)\lsm-test\lsmtest_mem.c \
+             $(LSMDIR)\lsm-test\lsmtest_tdb.c $(LSMDIR)\lsm-test\lsmtest_tdb3.c \
+             $(LSMDIR)\lsm-test\lsmtest_util.c
+
+# all: lsm.dll
+
+LSMOPTS = -DLSM_MUTEX_WIN32=1 -I$(LSMDIR)
+
+lsm_ckpt.lo:   $(LSMDIR)\lsm_ckpt.c $(LSMHDR) $(SQLITE3H)
+       $(LTCOMPILE) $(LSMOPTS) -c $(LSMDIR)\lsm_ckpt.c
+
+lsm_file.lo:   $(LSMDIR)\lsm_file.c $(LSMHDR) $(SQLITE3H)
+       $(LTCOMPILE) $(LSMOPTS) -c $(LSMDIR)\lsm_file.c
+
+lsm_log.lo:    $(LSMDIR)\lsm_log.c $(LSMHDR) $(SQLITE3H)
+       $(LTCOMPILE) $(LSMOPTS) -c $(LSMDIR)\lsm_log.c
+
+lsm_main.lo:   $(LSMDIR)\lsm_main.c $(LSMHDR) $(SQLITE3H)
+       $(LTCOMPILE) $(LSMOPTS) -c $(LSMDIR)\lsm_main.c
+
+lsm_mem.lo:    $(LSMDIR)\lsm_mem.c $(LSMHDR) $(SQLITE3H)
+       $(LTCOMPILE) $(LSMOPTS) -c $(LSMDIR)\lsm_mem.c
+
+lsm_mutex.lo:  $(LSMDIR)\lsm_mutex.c $(LSMHDR) $(SQLITE3H)
+       $(LTCOMPILE) $(LSMOPTS) -c $(LSMDIR)\lsm_mutex.c
+
+lsm_shared.lo: $(LSMDIR)\lsm_shared.c $(LSMHDR) $(SQLITE3H)
+       $(LTCOMPILE) $(LSMOPTS) -c $(LSMDIR)\lsm_shared.c
+
+lsm_sorted.lo: $(LSMDIR)\lsm_sorted.c $(LSMHDR) $(SQLITE3H)
+       $(LTCOMPILE) $(LSMOPTS) -c $(LSMDIR)\lsm_sorted.c
+
+lsm_str.lo:    $(LSMDIR)\lsm_str.c $(LSMHDR) $(SQLITE3H)
+       $(LTCOMPILE) $(LSMOPTS) -c $(LSMDIR)\lsm_str.c
+
+lsm_tree.lo:   $(LSMDIR)\lsm_tree.c $(LSMHDR) $(SQLITE3H)
+       $(LTCOMPILE) $(LSMOPTS) -c $(LSMDIR)\lsm_tree.c
+
+lsm_unix.lo:   $(LSMDIR)\lsm_unix.c $(LSMHDR) $(SQLITE3H)
+       $(LTCOMPILE) $(LSMOPTS) -c $(LSMDIR)\lsm_unix.c
+
+lsm_win32.lo:  $(LSMDIR)\lsm_win32.c $(LSMHDR) $(SQLITE3H)
+       $(LTCOMPILE) $(LSMOPTS) -c $(LSMDIR)\lsm_win32.c
+
+lsm_varint.lo: $(LSMDIR)\lsm_varint.c $(LSMHDR) $(SQLITE3H)
+       $(LTCOMPILE) $(LSMOPTS) -c $(LSMDIR)\lsm_varint.c
+
+lsm_vtab.lo:   $(LSMDIR)\lsm_vtab.c $(LSMHDR) $(SQLITE3H)
+       $(LTCOMPILE) $(LSMOPTS) -c $(LSMDIR)\lsm_vtab.c
+
+lsm.dll:       $(LSMOBJ)
+       $(LD) $(LDFLAGS) $(LTLINKOPTS) $(LTLIBPATHS) /VERBOSE /DLL /OUT:$@ $(LSMOBJ)
+
+lsmtest.exe: $(LSMOBJ) $(LSMTESTSRC) $(LSMTESTHDR) $(LIBOBJS1)
+       # $(LTCOMPILE) -c $(TOP)\lsm-test\lsmtest_tdb2.cc
+       $(LTCOMPILE) $(LSMOPTS) $(LSMTESTSRC) $(LSMOBJ) $(LIBOBJS1) -Fe$@
index ea44dd40fcebd22e77cb90aa41b6e65955f80cc9..01560bd057bb716759991340213d25f5b149caa9 100644 (file)
 #include <stdio.h>
 #include <ctype.h>
 
-#include <unistd.h>
+#ifdef _WIN32
+# define snprintf _snprintf
+#else
+# include <unistd.h>
+#endif
 
 #ifdef NDEBUG
 # ifdef LSM_DEBUG_EXPENSIVE
index 474981bd3ec56ae21ad215619ec59e68ccf5b363..14f340fe2c3bf347b23531c99e270439a1c9eff0 100644 (file)
@@ -2085,12 +2085,12 @@ int lsmFsSortedAppend(
 ){
   int rc = LSM_OK;
   Page *pPg = 0;
-  *ppOut = 0;
   int iApp = 0;
   int iNext = 0;
   Segment *p = &pLvl->lhs;
   int iPrev = p->iLastPg;
 
+  *ppOut = 0;
   assert( p->pRedirect==0 );
 
   if( pFS->pCompress || bDefer ){
index 86762a78119d144b7e569a174d83a8a4fffc77bf..3e5acccdaa3f23fa0a0bde5e2e537d137dc4c1ee 100644 (file)
@@ -13,7 +13,7 @@
 ** Unix-specific run-time environment implementation for LSM.
 */
 
-#ifndef WIN32
+#ifndef _WIN32
 
 #if defined(__GNUC__) || defined(__TINYC__)
 /* workaround for ftruncate() visibility on gcc. */
index 73e5bcb5ba980f06d9bfbf55a5da56bef5ea6356..8c047bcbcb6e67cf9486fa926bc011c93026f7fc 100644 (file)
 **
 *************************************************************************
 **
-** Unix-specific run-time environment implementation for LSM.
+** Win32-specific run-time environment implementation for LSM.
 */
 
-#ifdef WIN32
+#ifdef _WIN32
 
-#if defined(__GNUC__) || defined(__TINYC__)
-/* workaround for ftruncate() visibility on gcc. */
-# ifndef _XOPEN_SOURCE
-#  define _XOPEN_SOURCE 500
-# endif
-#endif
-
-#include <unistd.h>
-#include <sys/types.h>
-
-#include <sys/stat.h>
-#include <fcntl.h>
 #include <assert.h>
 #include <string.h>
 
@@ -35,8 +23,7 @@
 #include <stdio.h>
 #include <ctype.h>
 
-#include <unistd.h>
-#include <errno.h>
+#include "windows.h"
 
 #include "lsmInt.h"
 
@@ -48,19 +35,22 @@ struct Win32File {
   lsm_env *pEnv;                  /* The run-time environment */
   const char *zName;              /* Full path to file */
 
-  HANDLE h;                       /* Open file descriptor */
-  HANDLE shmh;                    /* File descriptor for *-shm file */
+  HANDLE hFile;                   /* Open file handle */
+  HANDLE hShmFile;                /* File handle for *-shm file */
 
+  HANDLE hMap;                    /* File handle for mapping */
   void *pMap;                     /* Pointer to mapping of file fd */
-  off_t nMap;                     /* Size of mapping at pMap in bytes */
+  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 lsmWin32OsSleep(lsm_env *pEnv, int us);
+
 static char *win32ShmFile(Win32File *p){
   char *zShm;
   int nName = strlen(p->zName);
-  zShm = (char *)lsmMalloc(p->pEnv, nName+4+1);
+  zShm = (char *)lsmMallocZero(p->pEnv, nName+4+1);
   if( zShm ){
     memcpy(zShm, p->zName, nName);
     memcpy(&zShm[nName], "-shm", 5);
@@ -68,6 +58,107 @@ static char *win32ShmFile(Win32File *p){
   return zShm;
 }
 
+/*
+** The number of times that an I/O operation will be retried following a
+** locking error - probably caused by antivirus software.  Also the initial
+** delay before the first retry.  The delay increases linearly with each
+** retry.
+*/
+#ifndef LSM_WIN32_IOERR_RETRY
+# define LSM_WIN32_IOERR_RETRY 10
+#endif
+#ifndef LSM_WIN32_IOERR_RETRY_DELAY
+# define LSM_WIN32_IOERR_RETRY_DELAY 25000
+#endif
+static int win32IoerrRetry = LSM_WIN32_IOERR_RETRY;
+static int win32IoerrRetryDelay = LSM_WIN32_IOERR_RETRY_DELAY;
+
+/*
+** The "win32IoerrCanRetry1" macro is used to determine if a particular
+** I/O error code obtained via GetLastError() is eligible to be retried.
+** It must accept the error code DWORD as its only argument and should
+** return non-zero if the error code is transient in nature and the
+** operation responsible for generating the original error might succeed
+** upon being retried.  The argument to this macro should be a variable.
+**
+** Additionally, a macro named "win32IoerrCanRetry2" may be defined.  If
+** it is defined, it will be consulted only when the macro
+** "win32IoerrCanRetry1" returns zero.  The "win32IoerrCanRetry2" macro
+** is completely optional and may be used to include additional error
+** codes in the set that should result in the failing I/O operation being
+** retried by the caller.  If defined, the "win32IoerrCanRetry2" macro
+** must exhibit external semantics identical to those of the
+** "win32IoerrCanRetry1" macro.
+*/
+#if !defined(win32IoerrCanRetry1)
+#define win32IoerrCanRetry1(a) (((a)==ERROR_ACCESS_DENIED)        || \
+                                ((a)==ERROR_SHARING_VIOLATION)    || \
+                                ((a)==ERROR_LOCK_VIOLATION)       || \
+                                ((a)==ERROR_DEV_NOT_EXIST)        || \
+                                ((a)==ERROR_NETNAME_DELETED)      || \
+                                ((a)==ERROR_SEM_TIMEOUT)          || \
+                                ((a)==ERROR_NETWORK_UNREACHABLE))
+#endif
+
+/*
+** If an I/O error occurs, invoke this routine to see if it should be
+** retried.  Return TRUE to retry.  Return FALSE to give up with an
+** error.
+*/
+static int win32RetryIoerr(
+  lsm_env *pEnv,
+  int *pnRetry
+){
+  DWORD lastErrno;
+  if( *pnRetry>=win32IoerrRetry ){
+    return 0;
+  }
+  lastErrno = GetLastError();
+  if( win32IoerrCanRetry1(lastErrno) ){
+    lsmWin32OsSleep(pEnv, win32IoerrRetryDelay*(1+*pnRetry));
+    ++*pnRetry;
+    return 1;
+  }
+#if defined(win32IoerrCanRetry2)
+  else if( win32IoerrCanRetry2(lastErrno) ){
+    lsmWin32OsSleep(pEnv, win32IoerrRetryDelay*(1+*pnRetry));
+    ++*pnRetry;
+    return 1;
+  }
+#endif
+  return 0;
+}
+
+/*
+** Convert a UTF-8 string to Microsoft Unicode.
+**
+** Space to hold the returned string is obtained from lsmMalloc().
+*/
+static LPWSTR win32Utf8ToUnicode(lsm_env *pEnv, const char *zText){
+  int nChar;
+  LPWSTR zWideText;
+
+  nChar = MultiByteToWideChar(CP_UTF8, 0, zText, -1, NULL, 0);
+  if( nChar==0 ){
+    return 0;
+  }
+  zWideText = lsmMallocZero(pEnv, nChar * sizeof(WCHAR));
+  if( zWideText==0 ){
+    return 0;
+  }
+  nChar = MultiByteToWideChar(CP_UTF8, 0, zText, -1, zWideText, nChar);
+  if( nChar==0 ){
+    lsmFree(pEnv, zWideText);
+    zWideText = 0;
+  }
+  return zWideText;
+}
+
+#if !defined(win32IsNotFound)
+#define win32IsNotFound(a) (((a)==ERROR_FILE_NOT_FOUND)  || \
+                            ((a)==ERROR_PATH_NOT_FOUND))
+#endif
+
 static int lsmWin32OsOpen(
   lsm_env *pEnv,
   const char *zFile,
@@ -75,122 +166,155 @@ static int lsmWin32OsOpen(
   lsm_file **ppFile
 ){
   int rc = LSM_OK;
-  Win32File *p;
+  Win32File *pWin32File;
 
-  p = lsm_malloc(pEnv, sizeof(Win32File));
-  if( p==0 ){
-    rc = LSM_NOMEM;
+  pWin32File = lsmMallocZero(pEnv, sizeof(Win32File));
+  if( pWin32File==0 ){
+    rc = LSM_NOMEM_BKPT;
   }else{
+    LPCWSTR zConverted;
     int bReadonly = (flags & LSM_OPEN_READONLY);
-    int oflags = (bReadonly ? O_RDONLY : (O_RDWR|O_CREAT));
-    memset(p, 0, sizeof(Win32File));
-    p->zName = zFile;
-    p->pEnv = pEnv;
-
-    CreateFile((LPCWSTR)zConverted,
-                              dwDesiredAccess,
-                              dwShareMode, NULL,
-                              dwCreationDisposition,
-                              dwFlagsAndAttributes,
-                              NULL))==INVALID_HANDLE_VALUE &&
-                              winRetryIoerr(&cnt, &lastErrno) ){
-
-
-    p->fd = open(zFile, oflags, 0644);
-    if( p->fd<0 ){
-      lsm_free(pEnv, p);
-      p = 0;
-      if( errno==ENOENT ){
-        rc = lsmErrorBkpt(LSM_IOERR_NOENT);
+    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 ){
+      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 */
+      }
+      if( hFile!=INVALID_HANDLE_VALUE ){
+        pWin32File->pEnv = pEnv;
+        pWin32File->zName = zFile;
+        pWin32File->hFile = hFile;
       }else{
-        rc = LSM_IOERR_BKPT;
+        lsmFree(pEnv, pWin32File);
+        pWin32File = 0;
+        if( win32IsNotFound(GetLastError()) ){
+          rc = lsmErrorBkpt(LSM_IOERR_NOENT);
+        }else{
+          rc = LSM_IOERR_BKPT;
+        }
       }
     }
   }
-
-  *ppFile = (lsm_file *)p;
+  *ppFile = (lsm_file *)pWin32File;
   return rc;
 }
 
 static int lsmWin32OsWrite(
-  lsm_file *pFile,                /* File to write to */
-  lsm_i64 iOff,                   /* Offset to write to */
-  void *pData,                    /* Write data from this buffer */
-  int nData                       /* Bytes of data to write */
+  lsm_file *pFile, /* File to write to */
+  lsm_i64 iOff,    /* Offset to write to */
+  void *pData,     /* Write data from this buffer */
+  int nData        /* Bytes of data to write */
 ){
-  int rc = LSM_OK;
-  Win32File *p = (Win32File *)pFile;
-  off_t offset;
-
-  offset = lseek(p->fd, (off_t)iOff, SEEK_SET);
-  if( offset!=iOff ){
-    rc = LSM_IOERR_BKPT;
-  }else{
-    ssize_t prc = write(p->fd, pData, (size_t)nData);
-    if( prc<0 ) rc = LSM_IOERR_BKPT;
+  Win32File *pWin32File = (Win32File *)pFile;
+  OVERLAPPED overlapped;  /* The offset for WriteFile. */
+  u8 *aRem = (u8 *)pData; /* Data yet to be written */
+  int nRem = nData;       /* Number of bytes yet to be written */
+  int nRetry = 0;         /* Number of retrys */
+
+  memset(&overlapped, 0, sizeof(OVERLAPPED));
+  overlapped.Offset = (LONG)(iOff & 0xffffffff);
+  overlapped.OffsetHigh = (LONG)((iOff>>32) & 0x7fffffff);
+  while( nRem>0 ){
+    DWORD nWrite = 0; /* Bytes written using WriteFile */
+    if( !WriteFile(pWin32File->hFile, aRem, nRem, &nWrite, &overlapped) ){
+      if( win32RetryIoerr(pWin32File->pEnv, &nRetry) ) continue;
+      break;
+    }
+    assert( nWrite==0 || nWrite<=(DWORD)nRem );
+    if( nWrite==0 || nWrite>(DWORD)nRem ){
+      break;
+    }
+    iOff += nWrite;
+    overlapped.Offset = (LONG)(iOff & 0xffffffff);
+    overlapped.OffsetHigh = (LONG)((iOff>>32) & 0x7fffffff);
+    aRem += nWrite;
+    nRem -= nWrite;
   }
-
-  return rc;
+  if( nRem!=0 ) 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 */
+  lsm_file *pFile, /* File to write to */
+  lsm_i64 nSize    /* Size to truncate file to */
 ){
-  Win32File *p = (Win32File *)pFile;
-  int rc = LSM_OK;                /* Return code */
-  int prc;                        /* Posix Return Code */
-  struct stat sStat;              /* Result of fstat() invocation */
-  
-  prc = fstat(p->fd, &sStat);
-  if( prc==0 && sStat.st_size>nSize ){
-    prc = ftruncate(p->fd, (off_t)nSize);
-  }
-  if( prc<0 ) rc = LSM_IOERR_BKPT;
+  Win32File *pWin32File = (Win32File *)pFile;
+  LARGE_INTEGER largeInteger; /* The new offset */
 
-  return rc;
+  largeInteger.QuadPart = nSize;
+  if( !SetFilePointerEx(pWin32File->hFile, largeInteger, 0, FILE_BEGIN) ){
+    return LSM_IOERR_BKPT;
+  }
+  if (!SetEndOfFile(pWin32File->hFile) ){
+    return LSM_IOERR_BKPT;
+  }
+  return LSM_OK;
 }
 
 static int lsmWin32OsRead(
-  lsm_file *pFile,                /* File to read from */
-  lsm_i64 iOff,                   /* Offset to read from */
-  void *pData,                    /* Read data into this buffer */
-  int nData                       /* Bytes of data to read */
+  lsm_file *pFile, /* File to read from */
+  lsm_i64 iOff,    /* Offset to read from */
+  void *pData,     /* Read data into this buffer */
+  int nData        /* Bytes of data to read */
 ){
-  int rc = LSM_OK;
-  Win32File *p = (Win32File *)pFile;
-  off_t offset;
-
-  offset = lseek(p->fd, (off_t)iOff, SEEK_SET);
-  if( offset!=iOff ){
-    rc = LSM_IOERR_BKPT;
-  }else{
-    ssize_t prc = read(p->fd, pData, (size_t)nData);
-    if( prc<0 ){ 
-      rc = LSM_IOERR_BKPT;
-    }else if( prc<nData ){
-      memset(&((u8 *)pData)[prc], 0, nData - prc);
-    }
-
+  Win32File *pWin32File = (Win32File *)pFile;
+  OVERLAPPED overlapped; /* The offset for ReadFile */
+  DWORD nRead = 0;       /* Bytes read using ReadFile */
+  int nRetry = 0;        /* Number of retrys */
+
+  memset(&overlapped, 0, sizeof(OVERLAPPED));
+  overlapped.Offset = (LONG)(iOff & 0xffffffff);
+  overlapped.OffsetHigh = (LONG)((iOff>>32) & 0x7fffffff);
+  while( !ReadFile(pWin32File->hFile, pData, nData, &nRead, &overlapped) &&
+         GetLastError()!=ERROR_HANDLE_EOF ){
+    if( win32RetryIoerr(pWin32File->pEnv, &nRetry) ) continue;
+    return LSM_IOERR_BKPT;
   }
-
-  return rc;
+  if( nRead<(DWORD)nData ){
+    /* Unread parts of the buffer must be zero-filled */
+    memset(&((char*)pData)[nRead], 0, nData - nRead);
+  }
+  return LSM_OK;
 }
 
 static int lsmWin32OsSync(lsm_file *pFile){
   int rc = LSM_OK;
 
 #ifndef LSM_NO_SYNC
-  Win32File *p = (Win32File *)pFile;
-  int prc = 0;
+  Win32File *pWin32File = (Win32File *)pFile;
 
-  if( p->pMap ){
-    prc = msync(p->pMap, p->nMap, MS_SYNC);
+  if( pWin32File->pMap ){
+    if( !FlushViewOfFile(pWin32File->pMap, 0) ){
+      rc = LSM_IOERR_BKPT;
+    }
+  }
+  if( rc==LSM_OK && !FlushFileBuffers(pWin32File->hFile) ){
+    rc = LSM_IOERR_BKPT;
   }
-  if( prc==0 ) prc = fdatasync(p->fd);
-  if( prc<0 ) rc = LSM_IOERR_BKPT;
 #else
-  (void)pFile;
 #endif
 
   return rc;
@@ -201,45 +325,12 @@ static int lsmWin32OsSectorSize(lsm_file *pFile){
 }
 
 static int lsmWin32OsRemap(
-  lsm_file *pFile, 
-  lsm_i64 iMin, 
+  lsm_file *pFile,
+  lsm_i64 iMin,
   void **ppOut,
   lsm_i64 *pnOut
 ){
-  off_t iSz;
-  int prc;
-  Win32File *p = (Win32File *)pFile;
-  struct stat buf;
-
-  /* If the file is between 0 and 2MB in size, extend it in chunks of 256K.
-  ** Thereafter, in chunks of 1MB at a time.  */
-  const int aIncrSz[] = {256*1024, 1024*1024};
-  int nIncrSz = aIncrSz[iMin>(2*1024*1024)];
-
-  if( p->pMap ){
-    munmap(p->pMap, p->nMap);
-    *ppOut = p->pMap = 0;
-    *pnOut = p->nMap = 0;
-  }
-
-  if( iMin>=0 ){
-    memset(&buf, 0, sizeof(buf));
-    prc = fstat(p->fd, &buf);
-    if( prc!=0 ) return LSM_IOERR_BKPT;
-    iSz = buf.st_size;
-    if( iSz<iMin ){
-      iSz = ((iMin + nIncrSz-1) / nIncrSz) * nIncrSz;
-      prc = ftruncate(p->fd, iSz);
-      if( prc!=0 ) return LSM_IOERR_BKPT;
-    }
-
-    p->pMap = mmap(0, iSz, PROT_READ|PROT_WRITE, MAP_SHARED, p->fd, 0);
-    p->nMap = iSz;
-  }
-
-  *ppOut = p->pMap;
-  *pnOut = p->nMap;
-  return LSM_OK;
+  return LSM_ERROR;
 }
 
 static int lsmWin32OsFullpath(
@@ -248,298 +339,163 @@ static int lsmWin32OsFullpath(
   char *zOut,
   int *pnOut
 ){
-  int nBuf = *pnOut;
-  int nReq;
-
-  if( zName[0]!='/' ){
-    char *z;
-    char *zTmp;
-    int nTmp = 512;
-    zTmp = lsmMalloc(pEnv, nTmp);
-    while( zTmp ){
-      z = getcwd(zTmp, nTmp);
-      if( z || errno!=ERANGE ) break;
-      nTmp = nTmp*2;
-      zTmp = lsmReallocOrFree(pEnv, zTmp, nTmp);
-    }
-    if( zTmp==0 ) return LSM_NOMEM_BKPT;
-    if( z==0 ) return LSM_IOERR_BKPT;
-    assert( z==zTmp );
-
-    nTmp = strlen(zTmp);
-    nReq = nTmp + 1 + strlen(zName) + 1;
-    if( nReq<=nBuf ){
-      memcpy(zOut, zTmp, nTmp);
-      zOut[nTmp] = '/';
-      memcpy(&zOut[nTmp+1], zName, strlen(zName)+1);
-    }
-    lsmFree(pEnv, zTmp);
-  }else{
-    nReq = strlen(zName)+1;
-    if( nReq<=nBuf ){
-      memcpy(zOut, zName, strlen(zName)+1);
-    }
-  }
-
-  *pnOut = nReq;
-  return LSM_OK;
+  return LSM_ERROR;
 }
 
 static int lsmWin32OsFileid(
-  lsm_file *pFile, 
+  lsm_file *pFile,
   void *pBuf,
   int *pnBuf
 ){
-  int prc;
   int nBuf;
   int nReq;
-  Win32File *p = (Win32File *)pFile;
-  struct stat buf;
+  u8 *pBuf2 = (u8 *)pBuf;
+  Win32File *pWin32File = (Win32File *)pFile;
+  BY_HANDLE_FILE_INFORMATION fileInfo;
 
   nBuf = *pnBuf;
-  nReq = (sizeof(buf.st_dev) + sizeof(buf.st_ino));
+  nReq = (sizeof(fileInfo.dwVolumeSerialNumber) +
+          sizeof(fileInfo.nFileIndexHigh) +
+          sizeof(fileInfo.nFileIndexLow));
   *pnBuf = nReq;
   if( nReq>nBuf ) return LSM_OK;
-
-  memset(&buf, 0, sizeof(buf));
-  prc = fstat(p->fd, &buf);
-  if( prc!=0 ) return LSM_IOERR_BKPT;
-
-  memcpy(pBuf, &buf.st_dev, sizeof(buf.st_dev));
-  memcpy(&(((u8 *)pBuf)[sizeof(buf.st_dev)]), &buf.st_ino, sizeof(buf.st_ino));
+  memset(&fileInfo, 0, sizeof(BY_HANDLE_FILE_INFORMATION));
+  if( !GetFileInformationByHandle(pWin32File->hFile, &fileInfo) ){
+    return LSM_IOERR_BKPT;
+  }
+  nReq = sizeof(fileInfo.dwVolumeSerialNumber);
+  memcpy(pBuf2, &fileInfo.dwVolumeSerialNumber, nReq);
+  pBuf2 += nReq;
+  nReq = sizeof(fileInfo.nFileIndexHigh);
+  memcpy(pBuf, &fileInfo.nFileIndexHigh, nReq);
+  pBuf2 += nReq;
+  nReq = sizeof(fileInfo.nFileIndexLow);
+  memcpy(pBuf2, &fileInfo.nFileIndexLow, nReq);
   return LSM_OK;
 }
 
 static int lsmWin32OsUnlink(lsm_env *pEnv, const char *zFile){
-  int prc = unlink(zFile);
-  return prc ? LSM_IOERR_BKPT : LSM_OK;
+  return LSM_ERROR;
 }
 
 int lsmWin32OsLock(lsm_file *pFile, int iLock, int eType){
-  int rc = LSM_OK;
-  Win32File *p = (Win32File *)pFile;
-  static const short aType[3] = { F_UNLCK, F_RDLCK, F_WRLCK };
-  struct flock lock;
-
-  assert( aType[LSM_LOCK_UNLOCK]==F_UNLCK );
-  assert( aType[LSM_LOCK_SHARED]==F_RDLCK );
-  assert( aType[LSM_LOCK_EXCL]==F_WRLCK );
-  assert( eType>=0 && eType<array_size(aType) );
-  assert( iLock>0 && iLock<=32 );
-
-  memset(&lock, 0, sizeof(lock));
-  lock.l_whence = SEEK_SET;
-  lock.l_len = 1;
-  lock.l_type = aType[eType];
-  lock.l_start = (4096-iLock);
-
-  if( fcntl(p->fd, F_SETLK, &lock) ){
-    int e = errno;
-    if( e==EACCES || e==EAGAIN ){
-      rc = LSM_BUSY;
-    }else{
-      rc = LSM_IOERR_BKPT;
-    }
-  }
-
-  return rc;
+  return LSM_ERROR;
 }
 
 int lsmWin32OsTestLock(lsm_file *pFile, int iLock, int nLock, int eType){
-  int rc = LSM_OK;
-  Win32File *p = (Win32File *)pFile;
-  static const short aType[3] = { 0, F_RDLCK, F_WRLCK };
-  struct flock lock;
-
-  assert( eType==LSM_LOCK_SHARED || eType==LSM_LOCK_EXCL );
-  assert( aType[LSM_LOCK_SHARED]==F_RDLCK );
-  assert( aType[LSM_LOCK_EXCL]==F_WRLCK );
-  assert( eType>=0 && eType<array_size(aType) );
-  assert( iLock>0 && iLock<=32 );
-
-  memset(&lock, 0, sizeof(lock));
-  lock.l_whence = SEEK_SET;
-  lock.l_len = nLock;
-  lock.l_type = aType[eType];
-  lock.l_start = (4096-iLock);
-
-  if( fcntl(p->fd, F_GETLK, &lock) ){
-    rc = LSM_IOERR_BKPT;
-  }else if( lock.l_type!=F_UNLCK ){
-    rc = LSM_BUSY;
-  }
-
-  return rc;
+  return LSM_ERROR;
 }
 
 int lsmWin32OsShmMap(lsm_file *pFile, int iChunk, int sz, void **ppShm){
-  Win32File *p = (Win32File *)pFile;
-
-  *ppShm = 0;
-  assert( sz==LSM_SHM_CHUNK_SIZE );
-  if( iChunk>=p->nShm ){
-    int i;
-    void **apNew;
-    int nNew = iChunk+1;
-    off_t nReq = nNew * LSM_SHM_CHUNK_SIZE;
-    struct stat sStat;
-
-    /* If the shared-memory file has not been opened, open it now. */
-    if( p->shmfd<=0 ){
-      char *zShm = win32ShmFile(p);
-      if( !zShm ) return LSM_NOMEM_BKPT;
-      p->shmfd = open(zShm, O_RDWR|O_CREAT, 0644);
-      lsmFree(p->pEnv, zShm);
-      if( p->shmfd<0 ){ 
-        return LSM_IOERR_BKPT;
-      }
-    }
-
-    /* If the shared-memory file is not large enough to contain the 
-    ** requested chunk, cause it to grow.  */
-    if( fstat(p->shmfd, &sStat) ){
-      return LSM_IOERR_BKPT;
-    }
-    if( sStat.st_size<nReq ){
-      if( ftruncate(p->shmfd, nReq) ){
-        return LSM_IOERR_BKPT;
-      }
-    }
-
-    apNew = (void **)lsmRealloc(p->pEnv, p->apShm, sizeof(void *) * nNew);
-    if( !apNew ) return LSM_NOMEM_BKPT;
-    for(i=p->nShm; i<nNew; i++){
-      apNew[i] = 0;
-    }
-    p->apShm = apNew;
-    p->nShm = nNew;
-  }
-
-  if( p->apShm[iChunk]==0 ){
-    p->apShm[iChunk] = mmap(0, LSM_SHM_CHUNK_SIZE, 
-        PROT_READ|PROT_WRITE, MAP_SHARED, p->shmfd, iChunk*LSM_SHM_CHUNK_SIZE
-    );
-    if( p->apShm[iChunk]==0 ) return LSM_IOERR_BKPT;
-  }
-
-  *ppShm = p->apShm[iChunk];
-  return LSM_OK;
+  return LSM_ERROR;
 }
 
 void lsmWin32OsShmBarrier(void){
+  MemoryBarrier();
 }
 
 int lsmWin32OsShmUnmap(lsm_file *pFile, int bDelete){
-  Win32File *p = (Win32File *)pFile;
-  if( p->shmfd>0 ){
-    int i;
-    for(i=0; i<p->nShm; i++){
-      if( p->apShm[i] ){
-        munmap(p->apShm[i], LSM_SHM_CHUNK_SIZE);
-        p->apShm[i] = 0;
-      }
-    }
-    close(p->shmfd);
-    p->shmfd = 0;
-    if( bDelete ){
-      char *zShm = win32ShmFile(p);
-      if( zShm ) unlink(zShm);
-      lsmFree(p->pEnv, zShm);
-    }
-  }
-  return LSM_OK;
+  return LSM_ERROR;
 }
 
-
+#define MX_CLOSE_ATTEMPT 3
 static int lsmWin32OsClose(lsm_file *pFile){
-  Win32File *p = (Win32File *)pFile;
+  int rc;
+  int nRetry = 0;
+  Win32File *pWin32File = (Win32File *)pFile;
   lsmWin32OsShmUnmap(pFile, 0);
-  if( p->pMap ) munmap(p->pMap, p->nMap);
-  close(p->fd);
-  lsm_free(p->pEnv, p->apShm);
-  lsm_free(p->pEnv, p);
-  return LSM_OK;
+  if( pWin32File->pMap ){
+    UnmapViewOfFile(pWin32File->pMap);
+    pWin32File->pMap = 0;
+  }
+  if( pWin32File->hMap!=NULL ){
+    CloseHandle(pWin32File->hMap);
+    pWin32File->hMap = NULL;
+  }
+  do{
+    rc = CloseHandle(pWin32File->hFile);
+    if( rc ){
+      rc = LSM_OK;
+      break;
+    }
+    if( ++nRetry>=MX_CLOSE_ATTEMPT ){
+      rc = LSM_IOERR_BKPT;
+      break;
+    }
+  }while( 1 );
+  lsmFree(pWin32File->pEnv, pWin32File->apShm);
+  lsmFree(pWin32File->pEnv, pWin32File);
+  return rc;
 }
 
 static int lsmWin32OsSleep(lsm_env *pEnv, int us){
-  usleep(us);
+  unused_parameter(pEnv);
+  Sleep((us + 999) / 1000);
   return LSM_OK;
 }
 
 /****************************************************************************
 ** Memory allocation routines.
 */
-#define BLOCK_HDR_SIZE ROUND8( sizeof(size_t) )
 
 static void *lsmWin32OsMalloc(lsm_env *pEnv, size_t N){
-  unsigned char * m;
-  N += BLOCK_HDR_SIZE;
-  m = (unsigned char *)malloc(N);
-  *((size_t*)m) = N;
-  return m + BLOCK_HDR_SIZE;
+  return HeapAlloc(GetProcessHeap(), 0, (SIZE_T)N);
 }
 
 static void lsmWin32OsFree(lsm_env *pEnv, void *p){
-  if(p){
-    free( ((unsigned char *)p) - BLOCK_HDR_SIZE );
+  if( p ){
+    HeapFree(GetProcessHeap(), 0, p);
   }
 }
 
 static void *lsmWin32OsRealloc(lsm_env *pEnv, void *p, size_t N){
-  unsigned char * m = (unsigned char *)p;
-  if(1>N){
-    lsmWin32OsFree( pEnv, p );
+  unsigned char *m = (unsigned char *)p;
+  if( 1>N ){
+    lsmWin32OsFree(pEnv, p);
     return NULL;
-  }else if(NULL==p){
+  }else if( NULL==p ){
     return lsmWin32OsMalloc(pEnv, N);
   }else{
-    void * re = NULL;
-    m -= BLOCK_HDR_SIZE;
 #if 0 /* arguable: don't shrink */
-    size_t * sz = (size_t*)m;
-    if(*sz >= (size_t)N){
+    SIZE_T sz = HeapSize(GetProcessHeap(), 0, m);
+    if( sz>=(SIZE_T)N ){
       return p;
     }
 #endif
-    re = realloc( m, N + BLOCK_HDR_SIZE );
-    if(re){
-      m = (unsigned char *)re;
-      *((size_t*)m) = N;
-      return m + BLOCK_HDR_SIZE;
-    }else{
-      return NULL;
-    }
+    return HeapReAlloc(GetProcessHeap(), 0, m, N);
   }
 }
 
 static size_t lsmWin32OsMSize(lsm_env *pEnv, void *p){
-  unsigned char * m = (unsigned char *)p;
-  return *((size_t*)(m-BLOCK_HDR_SIZE));
+  return (size_t)HeapSize(GetProcessHeap(), 0, p);
 }
-#undef BLOCK_HDR_SIZE
 
 
-#ifdef LSM_MUTEX_WIN32 
+#ifdef LSM_MUTEX_WIN32
 /*************************************************************************
-** Mutex methods for pthreads based systems.  If LSM_MUTEX_WIN32 is
-** missing then a no-op implementation of mutexes found below will be 
+** Mutex methods for Win32 based systems.  If LSM_MUTEX_WIN32 is
+** missing then a no-op implementation of mutexes found below will be
 ** used instead.
 */
-#include <pthread.h>
+#include "windows.h"
 
-typedef struct PthreadMutex PthreadMutex;
-struct PthreadMutex {
+typedef struct Win32Mutex Win32Mutex;
+struct Win32Mutex {
   lsm_env *pEnv;
-  pthread_mutex_t mutex;
+  CRITICAL_SECTION mutex;
 #ifdef LSM_DEBUG
-  pthread_t owner;
+  DWORD owner;
 #endif
 };
 
+#ifndef WIN32_MUTEX_INITIALIZER
+# define WIN32_MUTEX_INITIALIZER { 0 }
+#endif
+
 #ifdef LSM_DEBUG
-# define LSM_PTHREAD_STATIC_MUTEX { 0, PTHREAD_MUTEX_INITIALIZER, 0 }
+# define LSM_WIN32_STATIC_MUTEX { 0, WIN32_MUTEX_INITIALIZER, 0 }
 #else
-# define LSM_PTHREAD_STATIC_MUTEX { 0, PTHREAD_MUTEX_INITIALIZER }
+# define LSM_WIN32_STATIC_MUTEX { 0, WIN32_MUTEX_INITIALIZER }
 #endif
 
 static int lsmWin32OsMutexStatic(
@@ -547,84 +503,87 @@ static int lsmWin32OsMutexStatic(
   int iMutex,
   lsm_mutex **ppStatic
 ){
-  static PthreadMutex sMutex[2] = {
-    LSM_PTHREAD_STATIC_MUTEX,
-    LSM_PTHREAD_STATIC_MUTEX
+  static volatile LONG initialized = 0;
+  static Win32Mutex sMutex[2] = {
+    LSM_WIN32_STATIC_MUTEX,
+    LSM_WIN32_STATIC_MUTEX
   };
 
   assert( iMutex==LSM_MUTEX_GLOBAL || iMutex==LSM_MUTEX_HEAP );
   assert( LSM_MUTEX_GLOBAL==1 && LSM_MUTEX_HEAP==2 );
 
+  if( InterlockedCompareExchange(&initialized, 1, 0)==0 ){
+    int i;
+    for(i=0; i<array_size(sMutex); i++){
+      InitializeCriticalSection(&sMutex[i].mutex);
+    }
+  }
   *ppStatic = (lsm_mutex *)&sMutex[iMutex-1];
   return LSM_OK;
 }
 
 static int lsmWin32OsMutexNew(lsm_env *pEnv, lsm_mutex **ppNew){
-  PthreadMutex *pMutex;           /* Pointer to new mutex */
-  pthread_mutexattr_t attr;       /* Attributes object */
+  Win32Mutex *pMutex;           /* Pointer to new mutex */
 
-  pMutex = (PthreadMutex *)lsmMallocZero(pEnv, sizeof(PthreadMutex));
+  pMutex = (Win32Mutex *)lsmMallocZero(pEnv, sizeof(Win32Mutex));
   if( !pMutex ) return LSM_NOMEM_BKPT;
 
   pMutex->pEnv = pEnv;
-  pthread_mutexattr_init(&attr);
-  pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
-  pthread_mutex_init(&pMutex->mutex, &attr);
-  pthread_mutexattr_destroy(&attr);
+  InitializeCriticalSection(&pMutex->mutex);
 
   *ppNew = (lsm_mutex *)pMutex;
   return LSM_OK;
 }
 
 static void lsmWin32OsMutexDel(lsm_mutex *p){
-  PthreadMutex *pMutex = (PthreadMutex *)p;
-  pthread_mutex_destroy(&pMutex->mutex);
+  Win32Mutex *pMutex = (Win32Mutex *)p;
+  DeleteCriticalSection(&pMutex->mutex);
   lsmFree(pMutex->pEnv, pMutex);
 }
 
 static void lsmWin32OsMutexEnter(lsm_mutex *p){
-  PthreadMutex *pMutex = (PthreadMutex *)p;
-  pthread_mutex_lock(&pMutex->mutex);
+  Win32Mutex *pMutex = (Win32Mutex *)p;
+  EnterCriticalSection(&pMutex->mutex);
 
 #ifdef LSM_DEBUG
-  assert( !pthread_equal(pMutex->owner, pthread_self()) );
-  pMutex->owner = pthread_self();
-  assert( pthread_equal(pMutex->owner, pthread_self()) );
+  assert( pMutex->owner!=GetCurrentThreadId() );
+  pMutex->owner = GetCurrentThreadId();
+  assert( pMutex->owner==GetCurrentThreadId() );
 #endif
 }
 
 static int lsmWin32OsMutexTry(lsm_mutex *p){
-  int ret;
-  PthreadMutex *pMutex = (PthreadMutex *)p;
-  ret = pthread_mutex_trylock(&pMutex->mutex);
+  BOOL bRet;
+  Win32Mutex *pMutex = (Win32Mutex *)p;
+  bRet = TryEnterCriticalSection(&pMutex->mutex);
 #ifdef LSM_DEBUG
-  if( ret==0 ){
-    assert( !pthread_equal(pMutex->owner, pthread_self()) );
-    pMutex->owner = pthread_self();
-    assert( pthread_equal(pMutex->owner, pthread_self()) );
+  if( bRet ){
+    assert( pMutex->owner!=GetCurrentThreadId() );
+    pMutex->owner = GetCurrentThreadId();
+    assert( pMutex->owner==GetCurrentThreadId() );
   }
 #endif
-  return ret;
+  return !bRet;
 }
 
 static void lsmWin32OsMutexLeave(lsm_mutex *p){
-  PthreadMutex *pMutex = (PthreadMutex *)p;
+  Win32Mutex *pMutex = (Win32Mutex *)p;
 #ifdef LSM_DEBUG
-  assert( pthread_equal(pMutex->owner, pthread_self()) );
+  assert( pMutex->owner==GetCurrentThreadId() );
   pMutex->owner = 0;
-  assert( !pthread_equal(pMutex->owner, pthread_self()) );
+  assert( pMutex->owner!=GetCurrentThreadId() );
 #endif
-  pthread_mutex_unlock(&pMutex->mutex);
+  LeaveCriticalSection(&pMutex->mutex);
 }
 
 #ifdef LSM_DEBUG
 static int lsmWin32OsMutexHeld(lsm_mutex *p){
-  PthreadMutex *pMutex = (PthreadMutex *)p;
-  return pMutex ? pthread_equal(pMutex->owner, pthread_self()) : 1;
+  Win32Mutex *pMutex = (Win32Mutex *)p;
+  return pMutex ? pMutex->owner==GetCurrentThreadId() : 1;
 }
 static int lsmWin32OsMutexNotHeld(lsm_mutex *p){
-  PthreadMutex *pMutex = (PthreadMutex *)p;
-  return pMutex ? !pthread_equal(pMutex->owner, pthread_self()) : 1;
+  Win32Mutex *pMutex = (Win32Mutex *)p;
+  return pMutex ? pMutex->owner!=GetCurrentThreadId() : 1;
 }
 #endif
 /*
@@ -661,12 +620,12 @@ static int lsmWin32OsMutexNew(lsm_env *pEnv, lsm_mutex **ppNew){
   *ppNew = (lsm_mutex *)p;
   return (p ? LSM_OK : LSM_NOMEM_BKPT);
 }
-static void lsmWin32OsMutexDel(lsm_mutex *pMutex)  { 
+static void lsmWin32OsMutexDel(lsm_mutex *pMutex)  {
   NoopMutex *p = (NoopMutex *)pMutex;
   assert( p->bStatic==0 && p->pEnv );
   lsmFree(p->pEnv, p);
 }
-static void lsmWin32OsMutexEnter(lsm_mutex *pMutex){ 
+static void lsmWin32OsMutexEnter(lsm_mutex *pMutex){
   NoopMutex *p = (NoopMutex *)pMutex;
   assert( p->bHeld==0 );
   p->bHeld = 1;
@@ -677,17 +636,17 @@ static int lsmWin32OsMutexTry(lsm_mutex *pMutex){
   p->bHeld = 1;
   return 0;
 }
-static void lsmWin32OsMutexLeave(lsm_mutex *pMutex){ 
+static void lsmWin32OsMutexLeave(lsm_mutex *pMutex){
   NoopMutex *p = (NoopMutex *)pMutex;
   assert( p->bHeld==1 );
   p->bHeld = 0;
 }
 #ifdef LSM_DEBUG
-static int lsmWin32OsMutexHeld(lsm_mutex *pMutex){ 
+static int lsmWin32OsMutexHeld(lsm_mutex *pMutex){
   NoopMutex *p = (NoopMutex *)pMutex;
   return p ? p->bHeld : 1;
 }
-static int lsmWin32OsMutexNotHeld(lsm_mutex *pMutex){ 
+static int lsmWin32OsMutexNotHeld(lsm_mutex *pMutex){
   NoopMutex *p = (NoopMutex *)pMutex;
   return p ? !p->bHeld : 1;
 }
index 1b24eb7135607ad8898e9bd315827855c44b3b0a..fe3912acd647f819c48ece9d396aeb23485d4c02 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,8 +1,8 @@
-C Remove\san\sinvalid\sassert()\sfrom\slsm\stest\scode.
-D 2017-06-26T11:46:01.859
+C Work\sin\sprogress\sporting\slsm1\sto\sWin32.
+D 2017-06-27T05:59:47.975
 F Makefile.in 1cc758ce3374a32425e4d130c2fe7b026b20de5b8843243de75f087c0a2661fb
 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434
-F Makefile.msc 8eeb80162074004e906b53d7340a12a14c471a83743aab975947e95ce061efcc
+F Makefile.msc d389c6fb3344ea6887b386d56784a6d8a5c85107294448aeda50ac404285a1ef
 F README.md 2b15fae33852f2f53996774c21fb41e1d94181c4401a0e43ac93e11f2cc901b9
 F VERSION 87f1498f27e398bce3da2fa8125c9879a38ed9d87e4b5fb922b351de1e25cadb
 F aclocal.m4 a5c22d164aff7ed549d53a90fa56d56955281f50
@@ -209,6 +209,7 @@ F ext/icu/README.txt d9fbbad0c2f647c3fdf715fc9fd64af53aedfc43
 F ext/icu/icu.c 84900472a088a3a172c6c079f58a1d3a1952c332
 F ext/icu/sqliteicu.h 728867a802baa5a96de7495e9689a8e01715ef37
 F ext/lsm1/Makefile 5f60d0e1635ee51c438973f37a93f8e562229b446db59fc00af1621d39fdee26
+F ext/lsm1/Makefile.msc c9806a69a06dc3fcbbc82c21479b58e4b2d70d80f64518fe1a6c0f6585776bbb
 F ext/lsm1/lsm-test/README 87ea529d2abe615e856d4714bfe8bb185e6c2771b8612aa6298588b7b43e6f86
 F ext/lsm1/lsm-test/lsmtest.h e7057a3f9db71938496fc8ef081c9f45623b25bfd8499b3550d1ea7123143e90
 F ext/lsm1/lsm-test/lsmtest1.c 27c3cf6512514b25a145154ae4e54d053d883b2f7f52ed214747b5ebaceedd3e
@@ -233,9 +234,9 @@ F ext/lsm1/lsm-test/lsmtest_tdb3.c 6de609f6233026227d721e9265e62bf1834aed07d8795
 F ext/lsm1/lsm-test/lsmtest_tdb4.c 47e8bb5eba266472d690fb8264f1855ebdba0ae5a0e541e35fcda61ebf1d277f
 F ext/lsm1/lsm-test/lsmtest_util.c 0c2b7c1d109fbd6b7b9a2780f1315e2438a973d18afea5c4eccf94e8827c8260
 F ext/lsm1/lsm.h 0f6f64ff071471cb87bf98beb8386566f30ea001
-F ext/lsm1/lsmInt.h bc270dd81b3355c7410b06a6d54dd3eb9493a3e8
+F ext/lsm1/lsmInt.h de86f9dc7f2d90a3c94a5df820929c57d0b24399358ec274603028ed4cbe5b2b
 F ext/lsm1/lsm_ckpt.c e7907e782fe2e95de0833675e35e726e487cc4cd
-F ext/lsm1/lsm_file.c 6dcd83e040d0ea003875e7684ca2ef063b5cc8a5af99f464475dfeb51d13adbf
+F ext/lsm1/lsm_file.c 2f0232e2dc0262f60cab1b7010785fb961d566c740fc0370101c14ab085739e0
 F ext/lsm1/lsm_log.c 5b3e855fcfb85de9fb86fcbf65696cc6886d3231
 F ext/lsm1/lsm_main.c f52eada2910f8a57bd4cafcee39c6c375f6b7ed8
 F ext/lsm1/lsm_mem.c 4c51ea9fa285ee6e35301b33491642d071740a0a
@@ -244,10 +245,10 @@ F ext/lsm1/lsm_shared.c 54cc3a5157c6abd77f7d3ae60708b9f7bf022b3c
 F ext/lsm1/lsm_sorted.c 4a9e3ffecda87b379ed757b59c9cbcd84a80b55c
 F ext/lsm1/lsm_str.c 77ebdd5040ddf267a6f724d4c83132d2dce8a226
 F ext/lsm1/lsm_tree.c 5d9fb2bc58a1a70c75126bd8d7198f7b627e165b
-F ext/lsm1/lsm_unix.c ff6d0a89861c90193f21e35ea5dfea389b480e46085c1d7ff931833b77c3ff30
+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 de84068b4df2999a9cefcf67aae19b0733203f772ca58f7e0c2b0bc87136d2e3
+F ext/lsm1/lsm_win32.c 7da009125424b6e8b1dfac1d4cea9222f3e8510a6730b9ba80b7dd1ae5941e63
 F ext/misc/README.md 8e008c8d2b02e09096b31dfba033253ac27c6c06a18aa5826e299fa7601d90b2
 F ext/misc/amatch.c 6db4607cb17c54b853a2d7c7c36046d004853f65b9b733e6f019d543d5dfae87
 F ext/misc/anycollseq.c 5ffdfde9829eeac52219136ad6aa7cd9a4edb3b15f4f2532de52f4a22525eddb
@@ -1622,7 +1623,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 461ced77d93e84f09bfb4291999cd0245506fa9a8369049fd68968bbcf18d41b
-R 63e8a5819d5154609225118f393af4e2
-U dan
-Z 5b8d9ae5d3a8353b4cc4ac3639c99bf7
+P ca8a7e995c3da10ba05e3b7d4818c633fe5ba6d6f9351b67017a2603b50b903d
+R a7e826530d21c7f6dddff2b89dc79765
+U mistachkin
+Z 3a63fba7e138ec3099b3888a8dabf0af
index dcea3f37a7898fa27d2621bf9b3f6a0cf9b999fd..6dd37d5ed5495ed4b6d79463450bfae9088ea878 100644 (file)
@@ -1 +1 @@
-ca8a7e995c3da10ba05e3b7d4818c633fe5ba6d6f9351b67017a2603b50b903d
\ No newline at end of file
+2017636e93cf810fe4d1247c18de9f316fca037035a026f77c4588563d7bf0cc
\ No newline at end of file