1
0
mirror of https://github.com/sqlite/sqlite.git synced 2025-08-08 14:02:16 +03:00

fix for locking in Windows (CVS 760)

FossilOrigin-Name: 83add34f64895a4b465881213eba82f3b1f5c964
This commit is contained in:
mike
2002-10-17 00:38:54 +00:00
parent f1f0fa0769
commit 710dcfbde5
3 changed files with 84 additions and 35 deletions

View File

@@ -1,5 +1,5 @@
C Remove\sthe\scall\sto\ssrand()\sand\sadd\sbetter\scomments\sto\sthe\ssqliteOsRandomSeed()\nroutine.\s\sTicket\s#163.\s(CVS\s759) C fix\sfor\slocking\sin\sWindows\s(CVS\s760)
D 2002-10-12T13:44:00 D 2002-10-17T00:38:54
F Makefile.in d6c9a85c2a5e696843201d090dcf8bf2f8716f2a F Makefile.in d6c9a85c2a5e696843201d090dcf8bf2f8716f2a
F Makefile.linux-gcc b86a99c493a5bfb402d1d9178dcdc4bd4b32f906 F Makefile.linux-gcc b86a99c493a5bfb402d1d9178dcdc4bd4b32f906
F README f1de682fbbd94899d50aca13d387d1b3fd3be2dd F README f1de682fbbd94899d50aca13d387d1b3fd3be2dd
@@ -30,7 +30,7 @@ F src/hash.h cd0433998bc1a3759d244e1637fe5a3c13b53bf8
F src/insert.c 764300a0bd8074a2174946c0bf8a550bd833397a F src/insert.c 764300a0bd8074a2174946c0bf8a550bd833397a
F src/main.c ff7c05ef88fa1374e5540ce20173ae8e1836f8a4 F src/main.c ff7c05ef88fa1374e5540ce20173ae8e1836f8a4
F src/md5.c fe4f9c9c6f71dfc26af8da63e4d04489b1430565 F src/md5.c fe4f9c9c6f71dfc26af8da63e4d04489b1430565
F src/os.c a099c7058e79f86edce9ca1f812078cdabe47a2c F src/os.c 2c26f354c4bbe94ba4d6e1f04289c63bc1fdb87c
F src/os.h 3009379b06941e7796a9812d1b6cbc59b26248c8 F src/os.h 3009379b06941e7796a9812d1b6cbc59b26248c8
F src/pager.c 592e5931fdc65e952a6c3e152bc822580856532a F src/pager.c 592e5931fdc65e952a6c3e152bc822580856532a
F src/pager.h 6991c9c2dc5e4c7f2df4d4ba47d1c6458f763a32 F src/pager.h 6991c9c2dc5e4c7f2df4d4ba47d1c6458f763a32
@@ -149,7 +149,7 @@ F www/speed.tcl a20a792738475b68756ea7a19321600f23d1d803
F www/sqlite.tcl ae3dcfb077e53833b59d4fcc94d8a12c50a44098 F www/sqlite.tcl ae3dcfb077e53833b59d4fcc94d8a12c50a44098
F www/tclsqlite.tcl 1db15abeb446aad0caf0b95b8b9579720e4ea331 F www/tclsqlite.tcl 1db15abeb446aad0caf0b95b8b9579720e4ea331
F www/vdbe.tcl 2013852c27a02a091d39a766bc87cff329f21218 F www/vdbe.tcl 2013852c27a02a091d39a766bc87cff329f21218
P 6c0f44bd6374010f7a4a091e585eb36e0665f96f P d87a886d8f63f54466848151e2b0e8565b338593
R 5d988e98e73febc16900dcc2d7b1140f R bf058781dafbb0c6ad71e236c2683985
U drh U mike
Z 4347cb15b61079c5bf526a0f73fa4ac4 Z 02abffa2bb18c0118ab5f6d1ca430ce7

View File

@@ -1 +1 @@
d87a886d8f63f54466848151e2b0e8565b338593 83add34f64895a4b465881213eba82f3b1f5c964

101
src/os.c
View File

