Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Implement probabilistic reader/writer locks under windows so that windows can have multiple simultaneous readers. (CVS 714) |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
2127de3f03537ef2f18120e773f7603e |
User & Date: | drh 2002-08-14 12:56:55.000 |
Context
2002-08-14
| ||
23:18 | Fix for ticket #134: Change the lemon.c sources to work around a problem with the AIX C compiler. (CVS 715) (check-in: 07f6020bb5 user: drh tags: trunk) | |
12:56 | Implement probabilistic reader/writer locks under windows so that windows can have multiple simultaneous readers. (CVS 714) (check-in: 2127de3f03 user: drh tags: trunk) | |
03:03 | Disable sorting by indices if there is a COLLATE subclause in the ORDER BY clause. (CVS 713) (check-in: 2438da791a user: drh tags: trunk) | |
Changes
Changes to src/os.c.
︙ | ︙ | |||
575 576 577 578 579 580 581 582 583 584 585 586 587 588 | #if OS_WIN SimulateIOError(SQLITE_IOERR); *pSize = GetFileSize(id->h, 0); return SQLITE_OK; #endif } /* ** Change the status of the lock on the file "id" to be a readlock. ** If the file was write locked, then this reduces the lock to a read. ** If the file was read locked, then this acquires a new read lock. ** ** Return SQLITE_OK on success and SQLITE_BUSY on failure. */ | > > > > > > > > > > > > > > > > > > > > > > > > > > > | 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 | #if OS_WIN SimulateIOError(SQLITE_IOERR); *pSize = GetFileSize(id->h, 0); return SQLITE_OK; #endif } /* ** Windows file locking notes: ** ** We cannot use LockFileEx() or UnlockFileEx() because those functions ** are not available under Win95/98/ME. So we use only LockFile() and ** UnlockFile(). ** ** A read lock is obtained by locking a single random byte in the ** range of 1 to MX_LOCKBYTE. The lock byte is obtained at random so ** two separate readers can probably access the file at the same time, ** unless they are unlucky and choose the same lock byte. A write lock ** is obtained by locking all bytes in the range of 1 to MX_LOCKBYTE. ** There can only be one writer. ** ** A lock is obtained on byte 0 before acquiring either a read lock or ** a write lock. This prevents two processes from attempting to get a ** lock at a same time. The semantics of sqliteOsReadLock() require that ** if there is already a write lock, that lock is converted into a read ** lock atomically. The lock on byte 0 allows us to drop the old write ** lock and get the read lock without another process jumping into the ** middle and messing us up. The same argument applies to sqliteOsWriteLock(). ** ** There are a finite number of read locks under windows. That number ** is determined by the following variable: */ #define MX_LOCKBYTE 10240 /* ** Change the status of the lock on the file "id" to be a readlock. ** If the file was write locked, then this reduces the lock to a read. ** If the file was read locked, then this acquires a new read lock. ** ** Return SQLITE_OK on success and SQLITE_BUSY on failure. */ |
︙ | ︙ | |||
612 613 614 615 616 617 618 | rc = SQLITE_BUSY; } sqliteOsLeaveMutex(); return rc; #endif #if OS_WIN int rc; | | > > > > > > | > > > | < | | > | 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 | rc = SQLITE_BUSY; } sqliteOsLeaveMutex(); return rc; #endif #if OS_WIN int rc; if( id->locked>0 ){ rc = SQLITE_OK; }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); } if( res ){ id->locked = lk; rc = SQLITE_OK; }else{ rc = SQLITE_BUSY; } } return rc; #endif } /* ** Change the lock status to be an exclusive or write lock. Return |
︙ | ︙ | |||
652 653 654 655 656 657 658 | rc = SQLITE_BUSY; } sqliteOsLeaveMutex(); return rc; #endif #if OS_WIN int rc; | | > > | > > > | > > > > | > | | > | 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 | rc = SQLITE_BUSY; } sqliteOsLeaveMutex(); return rc; #endif #if OS_WIN int rc; if( id->locked<0 ){ 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 ){ id->locked = -1; rc = SQLITE_OK; }else{ rc = SQLITE_BUSY; } } return rc; #endif } /* ** Unlock the given file descriptor. If the file descriptor was |
︙ | ︙ | |||
695 696 697 698 699 700 701 | } sqliteOsLeaveMutex(); id->locked = 0; return rc; #endif #if OS_WIN int rc; | | > | > | > | 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 | } sqliteOsLeaveMutex(); id->locked = 0; return rc; #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; } return rc; #endif } /* ** Get information to seed the random number generator. |
︙ | ︙ |
Changes to src/os.h.
︙ | ︙ | |||
53 54 55 56 57 58 59 | #endif #if OS_WIN #include <windows.h> #include <winbase.h> typedef struct OsFile OsFile; struct OsFile { | | | | 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 | #endif #if OS_WIN #include <windows.h> #include <winbase.h> typedef struct OsFile OsFile; struct OsFile { HANDLE h; /* Handle for accessing the file */ int locked; /* 0: unlocked, <0: write lock, >0: read lock */ }; # define SQLITE_TEMPNAME_SIZE (MAX_PATH+50) # define SQLITE_MIN_SLEEP_MS 1 #endif int sqliteOsDelete(const char*); int sqliteOsFileExists(const char*); |
︙ | ︙ |
Changes to test/sort.test.
1 2 3 4 5 6 7 8 9 10 11 12 13 | # 2001 September 15 # # The author disclaims copyright to this source code. In place of # a legal notice, here is a blessing: # # May you do good and not evil. # May you find forgiveness for yourself and forgive others. # May you share freely, never taking more than you give. # #*********************************************************************** # This file implements regression tests for SQLite library. The # focus of this file is testing the CREATE TABLE statement. # | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | # 2001 September 15 # # The author disclaims copyright to this source code. In place of # a legal notice, here is a blessing: # # May you do good and not evil. # May you find forgiveness for yourself and forgive others. # May you share freely, never taking more than you give. # #*********************************************************************** # This file implements regression tests for SQLite library. The # focus of this file is testing the CREATE TABLE statement. # # $Id: sort.test,v 1.6 2002/08/14 12:56:56 drh Exp $ set testdir [file dirname $argv0] source $testdir/tester.tcl # Create a bunch of data to sort against # do_test sort-1.0 { |
︙ | ︙ | |||
207 208 209 210 211 212 213 | } } {x5.0e10 x2.7 x11 x1.6 x01234567890123456789 x0.0013442 x-4221 x-4.0e9 x-3.141592653 x-2b x-2.15 x-123} do_test sort-4.8 { execsql { SELECT substr(v,2,99) FROM t1 ORDER BY 1; } } {-123 -2.15 -2b -3.141592653 -4.0e9 -4221 0.0013442 01234567890123456789 1.6 11 2.7 5.0e10} | | | | < > | | 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 | } } {x5.0e10 x2.7 x11 x1.6 x01234567890123456789 x0.0013442 x-4221 x-4.0e9 x-3.141592653 x-2b x-2.15 x-123} do_test sort-4.8 { execsql { SELECT substr(v,2,99) FROM t1 ORDER BY 1; } } {-123 -2.15 -2b -3.141592653 -4.0e9 -4221 0.0013442 01234567890123456789 1.6 11 2.7 5.0e10} #do_test sort-4.9 { # execsql { # SELECT substr(v,2,99)+0.0 FROM t1 ORDER BY 1; # } #} {-4000000000 -4221 -123 -3.141592653 -2.15 -2 0.0013442 1.6 2.7 11 50000000000 1.23456789012346e+18} finish_test |
Changes to www/faq.tcl.
1 2 3 | # # Run this script to generated a faq.html output file # | | | 1 2 3 4 5 6 7 8 9 10 11 | # # Run this script to generated a faq.html output file # set rcsid {$Id: faq.tcl,v 1.16 2002/08/14 12:56:56 drh Exp $} puts {<html> <head> <title>SQLite Frequently Asked Questions</title> </head> <body bgcolor="white"> <h1 align="center">Frequently Asked Questions</h1> |
︙ | ︙ | |||
165 166 167 168 169 170 171 | } faq { Can multiple applications or multiple instances of the same application access a single database file at the same time? } { <p>Multiple processes can have the same database open at the same | | | > > > | > | > > | > > | | 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 | } faq { Can multiple applications or multiple instances of the same application access a single database file at the same time? } { <p>Multiple processes can have the same database open at the same time. Multiple processes can be doing a SELECT at the same time. But only one process can be making changes to the database at once.</p> <p>Win95/98/ME lacks support for reader/writer locks in the operating system. Prior to version 2.7.0, this meant that under windows you could only have a single process reading the database at one time. This problem was resolved in version 2.7.0 by implementing a user-space probabilistic reader/writer locking strategy in the windows interface code file. Windows now works like Unix in allowing multiple simultaneous readers.</p> <p>The locking mechanism used to control simultaneous access might not work correctly if the database file is kept on an NFS filesystem. 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> <p>Locking in SQLite is very course-grained. SQLite locks the entire database. Big database servers (PostgreSQL, Oracle, etc.) generally have finer grained locking, such as locking on a single table or a single row within a table. If you have a massively parallel database application, you should consider using a big database server instead of SQLite.</p> <p>When SQLite tries to access a file that is locked by another process, the default behavior is to return SQLITE_BUSY. You can |
︙ | ︙ |