mirror of
https://github.com/sqlite/sqlite.git
synced 2025-07-24 22:22:08 +03:00
Work in progress porting lsm1 to Win32.
FossilOrigin-Name: 2017636e93cf810fe4d1247c18de9f316fca037035a026f77c4588563d7bf0cc
This commit is contained in:
@ -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>>
|
||||
|
93
ext/lsm1/Makefile.msc
Normal file
93
ext/lsm1/Makefile.msc
Normal file
@ -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$@
|
@ -23,7 +23,11 @@
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#ifdef _WIN32
|
||||
# define snprintf _snprintf
|
||||
#else
|
||||
# include <unistd.h>
|
||||
#endif
|
||||
|
||||
#ifdef NDEBUG
|
||||
# ifdef LSM_DEBUG_EXPENSIVE
|
||||
|
@ -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 ){
|
||||
|
@ -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. */
|
||||
|
@ -10,23 +10,11 @@
|
||||
**
|
||||
*************************************************************************
|
||||
**
|
||||
** 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,40 +166,59 @@ 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;
|
||||
DWORD dwDesiredAccess;
|
||||
DWORD dwShareMode = FILE_SHARE_READ | FILE_SHARE_WRITE;
|
||||
DWORD dwCreationDisposition;
|
||||
DWORD dwFlagsAndAttributes = FILE_ATTRIBUTE_NORMAL;
|
||||
HANDLE hFile;
|
||||
|
||||
CreateFile((LPCWSTR)zConverted,
|
||||
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 &&
|
||||
winRetryIoerr(&cnt, &lastErrno) ){
|
||||
|
||||
|
||||
p->fd = open(zFile, oflags, 0644);
|
||||
if( p->fd<0 ){
|
||||
lsm_free(pEnv, p);
|
||||
p = 0;
|
||||
if( errno==ENOENT ){
|
||||
win32RetryIoerr(pEnv, &nRetry) ){
|
||||
/* Noop */
|
||||
}
|
||||
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 *)p;
|
||||
}
|
||||
*ppFile = (lsm_file *)pWin32File;
|
||||
return rc;
|
||||
}
|
||||
|
||||
@ -118,37 +228,50 @@ static int lsmWin32OsWrite(
|
||||
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;
|
||||
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 */
|
||||
|
||||
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;
|
||||
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;
|
||||
}
|
||||
|
||||
return rc;
|
||||
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;
|
||||
}
|
||||
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 */
|
||||
){
|
||||
Win32File *p = (Win32File *)pFile;
|
||||
int rc = LSM_OK; /* Return code */
|
||||
int prc; /* Posix Return Code */
|
||||
struct stat sStat; /* Result of fstat() invocation */
|
||||
Win32File *pWin32File = (Win32File *)pFile;
|
||||
LARGE_INTEGER largeInteger; /* The new offset */
|
||||
|
||||
prc = fstat(p->fd, &sStat);
|
||||
if( prc==0 && sStat.st_size>nSize ){
|
||||
prc = ftruncate(p->fd, (off_t)nSize);
|
||||
largeInteger.QuadPart = nSize;
|
||||
if( !SetFilePointerEx(pWin32File->hFile, largeInteger, 0, FILE_BEGIN) ){
|
||||
return LSM_IOERR_BKPT;
|
||||
}
|
||||
if( prc<0 ) rc = LSM_IOERR_BKPT;
|
||||
|
||||
return rc;
|
||||
if (!SetEndOfFile(pWin32File->hFile) ){
|
||||
return LSM_IOERR_BKPT;
|
||||
}
|
||||
return LSM_OK;
|
||||
}
|
||||
|
||||
static int lsmWin32OsRead(
|
||||
@ -157,40 +280,41 @@ static int lsmWin32OsRead(
|
||||
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;
|
||||
Win32File *pWin32File = (Win32File *)pFile;
|
||||
OVERLAPPED overlapped; /* The offset for ReadFile */
|
||||
DWORD nRead = 0; /* Bytes read using ReadFile */
|
||||
int nRetry = 0; /* Number of retrys */
|
||||
|
||||
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);
|
||||
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;
|
||||
}
|
||||
|
||||
if( nRead<(DWORD)nData ){
|
||||
/* Unread parts of the buffer must be zero-filled */
|
||||
memset(&((char*)pData)[nRead], 0, nData - nRead);
|
||||
}
|
||||
|
||||
return rc;
|
||||
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;
|
||||
@ -206,40 +330,7 @@ static int lsmWin32OsRemap(
|
||||
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,41 +339,7 @@ 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(
|
||||
@ -290,198 +347,104 @@ static int lsmWin32OsFileid(
|
||||
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 );
|
||||
HeapFree(GetProcessHeap(), 0, p);
|
||||
}
|
||||
}
|
||||
|
||||
@ -493,53 +456,46 @@ static void *lsmWin32OsRealloc(lsm_env *pEnv, void *p, size_t N){
|
||||
}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
|
||||
/*************************************************************************
|
||||
** Mutex methods for pthreads based systems. If LSM_MUTEX_WIN32 is
|
||||
** 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
|
||||
/*
|
||||
|
23
manifest
23
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
|
||||
|
@ -1 +1 @@
|
||||
ca8a7e995c3da10ba05e3b7d4818c633fe5ba6d6f9351b67017a2603b50b903d
|
||||
2017636e93cf810fe4d1247c18de9f316fca037035a026f77c4588563d7bf0cc
|
Reference in New Issue
Block a user