/ Check-in [c54dc967]
Login

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

Overview
Comment:Enhancements to the Win32 native heap integration.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | win32heap
Files: files | file ages | folders
SHA1: c54dc9672b686c8e323eac0c33cd90ea89d36364
User & Date: mistachkin 2013-11-08 18:13:48
Context
2013-11-08
18:37
Minor corrections to logging for sqlite3_win32_compact_heap(). check-in: 71347d02 user: mistachkin tags: win32heap
18:13
Enhancements to the Win32 native heap integration. check-in: c54dc967 user: mistachkin tags: win32heap
17:13
Fix harmless compiler warnings. check-in: 0077c077 user: drh tags: trunk
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to src/os_win.c.

   308    308   /*
   309    309   ** The winMemData structure stores information required by the Win32-specific
   310    310   ** sqlite3_mem_methods implementation.
   311    311   */
   312    312   typedef struct winMemData winMemData;
   313    313   struct winMemData {
   314    314   #ifndef NDEBUG
   315         -  u32 magic;    /* Magic number to detect structure corruption. */
          315  +  u32 magic1;   /* Magic number to detect structure corruption. */
   316    316   #endif
   317    317     HANDLE hHeap; /* The handle to our heap. */
   318    318     BOOL bOwned;  /* Do we own the heap (i.e. destroy it on shutdown)? */
          319  +#ifndef NDEBUG
          320  +  u32 magic2;   /* Magic number to detect structure corruption. */
          321  +#endif
   319    322   };
   320    323   
   321    324   #ifndef NDEBUG
   322         -#define WINMEM_MAGIC     0x42b2830b
          325  +#define WINMEM_MAGIC1     0x42b2830b
          326  +#define WINMEM_MAGIC2     0xbd4d7cf4
   323    327   #endif
   324    328   
   325    329   static struct winMemData win_mem_data = {
   326    330   #ifndef NDEBUG
   327         -  WINMEM_MAGIC,
          331  +  WINMEM_MAGIC1,
   328    332   #endif
   329    333     NULL, FALSE
          334  +#ifndef NDEBUG
          335  +  ,WINMEM_MAGIC2
          336  +#endif
   330    337   };
   331    338   
   332    339   #ifndef NDEBUG
   333         -#define winMemAssertMagic() assert( win_mem_data.magic==WINMEM_MAGIC )
          340  +#define winMemAssertMagic1() assert( win_mem_data.magic1==WINMEM_MAGIC1 )
          341  +#define winMemAssertMagic2() assert( win_mem_data.magic2==WINMEM_MAGIC2 )
          342  +#define winMemAssertMagic()  winMemAssertMagic1(); winMemAssertMagic2();
   334    343   #else
   335    344   #define winMemAssertMagic()
   336    345   #endif
   337    346   
   338         -#define winMemGetHeap() win_mem_data.hHeap
          347  +#define winMemGetDataPtr()  &win_mem_data
          348  +#define winMemGetHeap()     win_mem_data.hHeap
          349  +#define winMemGetOwned()    win_mem_data.bOwned
   339    350   
   340    351   static void *winMemMalloc(int nBytes);
   341    352   static void winMemFree(void *pPrior);
   342    353   static void *winMemRealloc(void *pPrior, int nBytes);
   343    354   static int winMemSize(void *p);
   344    355   static int winMemRoundup(int n);
   345    356   static int winMemInit(void *pAppData);
