]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
fix for locking in Windows (CVS 760)
authormike <mike@noemail.net>
Thu, 17 Oct 2002 00:38:54 +0000 (00:38 +0000)
committermike <mike@noemail.net>
Thu, 17 Oct 2002 00:38:54 +0000 (00:38 +0000)
FossilOrigin-Name: 83add34f64895a4b465881213eba82f3b1f5c964

manifest
manifest.uuid
src/os.c

index 870bd2561e490b56d9507b142f37908bd95a765f..1ab61d3fde4d4fdff19e2de41d4221805a67d7cc 100644 (file)
--- 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
index fb484560aaae67355d80fea1c7cec4daa38cf418..fe6ca9e26b348a9ab46dee3c233983fefbb51739 100644 (file)
@@ -1 +1 @@
-d87a886d8f63f54466848151e2b0e8565b338593
\ No newline at end of file
+83add34f64895a4b465881213eba82f3b1f5c964
\ No newline at end of file
index 7aaf7362f94c09e68e505775452b69683c275048..43374f9f867b497829798049e073b5a3e1f2d06e 100644 (file)
--- 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
 }