@@ -492,7 +492,7 @@ int sqliteOsRead(OsFile *id, void *pBuf, int amt){
if( !ReadFile(id->h, pBuf, amt, &got, 0) ){ if( !ReadFile(id->h, pBuf, amt, &got, 0) ){
got = 0; got = 0;
} }
if( got==amt ){ if( (int)got==amt ){
return SQLITE_OK; return SQLITE_OK;
}else{ }else{
return SQLITE_IOERR; return SQLITE_IOERR;
@@ -627,10 +627,64 @@ int sqliteOsFileSize(OsFile *id, int *pSize){
** lock and get the read lock without another process jumping into the ** lock and get the read lock without another process jumping into the
** middle and messing us up. The same argument applies to sqliteOsWriteLock(). ** middle and messing us up. The same argument applies to sqliteOsWriteLock().
** **
** Locks must be obtained in an area that does not overlap the "real data area"
** otherwise read/write operations will conflict with lock operations. Locking beyond EOF
** is allowed in windows.
**
** There are a finite number of read locks under windows. That number ** There are a finite number of read locks under windows. That number
** is determined by the following variable: ** is determined by the following variable:
*/ */
#define MX_LOCKBYTE 10240
#define MX_LOCKBYTE 0xFFF0
#if OS_WIN
// get the platform id to decide how to calculate the lock offset
int mkPlatformId(void){
static long init=0;
static int pid=VER_PLATFORM_WIN32_WINDOWS;
OSVERSIONINFOA info;
if (!init) {
if (InterlockedIncrement(&init)==1)
{
info.dwOSVersionInfoSize=sizeof(info);
if (GetVersionEx(&info)) pid=info.dwPlatformId;
}
}
return pid;
}
// locks and unlocks beyond eof. uses platformid to move the lock as far as possible.
int mklock(HANDLE h, WORD base, WORD size)
{
if (mkPlatformId()==VER_PLATFORM_WIN32_WINDOWS)
return LockFile(h,0xFFFF0000+base,0,size,0);
else
return LockFile(h,base,0xFFFFFFFF,size,0);
}
int mkunlock(HANDLE h, WORD base, WORD size)
{
if (mkPlatformId()==VER_PLATFORM_WIN32_WINDOWS)
return UnlockFile(h,0xFFFF0000+base,0,size,0);
else
return UnlockFile(h,base,0xFFFFFFFF,size,0);
}
//obtain the sync lock on a handle
void synclock(HANDLE h){
while (!mklock(h,0,1)) Sleep(1);
}
void syncunlock(HANDLE h){
mkunlock(h,0,1);
}
#endif
/* /*
** Change the status of the lock on the file "id" to be a readlock. ** Change the status of the lock on the file "id" to be a readlock.
@@ -639,6 +693,7 @@ int sqliteOsFileSize(OsFile *id, int *pSize){
** **
** Return SQLITE_OK on success and SQLITE_BUSY on failure. ** Return SQLITE_OK on success and SQLITE_BUSY on failure.
*/ */
int sqliteOsReadLock(OsFile *id){ int sqliteOsReadLock(OsFile *id){
#if OS_UNIX #if OS_UNIX
int rc; int rc;
@@ -674,11 +729,12 @@ int sqliteOsReadLock(OsFile *id){
}else{ }else{
int lk = (sqliteRandomInteger() & 0x7ffffff)%MX_LOCKBYTE + 1; int lk = (sqliteRandomInteger() & 0x7ffffff)%MX_LOCKBYTE + 1;
int res; int res;
if( (res = LockFile(id->h, 0, 0, 1, 0))!=0 ){
UnlockFile(id->h, 1, 0, MX_LOCKBYTE, 0); synclock(id->h);
res = LockFile(id->h, lk, 0, 1, 0); if (id->locked<0) mkunlock(id->h,1,MX_LOCKBYTE); // release write lock if we have it
UnlockFile(id->h, 0, 0, 1, 0); res=mklock(id->h,lk,1);
} syncunlock(id->h);
if( res ){ if( res ){
id->locked = lk; id->locked = lk;
rc = SQLITE_OK; rc = SQLITE_OK;
@@ -722,14 +778,12 @@ int sqliteOsWriteLock(OsFile *id){
rc = SQLITE_OK; rc = SQLITE_OK;
}else{ }else{
int res; int res;
if( (res = LockFile(id->h, 0, 0, 1, 0))!=0 ){
if( id->locked==0 || UnlockFile(id->h, id->locked, 0, 1, 0) ){ synclock(id->h);
res = LockFile(id->h, 1, 0, MX_LOCKBYTE, 0); if (id->locked>0) mkunlock(id->h,id->locked,1); // release read lock
}else{ res=mklock(id->h,1,MX_LOCKBYTE);
res = 0; syncunlock(id->h);
}
UnlockFile(id->h, 0, 0, 1, 0);
}
if(res){ if(res){
id->locked = -1; id->locked = -1;
rc = SQLITE_OK; rc = SQLITE_OK;
@@ -772,18 +826,13 @@ int sqliteOsUnlock(OsFile *id){
#endif #endif
#if OS_WIN #if OS_WIN
int rc; int rc;
if( id->locked==0 ){ if(id->locked<0 ) {
rc = SQLITE_OK; mkunlock(id->h,1,MX_LOCKBYTE);
}else if( id->locked<0 ){ }else if (id->locked>0) {
UnlockFile(id->h, 1, 0, MX_LOCKBYTE, 0); mkunlock(id->h,id->locked,1);
rc = SQLITE_OK;
id->locked = 0;
}else{
UnlockFile(id->h, id->locked, 0, 1, 0);
rc = SQLITE_OK;
id->locked = 0;
} }
return rc; id->locked = 0;
return SQLITE_OK;
#endif #endif
} }