................................................................................
   728    739   #else
   729    740     { "HeapValidate",            (SYSCALL)0,                       0 },
   730    741   #endif
   731    742   
   732    743   #define osHeapValidate ((BOOL(WINAPI*)(HANDLE,DWORD, \
   733    744           LPCVOID))aSyscall[42].pCurrent)
   734    745   
          746  +#if !SQLITE_OS_WINRT
          747  +  { "HeapCompact",             (SYSCALL)HeapCompact,             0 },
          748  +#else
          749  +  { "HeapCompact",             (SYSCALL)0,                       0 },
          750  +#endif
          751  +
          752  +#define osHeapCompact ((UINT(WINAPI*)(HANDLE,DWORD))aSyscall[43].pCurrent)
          753  +
   735    754   #if defined(SQLITE_WIN32_HAS_ANSI) && !defined(SQLITE_OMIT_LOAD_EXTENSION)
   736    755     { "LoadLibraryA",            (SYSCALL)LoadLibraryA,            0 },
   737    756   #else
   738    757     { "LoadLibraryA",            (SYSCALL)0,                       0 },
   739    758   #endif
   740    759   
   741         -#define osLoadLibraryA ((HMODULE(WINAPI*)(LPCSTR))aSyscall[43].pCurrent)
          760  +#define osLoadLibraryA ((HMODULE(WINAPI*)(LPCSTR))aSyscall[44].pCurrent)
   742    761   
   743    762   #if !SQLITE_OS_WINRT && defined(SQLITE_WIN32_HAS_WIDE) && \
   744    763           !defined(SQLITE_OMIT_LOAD_EXTENSION)
   745    764     { "LoadLibraryW",            (SYSCALL)LoadLibraryW,            0 },
   746    765   #else
   747    766     { "LoadLibraryW",            (SYSCALL)0,                       0 },
   748    767   #endif
   749    768   
   750         -#define osLoadLibraryW ((HMODULE(WINAPI*)(LPCWSTR))aSyscall[44].pCurrent)
          769  +#define osLoadLibraryW ((HMODULE(WINAPI*)(LPCWSTR))aSyscall[45].pCurrent)
   751    770   
   752    771   #if !SQLITE_OS_WINRT
   753    772     { "LocalFree",               (SYSCALL)LocalFree,               0 },
   754    773   #else
   755    774     { "LocalFree",               (SYSCALL)0,                       0 },
   756    775   #endif
   757    776   
   758         -#define osLocalFree ((HLOCAL(WINAPI*)(HLOCAL))aSyscall[45].pCurrent)
          777  +#define osLocalFree ((HLOCAL(WINAPI*)(HLOCAL))aSyscall[46].pCurrent)
   759    778   
   760    779   #if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT
   761    780     { "LockFile",                (SYSCALL)LockFile,                0 },
   762    781   #else
   763    782     { "LockFile",                (SYSCALL)0,                       0 },
   764    783   #endif
   765    784   
   766    785   #ifndef osLockFile
   767    786   #define osLockFile ((BOOL(WINAPI*)(HANDLE,DWORD,DWORD,DWORD, \
   768         -        DWORD))aSyscall[46].pCurrent)
          787  +        DWORD))aSyscall[47].pCurrent)
   769    788   #endif
   770    789   
   771    790   #if !SQLITE_OS_WINCE
   772    791     { "LockFileEx",              (SYSCALL)LockFileEx,              0 },
   773    792   #else
   774    793     { "LockFileEx",              (SYSCALL)0,                       0 },
   775    794   #endif
   776    795   
   777    796   #ifndef osLockFileEx
   778    797   #define osLockFileEx ((BOOL(WINAPI*)(HANDLE,DWORD,DWORD,DWORD,DWORD, \
   779         -        LPOVERLAPPED))aSyscall[47].pCurrent)
          798  +        LPOVERLAPPED))aSyscall[48].pCurrent)
   780    799   #endif
   781    800   
   782    801   #if SQLITE_OS_WINCE || (!SQLITE_OS_WINRT && !defined(SQLITE_OMIT_WAL))
   783    802     { "MapViewOfFile",           (SYSCALL)MapViewOfFile,           0 },
   784    803   #else
   785    804     { "MapViewOfFile",           (SYSCALL)0,                       0 },
   786    805   #endif
   787    806   
   788    807   #define osMapViewOfFile ((LPVOID(WINAPI*)(HANDLE,DWORD,DWORD,DWORD, \
   789         -        SIZE_T))aSyscall[48].pCurrent)
          808  +        SIZE_T))aSyscall[49].pCurrent)
   790    809   
   791    810     { "MultiByteToWideChar",     (SYSCALL)MultiByteToWideChar,     0 },
   792    811   
   793    812   #define osMultiByteToWideChar ((int(WINAPI*)(UINT,DWORD,LPCSTR,int,LPWSTR, \
   794         -        int))aSyscall[49].pCurrent)
          813  +        int))aSyscall[50].pCurrent)
   795    814   
   796    815     { "QueryPerformanceCounter", (SYSCALL)QueryPerformanceCounter, 0 },
   797    816   
   798    817   #define osQueryPerformanceCounter ((BOOL(WINAPI*)( \
   799         -        LARGE_INTEGER*))aSyscall[50].pCurrent)
          818  +        LARGE_INTEGER*))aSyscall[51].pCurrent)
   800    819   
   801    820     { "ReadFile",                (SYSCALL)ReadFile,                0 },
   802    821   
   803    822   #define osReadFile ((BOOL(WINAPI*)(HANDLE,LPVOID,DWORD,LPDWORD, \
   804         -        LPOVERLAPPED))aSyscall[51].pCurrent)
          823  +        LPOVERLAPPED))aSyscall[52].pCurrent)
   805    824   
   806    825     { "SetEndOfFile",            (SYSCALL)SetEndOfFile,            0 },
   807    826   
   808         -#define osSetEndOfFile ((BOOL(WINAPI*)(HANDLE))aSyscall[52].pCurrent)
          827  +#define osSetEndOfFile ((BOOL(WINAPI*)(HANDLE))aSyscall[53].pCurrent)
   809    828   
   810    829   #if !SQLITE_OS_WINRT
   811    830     { "SetFilePointer",          (SYSCALL)SetFilePointer,          0 },
   812    831   #else
   813    832     { "SetFilePointer",          (SYSCALL)0,                       0 },
   814    833   #endif
   815    834   
   816    835   #define osSetFilePointer ((DWORD(WINAPI*)(HANDLE,LONG,PLONG, \
   817         -        DWORD))aSyscall[53].pCurrent)
          836  +        DWORD))aSyscall[54].pCurrent)
   818    837   
   819    838   #if !SQLITE_OS_WINRT
   820    839     { "Sleep",                   (SYSCALL)Sleep,                   0 },
   821    840   #else
   822    841     { "Sleep",                   (SYSCALL)0,                       0 },
   823    842   #endif
   824    843   
   825         -#define osSleep ((VOID(WINAPI*)(DWORD))aSyscall[54].pCurrent)
          844  +#define osSleep ((VOID(WINAPI*)(DWORD))aSyscall[55].pCurrent)
   826    845   
   827    846     { "SystemTimeToFileTime",    (SYSCALL)SystemTimeToFileTime,    0 },
   828    847   
   829    848   #define osSystemTimeToFileTime ((BOOL(WINAPI*)(CONST SYSTEMTIME*, \
   830         -        LPFILETIME))aSyscall[55].pCurrent)
          849  +        LPFILETIME))aSyscall[56].pCurrent)
   831    850   
   832    851   #if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT
   833    852     { "UnlockFile",              (SYSCALL)UnlockFile,              0 },
   834    853   #else
   835    854     { "UnlockFile",              (SYSCALL)0,                       0 },
   836    855   #endif
   837    856   
   838    857   #ifndef osUnlockFile
   839    858   #define osUnlockFile ((BOOL(WINAPI*)(HANDLE,DWORD,DWORD,DWORD, \
   840         -        DWORD))aSyscall[56].pCurrent)
          859  +        DWORD))aSyscall[57].pCurrent)
   841    860   #endif
   842    861   
   843    862   #if !SQLITE_OS_WINCE
   844    863     { "UnlockFileEx",            (SYSCALL)UnlockFileEx,            0 },
   845    864   #else
   846    865     { "UnlockFileEx",            (SYSCALL)0,                       0 },
   847    866   #endif
   848    867   
   849    868   #define osUnlockFileEx ((BOOL(WINAPI*)(HANDLE,DWORD,DWORD,DWORD, \
   850         -        LPOVERLAPPED))aSyscall[57].pCurrent)
          869  +        LPOVERLAPPED))aSyscall[58].pCurrent)
   851    870   
   852    871   #if SQLITE_OS_WINCE || !defined(SQLITE_OMIT_WAL)
   853    872     { "UnmapViewOfFile",         (SYSCALL)UnmapViewOfFile,         0 },
   854    873   #else
   855    874     { "UnmapViewOfFile",         (SYSCALL)0,                       0 },
   856    875   #endif
   857    876   
   858         -#define osUnmapViewOfFile ((BOOL(WINAPI*)(LPCVOID))aSyscall[58].pCurrent)
          877  +#define osUnmapViewOfFile ((BOOL(WINAPI*)(LPCVOID))aSyscall[59].pCurrent)
   859    878   
   860    879     { "WideCharToMultiByte",     (SYSCALL)WideCharToMultiByte,     0 },
   861    880   
   862    881   #define osWideCharToMultiByte ((int(WINAPI*)(UINT,DWORD,LPCWSTR,int,LPSTR,int, \
   863         -        LPCSTR,LPBOOL))aSyscall[59].pCurrent)
          882  +        LPCSTR,LPBOOL))aSyscall[60].pCurrent)
   864    883   
   865    884     { "WriteFile",               (SYSCALL)WriteFile,               0 },
   866    885   
   867    886   #define osWriteFile ((BOOL(WINAPI*)(HANDLE,LPCVOID,DWORD,LPDWORD, \
   868         -        LPOVERLAPPED))aSyscall[60].pCurrent)
          887  +        LPOVERLAPPED))aSyscall[61].pCurrent)
   869    888   
   870    889   #if SQLITE_OS_WINRT
   871    890     { "CreateEventExW",          (SYSCALL)CreateEventExW,          0 },
   872    891   #else
   873    892     { "CreateEventExW",          (SYSCALL)0,                       0 },
   874    893   #endif
   875    894   
   876    895   #define osCreateEventExW ((HANDLE(WINAPI*)(LPSECURITY_ATTRIBUTES,LPCWSTR, \
   877         -        DWORD,DWORD))aSyscall[61].pCurrent)
          896  +        DWORD,DWORD))aSyscall[62].pCurrent)
   878    897   
   879    898   #if !SQLITE_OS_WINRT
   880    899     { "WaitForSingleObject",     (SYSCALL)WaitForSingleObject,     0 },
   881    900   #else
   882    901     { "WaitForSingleObject",     (SYSCALL)0,                       0 },
   883    902   #endif
   884    903   
   885    904   #define osWaitForSingleObject ((DWORD(WINAPI*)(HANDLE, \
   886         -        DWORD))aSyscall[62].pCurrent)
          905  +        DWORD))aSyscall[63].pCurrent)
   887    906   
   888    907   #if SQLITE_OS_WINRT
   889    908     { "WaitForSingleObjectEx",   (SYSCALL)WaitForSingleObjectEx,   0 },
   890    909   #else
   891    910     { "WaitForSingleObjectEx",   (SYSCALL)0,                       0 },
   892    911   #endif
   893    912   
   894    913   #define osWaitForSingleObjectEx ((DWORD(WINAPI*)(HANDLE,DWORD, \
   895         -        BOOL))aSyscall[63].pCurrent)
          914  +        BOOL))aSyscall[64].pCurrent)
   896    915   
   897    916   #if SQLITE_OS_WINRT
   898    917     { "SetFilePointerEx",        (SYSCALL)SetFilePointerEx,        0 },
   899    918   #else
   900    919     { "SetFilePointerEx",        (SYSCALL)0,                       0 },
   901    920   #endif
   902    921   
   903    922   #define osSetFilePointerEx ((BOOL(WINAPI*)(HANDLE,LARGE_INTEGER, \
   904         -        PLARGE_INTEGER,DWORD))aSyscall[64].pCurrent)
          923  +        PLARGE_INTEGER,DWORD))aSyscall[65].pCurrent)
   905    924   
   906    925   #if SQLITE_OS_WINRT
   907    926     { "GetFileInformationByHandleEx", (SYSCALL)GetFileInformationByHandleEx, 0 },
   908    927   #else
   909    928     { "GetFileInformationByHandleEx", (SYSCALL)0,                  0 },
   910    929   #endif
   911    930   
   912    931   #define osGetFileInformationByHandleEx ((BOOL(WINAPI*)(HANDLE, \
   913         -        FILE_INFO_BY_HANDLE_CLASS,LPVOID,DWORD))aSyscall[65].pCurrent)
          932  +        FILE_INFO_BY_HANDLE_CLASS,LPVOID,DWORD))aSyscall[66].pCurrent)
   914    933   
   915    934   #if SQLITE_OS_WINRT && !defined(SQLITE_OMIT_WAL)
   916    935     { "MapViewOfFileFromApp",    (SYSCALL)MapViewOfFileFromApp,    0 },
   917    936   #else
   918    937     { "MapViewOfFileFromApp",    (SYSCALL)0,                       0 },
   919    938   #endif
   920    939   
   921    940   #define osMapViewOfFileFromApp ((LPVOID(WINAPI*)(HANDLE,ULONG,ULONG64, \
   922         -        SIZE_T))aSyscall[66].pCurrent)
          941  +        SIZE_T))aSyscall[67].pCurrent)
   923    942   
   924    943   #if SQLITE_OS_WINRT
   925    944     { "CreateFile2",             (SYSCALL)CreateFile2,             0 },
   926    945   #else
   927    946     { "CreateFile2",             (SYSCALL)0,                       0 },
   928    947   #endif
   929    948   
   930    949   #define osCreateFile2 ((HANDLE(WINAPI*)(LPCWSTR,DWORD,DWORD,DWORD, \
   931         -        LPCREATEFILE2_EXTENDED_PARAMETERS))aSyscall[67].pCurrent)
          950  +        LPCREATEFILE2_EXTENDED_PARAMETERS))aSyscall[68].pCurrent)
   932    951   
   933    952   #if SQLITE_OS_WINRT && !defined(SQLITE_OMIT_LOAD_EXTENSION)
   934    953     { "LoadPackagedLibrary",     (SYSCALL)LoadPackagedLibrary,     0 },
   935    954   #else
   936    955     { "LoadPackagedLibrary",     (SYSCALL)0,                       0 },
   937    956   #endif
   938    957   
   939    958   #define osLoadPackagedLibrary ((HMODULE(WINAPI*)(LPCWSTR, \
   940         -        DWORD))aSyscall[68].pCurrent)
          959  +        DWORD))aSyscall[69].pCurrent)
   941    960   
   942    961   #if SQLITE_OS_WINRT
   943    962     { "GetTickCount64",          (SYSCALL)GetTickCount64,          0 },
   944    963   #else
   945    964     { "GetTickCount64",          (SYSCALL)0,                       0 },
   946    965   #endif
   947    966   
   948         -#define osGetTickCount64 ((ULONGLONG(WINAPI*)(VOID))aSyscall[69].pCurrent)
          967  +#define osGetTickCount64 ((ULONGLONG(WINAPI*)(VOID))aSyscall[70].pCurrent)
   949    968   
   950    969   #if SQLITE_OS_WINRT
   951    970     { "GetNativeSystemInfo",     (SYSCALL)GetNativeSystemInfo,     0 },
   952    971   #else
   953    972     { "GetNativeSystemInfo",     (SYSCALL)0,                       0 },
   954    973   #endif
   955    974   
   956    975   #define osGetNativeSystemInfo ((VOID(WINAPI*)( \
   957         -        LPSYSTEM_INFO))aSyscall[70].pCurrent)
          976  +        LPSYSTEM_INFO))aSyscall[71].pCurrent)
   958    977   
   959    978   #if defined(SQLITE_WIN32_HAS_ANSI)
   960    979     { "OutputDebugStringA",      (SYSCALL)OutputDebugStringA,      0 },
   961    980   #else
   962    981     { "OutputDebugStringA",      (SYSCALL)0,                       0 },
   963    982   #endif
   964    983   
   965         -#define osOutputDebugStringA ((VOID(WINAPI*)(LPCSTR))aSyscall[71].pCurrent)
          984  +#define osOutputDebugStringA ((VOID(WINAPI*)(LPCSTR))aSyscall[72].pCurrent)
   966    985   
   967    986   #if defined(SQLITE_WIN32_HAS_WIDE)
   968    987     { "OutputDebugStringW",      (SYSCALL)OutputDebugStringW,      0 },
   969    988   #else
   970    989     { "OutputDebugStringW",      (SYSCALL)0,                       0 },
   971    990   #endif
   972    991   
   973         -#define osOutputDebugStringW ((VOID(WINAPI*)(LPCWSTR))aSyscall[72].pCurrent)
          992  +#define osOutputDebugStringW ((VOID(WINAPI*)(LPCWSTR))aSyscall[73].pCurrent)
   974    993   
   975    994     { "GetProcessHeap",          (SYSCALL)GetProcessHeap,          0 },
   976    995   
   977         -#define osGetProcessHeap ((HANDLE(WINAPI*)(VOID))aSyscall[73].pCurrent)
          996  +#define osGetProcessHeap ((HANDLE(WINAPI*)(VOID))aSyscall[74].pCurrent)
   978    997   
   979    998   #if SQLITE_OS_WINRT && !defined(SQLITE_OMIT_WAL)
   980    999     { "CreateFileMappingFromApp", (SYSCALL)CreateFileMappingFromApp, 0 },
   981   1000   #else
   982   1001     { "CreateFileMappingFromApp", (SYSCALL)0,                      0 },
   983   1002   #endif
   984   1003   
   985   1004   #define osCreateFileMappingFromApp ((HANDLE(WINAPI*)(HANDLE, \
   986         -        LPSECURITY_ATTRIBUTES,ULONG,ULONG64,LPCWSTR))aSyscall[74].pCurrent)
         1005  +        LPSECURITY_ATTRIBUTES,ULONG,ULONG64,LPCWSTR))aSyscall[75].pCurrent)
   987   1006   
   988   1007   }; /* End of the overrideable system calls */
   989   1008   
   990   1009   /*
   991   1010   ** This is the xSetSystemCall() method of sqlite3_vfs for all of the
   992   1011   ** "win32" VFSes.  Return SQLITE_OK opon successfully updating the
   993   1012   ** system call pointer, or SQLITE_NOTFOUND if there is no configurable
................................................................................
  1065   1084       }
  1066   1085     }
  1067   1086     for(i++; i<ArraySize(aSyscall); i++){
  1068   1087       if( aSyscall[i].pCurrent!=0 ) return aSyscall[i].zName;
  1069   1088     }
  1070   1089     return 0;
  1071   1090   }
         1091  +
         1092  +/*
         1093  +** If a Win32 native heap has been configured, this function will attempt to
         1094  +** compact it.  Upon success, SQLITE_OK will be returned.  Upon failure, one
         1095  +** of SQLITE_NOMEM, SQLITE_ERROR, or SQLITE_NOTFOUND will be returned.  The
         1096  +** "pnLargest" argument, if non-zero, will be used to return the size of the
         1097  +** largest committed free block in the heap, in bytes.
         1098  +*/
         1099  +int sqlite3_win32_compact_heap(LPUINT pnLargest){
         1100  +  int rc = SQLITE_OK;
         1101  +  UINT nLargest = 0;
         1102  +  HANDLE hHeap;
         1103  +
         1104  +  winMemAssertMagic();
         1105  +  hHeap = winMemGetHeap();
         1106  +  assert( hHeap!=0 );
         1107  +  assert( hHeap!=INVALID_HANDLE_VALUE );
         1108  +#if !SQLITE_OS_WINRT && defined(SQLITE_WIN32_MALLOC_VALIDATE)
         1109  +  assert( osHeapValidate(hHeap, SQLITE_WIN32_HEAP_FLAGS, NULL) );
         1110  +#endif
         1111  +#if !SQLITE_OS_WINRT
         1112  +  if( (nLargest=osHeapCompact(hHeap, SQLITE_WIN32_HEAP_FLAGS))==0 ){
         1113  +    DWORD lastErrno = osGetLastError();
         1114  +    if( lastErrno==NO_ERROR ){
         1115  +      sqlite3_log(SQLITE_NOMEM, "failed to HeapCompact (no space), heap=%p",
         1116  +                  (void*)hHeap);
         1117  +      rc = SQLITE_NOMEM;
         1118  +    }else{
         1119  +      sqlite3_log(SQLITE_NOMEM, "failed to HeapCompact (%lu), heap=%p",
         1120  +                  osGetLastError(), (void*)hHeap);
         1121  +      rc = SQLITE_ERROR;
         1122  +    }
         1123  +  }
         1124  +#else
         1125  +  rc = SQLITE_NOTFOUND;
         1126  +#endif
         1127  +  if( pnLargest ) *pnLargest = nLargest;
         1128  +  return rc;
         1129  +}
         1130  +
         1131  +/*
         1132  +** If a Win32 native heap has been configured, this function will attempt to
         1133  +** destroy and recreate it.  If the Win32 native heap is not isolated and/or
         1134  +** the sqlite3_memory_used() function does not return zero, SQLITE_BUSY will
         1135  +** be returned and no changes will be made to the Win32 native heap.
         1136  +*/
         1137  +int sqlite3_win32_reset_heap(){
         1138  +  int rc;
         1139  +  MUTEX_LOGIC( sqlite3_mutex *pMaster; ) /* The main static mutex */
         1140  +  MUTEX_LOGIC( sqlite3_mutex *pMem; )    /* The memsys static mutex */
         1141  +  MUTEX_LOGIC( pMaster = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER); )
         1142  +  MUTEX_LOGIC( pMem = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MEM); )
         1143  +  sqlite3_mutex_enter(pMaster);
         1144  +  sqlite3_mutex_enter(pMem);
         1145  +  if( winMemGetOwned() && sqlite3_memory_used()==0 ){
         1146  +    /*
         1147  +    ** At this point, there should be no outstanding memory allocations on
         1148  +    ** the heap.  Also, since both the master and memsys locks are currently
         1149  +    ** being held by us, no other function (i.e. from another thread) should
         1150  +    ** be able to even access the heap.  Attempt to destroy and recreate our
         1151  +    ** isolated Win32 native heap now.
         1152  +    */
         1153  +    winMemShutdown(winMemGetDataPtr());
         1154  +    winMemInit(winMemGetDataPtr());
         1155  +    rc = SQLITE_OK;
         1156  +  }else{
         1157  +    /*
         1158  +    ** The Win32 native heap cannot be modified because it may be in use.
         1159  +    */
         1160  +    rc = SQLITE_BUSY;
         1161  +  }
         1162  +  sqlite3_mutex_leave(pMem);
         1163  +  sqlite3_mutex_leave(pMaster);
         1164  +  return rc;
         1165  +}
  1072   1166   
  1073   1167   /*
  1074   1168   ** This function outputs the specified (ANSI) string to the Win32 debugger
  1075   1169   ** (if available).
  1076   1170   */
  1077   1171   
  1078   1172   void sqlite3_win32_write_debug(const char *zBuf, int nBuf){
................................................................................
  1174   1268     void *p;
  1175   1269   
  1176   1270     winMemAssertMagic();
  1177   1271     hHeap = winMemGetHeap();
  1178   1272     assert( hHeap!=0 );
  1179   1273     assert( hHeap!=INVALID_HANDLE_VALUE );
  1180   1274   #if !SQLITE_OS_WINRT && defined(SQLITE_WIN32_MALLOC_VALIDATE)
  1181         -  assert ( osHeapValidate(hHeap, SQLITE_WIN32_HEAP_FLAGS, NULL) );
         1275  +  assert( osHeapValidate(hHeap, SQLITE_WIN32_HEAP_FLAGS, NULL) );
  1182   1276   #endif
  1183   1277     assert( nBytes>=0 );
  1184   1278     p = osHeapAlloc(hHeap, SQLITE_WIN32_HEAP_FLAGS, (SIZE_T)nBytes);
  1185   1279     if( !p ){
  1186   1280       sqlite3_log(SQLITE_NOMEM, "failed to HeapAlloc %u bytes (%lu), heap=%p",
  1187   1281                   nBytes, osGetLastError(), (void*)hHeap);
  1188   1282     }
................................................................................
  1196   1290     HANDLE hHeap;
  1197   1291   
  1198   1292     winMemAssertMagic();
  1199   1293     hHeap = winMemGetHeap();
  1200   1294     assert( hHeap!=0 );
  1201   1295     assert( hHeap!=INVALID_HANDLE_VALUE );
  1202   1296   #if !SQLITE_OS_WINRT && defined(SQLITE_WIN32_MALLOC_VALIDATE)
  1203         -  assert ( osHeapValidate(hHeap, SQLITE_WIN32_HEAP_FLAGS, pPrior) );
         1297  +  assert( osHeapValidate(hHeap, SQLITE_WIN32_HEAP_FLAGS, pPrior) );
  1204   1298   #endif
  1205   1299     if( !pPrior ) return; /* Passing NULL to HeapFree is undefined. */
  1206   1300     if( !osHeapFree(hHeap, SQLITE_WIN32_HEAP_FLAGS, pPrior) ){
  1207   1301       sqlite3_log(SQLITE_NOMEM, "failed to HeapFree block %p (%lu), heap=%p",
  1208   1302                   pPrior, osGetLastError(), (void*)hHeap);
  1209   1303     }
  1210   1304   }
