Modify the windows locking code so that it works correctly for a database
being shared between Win95/98/ME and WinNT/2K/XP systems. Ticket #310. (CVS 988) FossilOrigin-Name: 8c402db7e0745622d9950e5ca5d4d8e933da436c
This commit is contained in:
parent
124e74e685
commit
9ac717d7f6
18
manifest
18
manifest
@ -1,5 +1,5 @@
|
||||
C Added\stypeof()\soperator.\nMinor\sadditions\sfor\sATTACH/DETACH.\s(CVS\s987)
|
||||
D 2003-05-29T04:21:39
|
||||
C Modify\sthe\swindows\slocking\scode\sso\sthat\sit\sworks\scorrectly\sfor\sa\sdatabase\r\nbeing\sshared\sbetween\sWin95/98/ME\sand\sWinNT/2K/XP\ssystems.\s\sTicket\s#310.\s(CVS\s988)
|
||||
D 2003-05-29T17:43:08
|
||||
F Makefile.in 1ff85c27d4350c74118341024e8a4fb2a04a3a43
|
||||
F Makefile.linux-gcc b86a99c493a5bfb402d1d9178dcdc4bd4b32f906
|
||||
F README f1de682fbbd94899d50aca13d387d1b3fd3be2dd
|
||||
@ -35,7 +35,7 @@ F src/hash.h cd0433998bc1a3759d244e1637fe5a3c13b53bf8
|
||||
F src/insert.c 2f26b95cc1055062411cbdea06e2e1b40a8b0d8d
|
||||
F src/main.c 717aaf32d468667dabeaec80054e11bfdb6309b6
|
||||
F src/md5.c fe4f9c9c6f71dfc26af8da63e4d04489b1430565
|
||||
F src/os.c 94b618c0c0a76210e53857d77c96d2f042dc33b1
|
||||
F src/os.c 080238f03015057879cdf53bc4af9e497f2ba724
|
||||
F src/os.h 9e5bbddff123187295e3d00d49af06192cd1cd49
|
||||
F src/pager.c 51fdfda63e2d8c01fff8f7fe0c49f2636d5b1321
|
||||
F src/pager.h 5da62c83443f26b1792cfd72c96c422f91aadd31
|
||||
@ -47,7 +47,7 @@ F src/select.c 15d921308065c9320363af6f43c01d9f09ea7118
|
||||
F src/shell.c b63089a91d6584df06eaa2e53ea1150c68ab1e61
|
||||
F src/shell.tcl 27ecbd63dd88396ad16d81ab44f73e6c0ea9d20e
|
||||
F src/sqlite.h.in eec06462cba262c0ee03f38462a18a4bc66dda4e
|
||||
F src/sqliteInt.h 3ba355793a1e0b891cfa414901759189c9287a18
|
||||
F src/sqliteInt.h e5ae70c84c07100561eff4ef88ac7b5f1b4dff1e
|
||||
F src/table.c 4301926464d88d2c2c7cd21c3360aa75bf068b95
|
||||
F src/tclsqlite.c 9e25f98f1765afa0716144ef57abda75c88f688d
|
||||
F src/test1.c 4596acd9d9f2a49fda0160a8a6dee5bfc7c6c325
|
||||
@ -151,7 +151,7 @@ F www/conflict.tcl 81dd21f9a679e60aae049e9dd8ab53d59570cda2
|
||||
F www/datatypes.tcl 0cb28565580554fa7e03e8fcb303e87ce57757ae
|
||||
F www/download.tcl 0932d7f4f0e8b2adbbd22fac73132f86e43ab4a9
|
||||
F www/dynload.tcl 02eb8273aa78cfa9070dd4501dca937fb22b466c
|
||||
F www/faq.tcl 12d1788d4abcfe1ff3054e17605df2418883bf6f
|
||||
F www/faq.tcl 88d3b95d9cd8e374772daa3a646c4d107e7f3e9b
|
||||
F www/fileformat.tcl d9b586416c0d099b82e02e469d532c9372f98f3f
|
||||
F www/formatchng.tcl cbaf0f410096c71f86a7537cf9249fa04b9a659c
|
||||
F www/index.tcl a34315cada875af0b098b4c45981da8ab33fe7b6
|
||||
@ -165,7 +165,7 @@ F www/speed.tcl cb4c10a722614aea76d2c51f32ee43400d5951be
|
||||
F www/sqlite.tcl 4bd1729e320f5fa9125f0022b281fbe839192125
|
||||
F www/tclsqlite.tcl 1db15abeb446aad0caf0b95b8b9579720e4ea331
|
||||
F www/vdbe.tcl 2013852c27a02a091d39a766bc87cff329f21218
|
||||
P e8566cf5a381fa7655caacbc0fe95091e1137fea
|
||||
R 2370f3a91a8462e6af77d63e50ad9dc5
|
||||
U jplyon
|
||||
Z b0d55a69cad4bca6e8fe74221533622d
|
||||
P 8b8fa0fff26107912f0bec4e44df207c7885e273
|
||||
R b9d0e8972fcc9a231c0902a3a73faac1
|
||||
U drh
|
||||
Z 03fcc024f3cf3df89cb775ce044ef1b0
|
||||
|
@ -1 +1 @@
|
||||
8b8fa0fff26107912f0bec4e44df207c7885e273
|
||||
8c402db7e0745622d9950e5ca5d4d8e933da436c
|
64
src/os.c
64
src/os.c
@ -992,10 +992,18 @@ int sqliteOsFileSize(OsFile *id, off_t *pSize){
|
||||
/*
|
||||
** Return true (non-zero) if we are running under WinNT, Win2K or WinXP.
|
||||
** Return false (zero) for Win95, Win98, or WinME.
|
||||
**
|
||||
** Here is an interesting observation: Win95, Win98, and WinME lack
|
||||
** the LockFileEx() API. But we can still statically link against that
|
||||
** API as long as we don't call it win running Win95/98/ME. A call to
|
||||
** this routine is used to determine if the host is Win95/98/ME or
|
||||
** WinNT/2K/XP so that we will know whether or not we can safely call
|
||||
** the LockFileEx() API.
|
||||
*/
|
||||
int isNT(void){
|
||||
static osType = 0; /* 0=unknown 1=win95 2=winNT */
|
||||
if( osType==0 ){
|
||||
int tmpOsType;
|
||||
OSVERSIONINFO sInfo;
|
||||
sInfo.dwOSVersionInfoSize = sizeof(sInfo);
|
||||
GetVersionEx(&sInfo);
|
||||
@ -1006,10 +1014,10 @@ int isNT(void){
|
||||
#endif
|
||||
|
||||
/*
|
||||
** Windows file locking notes: [the same/equivalent applies to MacOS]
|
||||
** Windows file locking notes: [similar issues apply to MacOS]
|
||||
**
|
||||
** We cannot use LockFileEx() or UnlockFileEx() because those functions
|
||||
** are not available under Win95/98/ME. So we use only LockFile() and
|
||||
** We cannot use LockFileEx() or UnlockFileEx() on Win95/98/ME because
|
||||
** those functions are not available. So we use only LockFile() and
|
||||
** UnlockFile().
|
||||
**
|
||||
** LockFile() prevents not just writing but also reading by other processes.
|
||||
@ -1034,6 +1042,14 @@ int isNT(void){
|
||||
** another process jumping into the middle and messing us up. The same
|
||||
** argument applies to sqliteOsWriteLock().
|
||||
**
|
||||
** On WinNT/2K/XP systems, LockFileEx() and UnlockFileEx() are available,
|
||||
** which means we can use reader/writer locks. When reader writer locks
|
||||
** are used, the lock is placed on the same range of bytes that is used
|
||||
** for probabilistic locking in Win95/98/ME. Hence, the locking scheme
|
||||
** will support two or more Win95 readers or two or more WinNT readers.
|
||||
** But a single Win95 reader will lock out all WinNT readers and a single
|
||||
** WinNT reader will lock out all other Win95 readers.
|
||||
**
|
||||
** Note: On MacOS we use the resource fork for locking.
|
||||
**
|
||||
** The following #defines specify the range of bytes used for locking.
|
||||
@ -1096,14 +1112,22 @@ int sqliteOsReadLock(OsFile *id){
|
||||
int lk = (sqliteRandomInteger() & 0x7ffffff)%N_LOCKBYTE+1;
|
||||
int res;
|
||||
int cnt = 100;
|
||||
int page = isNT() ? 0xffffffff : 0;
|
||||
while( cnt-->0 && (res = LockFile(id->h, FIRST_LOCKBYTE, page, 1, 0))==0 ){
|
||||
while( cnt-->0 && (res = LockFile(id->h, FIRST_LOCKBYTE, 0, 1, 0))==0 ){
|
||||
Sleep(1);
|
||||
}
|
||||
if( res ){
|
||||
UnlockFile(id->h, FIRST_LOCKBYTE+1, page, N_LOCKBYTE, 0);
|
||||
res = LockFile(id->h, FIRST_LOCKBYTE+lk, page, 1, 0);
|
||||
UnlockFile(id->h, FIRST_LOCKBYTE, page, 1, 0);
|
||||
UnlockFile(id->h, FIRST_LOCKBYTE+1, 0, N_LOCKBYTE, 0);
|
||||
if( isNT() ){
|
||||
OVERLAPPED ovlp;
|
||||
ovlp.Offset = FIRST_LOCKBYTE+1;
|
||||
ovlp.OffsetHigh = 0;
|
||||
ovlp.hEvent = 0;
|
||||
res = LockFileEx(id->h, LOCKFILE_FAIL_IMMEDIATELY,
|
||||
0, N_LOCKBYTE, 0, &ovlp);
|
||||
}else{
|
||||
res = LockFile(id->h, FIRST_LOCKBYTE+lk, 0, 1, 0);
|
||||
}
|
||||
UnlockFile(id->h, FIRST_LOCKBYTE, 0, 1, 0);
|
||||
}
|
||||
if( res ){
|
||||
id->locked = lk;
|
||||
@ -1191,18 +1215,23 @@ int sqliteOsWriteLock(OsFile *id){
|
||||
}else{
|
||||
int res;
|
||||
int cnt = 100;
|
||||
int page = isNT() ? 0xffffffff : 0;
|
||||
while( cnt-->0 && (res = LockFile(id->h, FIRST_LOCKBYTE, page, 1, 0))==0 ){
|
||||
while( cnt-->0 && (res = LockFile(id->h, FIRST_LOCKBYTE, 0, 1, 0))==0 ){
|
||||
Sleep(1);
|
||||
}
|
||||
if( res ){
|
||||
if( id->locked==0
|
||||
|| UnlockFile(id->h, FIRST_LOCKBYTE + id->locked, page, 1, 0) ){
|
||||
res = LockFile(id->h, FIRST_LOCKBYTE+1, page, N_LOCKBYTE, 0);
|
||||
if( id->locked>0 ){
|
||||
if( isNT() ){
|
||||
UnlockFile(id->h, FIRST_LOCKBYTE+1, 0, N_LOCKBYTE, 0);
|
||||
}else{
|
||||
res = UnlockFile(id->h, FIRST_LOCKBYTE + id->locked, 0, 1, 0);
|
||||
}
|
||||
}
|
||||
if( res ){
|
||||
res = LockFile(id->h, FIRST_LOCKBYTE+1, 0, N_LOCKBYTE, 0);
|
||||
}else{
|
||||
res = 0;
|
||||
}
|
||||
UnlockFile(id->h, FIRST_LOCKBYTE, page, 1, 0);
|
||||
UnlockFile(id->h, FIRST_LOCKBYTE, 0, 1, 0);
|
||||
}
|
||||
if( res ){
|
||||
id->locked = -1;
|
||||
@ -1291,15 +1320,14 @@ int sqliteOsUnlock(OsFile *id){
|
||||
#endif
|
||||
#if OS_WIN
|
||||
int rc;
|
||||
int page = isNT() ? 0xffffffff : 0;
|
||||
if( id->locked==0 ){
|
||||
rc = SQLITE_OK;
|
||||
}else if( id->locked<0 ){
|
||||
UnlockFile(id->h, FIRST_LOCKBYTE+1, page, N_LOCKBYTE, 0);
|
||||
}else if( isNT() || id->locked<0 ){
|
||||
UnlockFile(id->h, FIRST_LOCKBYTE+1, 0, N_LOCKBYTE, 0);
|
||||
rc = SQLITE_OK;
|
||||
id->locked = 0;
|
||||
}else{
|
||||
UnlockFile(id->h, FIRST_LOCKBYTE+id->locked, page, 1, 0);
|
||||
UnlockFile(id->h, FIRST_LOCKBYTE+id->locked, 0, 1, 0);
|
||||
rc = SQLITE_OK;
|
||||
id->locked = 0;
|
||||
}
|
||||
|
@ -11,7 +11,7 @@
|
||||
*************************************************************************
|
||||
** Internal interface definitions for SQLite.
|
||||
**
|
||||
** @(#) $Id: sqliteInt.h,v 1.186 2003/05/17 19:04:04 drh Exp $
|
||||
** @(#) $Id: sqliteInt.h,v 1.187 2003/05/29 17:43:08 drh Exp $
|
||||
*/
|
||||
#include "config.h"
|
||||
#include "sqlite.h"
|
||||
@ -132,8 +132,13 @@ typedef unsigned INTPTR_TYPE uptr; /* Big enough to hold a pointer */
|
||||
** multi-megabyte records are OK. If your needs are different, you can
|
||||
** change this define and recompile to increase or decrease the record
|
||||
** size.
|
||||
**
|
||||
** The 16777198 is computed as follows: 238 bytes of payload on the
|
||||
** original pages plus 16448 overflow pages each holding 1020 bytes of
|
||||
** data.
|
||||
*/
|
||||
#define MAX_BYTES_PER_ROW 1048576
|
||||
/* #define MAX_BYTES_PER_ROW 1048576 */
|
||||
#define MAX_BYTES_PER_ROW 16777198
|
||||
|
||||
/*
|
||||
** If memory allocation problems are found, recompile with
|
||||
|
@ -1,7 +1,7 @@
|
||||
#
|
||||
# Run this script to generated a faq.html output file
|
||||
#
|
||||
set rcsid {$Id: faq.tcl,v 1.22 2003/05/03 19:04:04 drh Exp $}
|
||||
set rcsid {$Id: faq.tcl,v 1.23 2003/05/29 17:43:08 drh Exp $}
|
||||
|
||||
puts {<html>
|
||||
<head>
|
||||
@ -199,10 +199,15 @@ faq {
|
||||
|
||||
<p>The locking mechanism used to control simultaneous access might
|
||||
not work correctly if the database file is kept on an NFS filesystem.
|
||||
This is because file locking is broken on some NFS implementations.
|
||||
You should avoid putting SQLite database files on NFS if multiple
|
||||
processes might try to access the file at the same time. On Windows,
|
||||
Microsoft's documentation says that locking may not work under FAT
|
||||
filesystems if you are not running the Share.exe daemon.</p>
|
||||
filesystems if you are not running the Share.exe daemon. People who
|
||||
have a lot of experience with Windows tell me that file locking of
|
||||
network files is very buggy and is not dependable. If what they
|
||||
say is true, sharing an SQLite database between two or more Windows
|
||||
machines might cause unexpected problems.</p>
|
||||
|
||||
<p>Locking in SQLite is very course-grained. SQLite locks the
|
||||
entire database. Big database servers (PostgreSQL, Oracle, etc.)
|
||||
|
Loading…
Reference in New Issue
Block a user