From: mike Date: Thu, 17 Oct 2002 00:38:54 +0000 (+0000) Subject: fix for locking in Windows (CVS 760) X-Git-Tag: version-3.6.10~5313 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=710dcfbde5c3bdf14a030e32d7c88a6fda2020f1;p=thirdparty%2Fsqlite.git fix for locking in Windows (CVS 760) FossilOrigin-Name: 83add34f64895a4b465881213eba82f3b1f5c964 --- diff --git a/manifest b/manifest index 870bd2561e..1ab61d3fde 100644 --- a/manifest +++ b/manifest @@ -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) -D 2002-10-12T13:44:00 +C fix\sfor\slocking\sin\sWindows\s(CVS\s760) +D 2002-10-17T00:38:54 F Makefile.in d6c9a85c2a5e696843201d090dcf8bf2f8716f2a F Makefile.linux-gcc b86a99c493a5bfb402d1d9178dcdc4bd4b32f906 F README f1de682fbbd94899d50aca13d387d1b3fd3be2dd @@ -30,7 +30,7 @@ F src/hash.h cd0433998bc1a3759d244e1637fe5a3c13b53bf8 F src/insert.c 764300a0bd8074a2174946c0bf8a550bd833397a F src/main.c ff7c05ef88fa1374e5540ce20173ae8e1836f8a4 F src/md5.c fe4f9c9c6f71dfc26af8da63e4d04489b1430565 -F src/os.c a099c7058e79f86edce9ca1f812078cdabe47a2c +F src/os.c 2c26f354c4bbe94ba4d6e1f04289c63bc1fdb87c F src/os.h 3009379b06941e7796a9812d1b6cbc59b26248c8 F src/pager.c 592e5931fdc65e952a6c3e152bc822580856532a F src/pager.h 6991c9c2dc5e4c7f2df4d4ba47d1c6458f763a32 @@ -149,7 +149,7 @@ F www/speed.tcl a20a792738475b68756ea7a19321600f23d1d803 F www/sqlite.tcl ae3dcfb077e53833b59d4fcc94d8a12c50a44098 F www/tclsqlite.tcl 1db15abeb446aad0caf0b95b8b9579720e4ea331 F www/vdbe.tcl 2013852c27a02a091d39a766bc87cff329f21218 -P 6c0f44bd6374010f7a4a091e585eb36e0665f96f -R 5d988e98e73febc16900dcc2d7b1140f -U drh -Z 4347cb15b61079c5bf526a0f73fa4ac4 +P d87a886d8f63f54466848151e2b0e8565b338593 +R bf058781dafbb0c6ad71e236c2683985 +U mike +Z 02abffa2bb18c0118ab5f6d1ca430ce7 diff --git a/manifest.uuid b/manifest.uuid index fb484560aa..fe6ca9e26b 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -d87a886d8f63f54466848151e2b0e8565b338593 \ No newline at end of file +83add34f64895a4b465881213eba82f3b1f5c964 \ No newline at end of file diff --git a/src/os.c b/src/os.c index 7aaf7362f9..43374f9f86 100644 --- a/src/os.c +++ b/src/os.c @@ -492,7 +492,7 @@ int sqliteOsRead(OsFile *id, void *pBuf, int amt){ if( !ReadFile(id->h, pBuf, amt, &got, 0) ){ got = 0; } - if( got==amt ){ + if( (int)got==amt ){ return SQLITE_OK; }else{ 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 ** 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 ** 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. @@ -639,6 +693,7 @@ int sqliteOsFileSize(OsFile *id, int *pSize){ ** ** Return SQLITE_OK on success and SQLITE_BUSY on failure. */ + int sqliteOsReadLock(OsFile *id){ #if OS_UNIX int rc; @@ -674,11 +729,12 @@ int sqliteOsReadLock(OsFile *id){ }else{ int lk = (sqliteRandomInteger() & 0x7ffffff)%MX_LOCKBYTE + 1; int res; - if( (res = LockFile(id->h, 0, 0, 1, 0))!=0 ){ - UnlockFile(id->h, 1, 0, MX_LOCKBYTE, 0); - res = LockFile(id->h, lk, 0, 1, 0); - UnlockFile(id->h, 0, 0, 1, 0); - } + + synclock(id->h); + if (id->locked<0) mkunlock(id->h,1,MX_LOCKBYTE); // release write lock if we have it + res=mklock(id->h,lk,1); + syncunlock(id->h); + if( res ){ id->locked = lk; rc = SQLITE_OK; @@ -722,15 +778,13 @@ int sqliteOsWriteLock(OsFile *id){ rc = SQLITE_OK; }else{ int res; - if( (res = LockFile(id->h, 0, 0, 1, 0))!=0 ){ - if( id->locked==0 || UnlockFile(id->h, id->locked, 0, 1, 0) ){ - res = LockFile(id->h, 1, 0, MX_LOCKBYTE, 0); - }else{ - res = 0; - } - UnlockFile(id->h, 0, 0, 1, 0); - } - if( res ){ + + synclock(id->h); + if (id->locked>0) mkunlock(id->h,id->locked,1); // release read lock + res=mklock(id->h,1,MX_LOCKBYTE); + syncunlock(id->h); + + if(res){ id->locked = -1; rc = SQLITE_OK; }else{ @@ -772,18 +826,13 @@ int sqliteOsUnlock(OsFile *id){ #endif #if OS_WIN int rc; - if( id->locked==0 ){ - rc = SQLITE_OK; - }else if( id->locked<0 ){ - UnlockFile(id->h, 1, 0, MX_LOCKBYTE, 0); - rc = SQLITE_OK; - id->locked = 0; - }else{ - UnlockFile(id->h, id->locked, 0, 1, 0); - rc = SQLITE_OK; - id->locked = 0; + if(id->locked<0 ) { + mkunlock(id->h,1,MX_LOCKBYTE); + }else if (id->locked>0) { + mkunlock(id->h,id->locked,1); } - return rc; + id->locked = 0; + return SQLITE_OK; #endif }