................................................................................
  1217   1311     void *p;
  1218   1312   
  1219   1313     winMemAssertMagic();
  1220   1314     hHeap = winMemGetHeap();
  1221   1315     assert( hHeap!=0 );
  1222   1316     assert( hHeap!=INVALID_HANDLE_VALUE );
  1223   1317   #if !SQLITE_OS_WINRT && defined(SQLITE_WIN32_MALLOC_VALIDATE)
  1224         -  assert ( osHeapValidate(hHeap, SQLITE_WIN32_HEAP_FLAGS, pPrior) );
         1318  +  assert( osHeapValidate(hHeap, SQLITE_WIN32_HEAP_FLAGS, pPrior) );
  1225   1319   #endif
  1226   1320     assert( nBytes>=0 );
  1227   1321     if( !pPrior ){
  1228   1322       p = osHeapAlloc(hHeap, SQLITE_WIN32_HEAP_FLAGS, (SIZE_T)nBytes);
  1229   1323     }else{
  1230   1324       p = osHeapReAlloc(hHeap, SQLITE_WIN32_HEAP_FLAGS, pPrior, (SIZE_T)nBytes);
  1231   1325     }
................................................................................
  1245   1339     SIZE_T n;
  1246   1340   
  1247   1341     winMemAssertMagic();
  1248   1342     hHeap = winMemGetHeap();
  1249   1343     assert( hHeap!=0 );
  1250   1344     assert( hHeap!=INVALID_HANDLE_VALUE );
  1251   1345   #if !SQLITE_OS_WINRT && defined(SQLITE_WIN32_MALLOC_VALIDATE)
  1252         -  assert ( osHeapValidate(hHeap, SQLITE_WIN32_HEAP_FLAGS, NULL) );
         1346  +  assert( osHeapValidate(hHeap, SQLITE_WIN32_HEAP_FLAGS, NULL) );
  1253   1347   #endif
  1254   1348     if( !p ) return 0;
  1255   1349     n = osHeapSize(hHeap, SQLITE_WIN32_HEAP_FLAGS, p);
  1256   1350     if( n==(SIZE_T)-1 ){
  1257   1351       sqlite3_log(SQLITE_NOMEM, "failed to HeapSize block %p (%lu), heap=%p",
  1258   1352                   p, osGetLastError(), (void*)hHeap);
  1259   1353       return 0;
................................................................................
  1271   1365   /*
  1272   1366   ** Initialize this module.
  1273   1367   */
  1274   1368   static int winMemInit(void *pAppData){
  1275   1369     winMemData *pWinMemData = (winMemData *)pAppData;
  1276   1370   
  1277   1371     if( !pWinMemData ) return SQLITE_ERROR;
  1278         -  assert( pWinMemData->magic==WINMEM_MAGIC );
         1372  +  assert( pWinMemData->magic1==WINMEM_MAGIC1 );
         1373  +  assert( pWinMemData->magic2==WINMEM_MAGIC2 );
  1279   1374   
  1280   1375   #if !SQLITE_OS_WINRT && SQLITE_WIN32_HEAP_CREATE
  1281   1376     if( !pWinMemData->hHeap ){
  1282   1377       pWinMemData->hHeap = osHeapCreate(SQLITE_WIN32_HEAP_FLAGS,
  1283   1378                                         SQLITE_WIN32_HEAP_INIT_SIZE,
  1284   1379                                         SQLITE_WIN32_HEAP_MAX_SIZE);
  1285   1380       if( !pWinMemData->hHeap ){
................................................................................
  1313   1408   /*
  1314   1409   ** Deinitialize this module.
  1315   1410   */
  1316   1411   static void winMemShutdown(void *pAppData){
  1317   1412     winMemData *pWinMemData = (winMemData *)pAppData;
  1318   1413   
  1319   1414     if( !pWinMemData ) return;
         1415  +  assert( pWinMemData->magic1==WINMEM_MAGIC1 );
         1416  +  assert( pWinMemData->magic2==WINMEM_MAGIC2 );
         1417  +
  1320   1418     if( pWinMemData->hHeap ){
  1321   1419       assert( pWinMemData->hHeap!=INVALID_HANDLE_VALUE );
  1322   1420   #if !SQLITE_OS_WINRT && defined(SQLITE_WIN32_MALLOC_VALIDATE)
  1323   1421       assert( osHeapValidate(pWinMemData->hHeap, SQLITE_WIN32_HEAP_FLAGS, NULL) );
  1324   1422   #endif
  1325   1423       if( pWinMemData->bOwned ){
  1326   1424         if( !osHeapDestroy(pWinMemData->hHeap) ){
................................................................................
  5192   5290       winGetSystemCall,    /* xGetSystemCall */
  5193   5291       winNextSystemCall,   /* xNextSystemCall */
  5194   5292     };
  5195   5293   #endif
  5196   5294   
  5197   5295     /* Double-check that the aSyscall[] array has been constructed
  5198   5296     ** correctly.  See ticket [bb3a86e890c8e96ab] */
  5199         -  assert( ArraySize(aSyscall)==75 );
         5297  +  assert( ArraySize(aSyscall)==76 );
  5200   5298   
  5201   5299     /* get memory map allocation granularity */
  5202   5300     memset(&winSysInfo, 0, sizeof(SYSTEM_INFO));
  5203   5301   #if SQLITE_OS_WINRT
  5204   5302     osGetNativeSystemInfo(&winSysInfo);
  5205   5303   #else
  5206   5304     osGetSystemInfo(&winSysInfo);