Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Bug fix in the unix locking code. (CVS 1574) |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
dcad244f58453d23f2bcb749dcea0774 |
User & Date: | drh 2004-06-12 02:17:15.000 |
Context
2004-06-12
| ||
09:25 | (1) Modifications to the user-function interface and (2) Internal changes to automatically created indices. (CVS 1575) (check-in: 5903f53828 user: danielk1977 tags: trunk) | |
02:17 | Bug fix in the unix locking code. (CVS 1574) (check-in: dcad244f58 user: drh tags: trunk) | |
01:43 | Change prototype for busy callbacks to "int xBusy(void *, int);" (CVS 1573) (check-in: 4f1cfca5ca user: danielk1977 tags: trunk) | |
Changes
Changes to src/os_unix.c.
︙ | ︙ | |||
729 730 731 732 733 734 735 | sqlite3OsEnterMutex(); /* If some thread using this PID has a lock via a different OsFile* ** handle that precludes the requested lock, return BUSY. */ if( (id->locktype!=pLock->locktype && (pLock->locktype>=PENDING_LOCK || locktype>SHARED_LOCK)) | < | 729 730 731 732 733 734 735 736 737 738 739 740 741 742 | sqlite3OsEnterMutex(); /* If some thread using this PID has a lock via a different OsFile* ** handle that precludes the requested lock, return BUSY. */ if( (id->locktype!=pLock->locktype && (pLock->locktype>=PENDING_LOCK || locktype>SHARED_LOCK)) ){ rc = SQLITE_BUSY; goto end_lock; } /* If a SHARED lock is requested, and some thread using this PID already ** has a SHARED or RESERVED lock, then increment reference counts and |
︙ | ︙ | |||
753 754 755 756 757 758 759 | id->pOpen->nLock++; goto end_lock; } lock.l_len = 1L; lock.l_whence = SEEK_SET; | | | > | < | | < < < > > > > > > > > > > > > > | < < < > > > | 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 | id->pOpen->nLock++; goto end_lock; } lock.l_len = 1L; lock.l_whence = SEEK_SET; /* A PENDING lock is needed before acquiring a SHARED lock and before ** acquiring an EXCLUSIVE lock. For the SHARED lock, the PENDING will ** be released. */ if( locktype==SHARED_LOCK || (locktype==EXCLUSIVE_LOCK && id->locktype<PENDING_LOCK) ){ lock.l_type = F_RDLCK; lock.l_start = PENDING_BYTE; s = fcntl(id->h, F_SETLK, &lock); if( s ){ rc = (errno==EINVAL) ? SQLITE_NOLFS : SQLITE_BUSY; goto end_lock; } } /* If control gets to this point, then actually go ahead and make ** operating system calls for the specified lock. */ if( locktype==SHARED_LOCK ){ assert( pLock->cnt==0 ); assert( pLock->locktype==0 ); /* Now get the read-lock */ lock.l_start = SHARED_FIRST; lock.l_len = SHARED_SIZE; s = fcntl(id->h, F_SETLK, &lock); /* Drop the temporary PENDING lock */ lock.l_start = PENDING_BYTE; lock.l_len = 1L; lock.l_type = F_UNLCK; fcntl(id->h, F_SETLK, &lock); if( s ){ rc = (errno==EINVAL) ? SQLITE_NOLFS : SQLITE_BUSY; }else{ id->locktype = SHARED_LOCK; id->pOpen->nLock++; pLock->cnt = 1; } }else if( locktype==EXCLUSIVE_LOCK && pLock->cnt>1 ){ /* We are trying for an exclusive lock but another thread in this ** same process is still holding a shared lock. */ rc = SQLITE_BUSY; }else{ /* The request was for a RESERVED or EXCLUSIVE lock. It is ** assumed that there is a SHARED or greater lock on the file ** already. */ assert( 0!=id->locktype ); lock.l_type = F_WRLCK; switch( locktype ){ case RESERVED_LOCK: lock.l_start = RESERVED_BYTE; break; case EXCLUSIVE_LOCK: lock.l_start = SHARED_FIRST; lock.l_len = SHARED_SIZE; break; default: assert(0); } s = fcntl(id->h, F_SETLK, &lock); if( s ){ rc = (errno==EINVAL) ? SQLITE_NOLFS : SQLITE_BUSY; } } if( rc==SQLITE_OK ){ id->locktype = locktype; pLock->locktype = locktype; }else if( locktype==EXCLUSIVE_LOCK ){ id->locktype = PENDING_LOCK; pLock->locktype = PENDING_LOCK; } end_lock: sqlite3OsLeaveMutex(); TRACE4("LOCK %d %d %s\n", id->h, locktype, rc==SQLITE_OK ? "ok" : "failed"); return rc; } |
︙ | ︙ |
Changes to src/os_win.c.
︙ | ︙ | |||
416 417 418 419 420 421 422 423 424 425 426 427 428 429 | assert( locktype!=PENDING_LOCK ); assert( locktype!=RESERVED_LOCK || id->locktype==SHARED_LOCK ); /* Lock the PENDING_LOCK byte if we need to acquire a PENDING lock or ** a SHARED lock. If we are acquiring a SHARED lock, the acquisition of ** the PENDING_LOCK byte is temporary. */ if( id->locktype==NO_LOCK || (locktype==EXCLUSIVE_LOCK && id->locktype==RESERVED_LOCK) ){ int cnt = 3; while( cnt-->0 && (res = LockFile(id->h, PENDING_BYTE, 0, 1, 0))==0 ){ /* Try 3 times to get the pending lock. The pending lock might be ** held by another reader process who will release it momentarily. | > | 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 | assert( locktype!=PENDING_LOCK ); assert( locktype!=RESERVED_LOCK || id->locktype==SHARED_LOCK ); /* Lock the PENDING_LOCK byte if we need to acquire a PENDING lock or ** a SHARED lock. If we are acquiring a SHARED lock, the acquisition of ** the PENDING_LOCK byte is temporary. */ newLocktype = id->locktype; if( id->locktype==NO_LOCK || (locktype==EXCLUSIVE_LOCK && id->locktype==RESERVED_LOCK) ){ int cnt = 3; while( cnt-->0 && (res = LockFile(id->h, PENDING_BYTE, 0, 1, 0))==0 ){ /* Try 3 times to get the pending lock. The pending lock might be ** held by another reader process who will release it momentarily. |
︙ | ︙ | |||
532 533 534 535 536 537 538 | ** the requested locking level, this routine is a no-op. ** ** It is not possible for this routine to fail. */ int sqlite3OsUnlock(OsFile *id, int locktype){ int rc, type; assert( locktype<=SHARED_LOCK ); | | | 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 | ** the requested locking level, this routine is a no-op. ** ** It is not possible for this routine to fail. */ int sqlite3OsUnlock(OsFile *id, int locktype){ int rc, type; assert( locktype<=SHARED_LOCK ); TRACE5("UNLOCK %d to %d was %d(%d)\n", id->h, locktype, id->locktype, id->sharedLockByte); type = id->locktype; if( type>=EXCLUSIVE_LOCK ){ UnlockFile(id->h, SHARED_FIRST, 0, SHARED_SIZE, 0); } if( type>=RESERVED_LOCK ){ UnlockFile(id->h, RESERVED_BYTE, 0, 1, 0); |
︙ | ︙ |
Changes to test/attach2.test.
︙ | ︙ | |||
8 9 10 11 12 13 14 | # May you share freely, never taking more than you give. # #*********************************************************************** # This file implements regression tests for SQLite library. The # focus of this script is testing the ATTACH and DETACH commands # and related functionality. # | | | 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | # May you share freely, never taking more than you give. # #*********************************************************************** # This file implements regression tests for SQLite library. The # focus of this script is testing the ATTACH and DETACH commands # and related functionality. # # $Id: attach2.test,v 1.16 2004/06/12 02:17:15 drh Exp $ # set testdir [file dirname $argv0] source $testdir/tester.tcl # Ticket #354 |
︙ | ︙ | |||
259 260 261 262 263 264 265 | INSERT INTO t1 VALUES(1, 2) } } {1 {database is locked}} lock_status 4.9.1 db {main shared temp reserved file2 shared} lock_status 4.9.2 db2 {main reserved temp reserved file2 reserved} | < | > > | | 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 | INSERT INTO t1 VALUES(1, 2) } } {1 {database is locked}} lock_status 4.9.1 db {main shared temp reserved file2 shared} lock_status 4.9.2 db2 {main reserved temp reserved file2 reserved} btree_breakpoint do_test attach2-4.10 { # We cannot commit db2 while db is holding a read-lock catchsql {COMMIT} db2 } {1 {database is locked}} lock_status 4.10.1 db {main shared temp reserved file2 shared} lock_status 4.10.2 db2 {main pending temp reserved file2 reserved} set sqlite_os_trace 0 btree_breakpoint do_test attach2-4.11 { # db is able to commit. catchsql {COMMIT} } {0 {}} lock_status 4.11.1 db {main unlocked temp unlocked file2 unlocked} lock_status 4.11.2 db2 {main pending temp reserved file2 reserved} do_test attach2-4.12 { # Now we can commit db2 catchsql {COMMIT} db2 } {0 {}} lock_status 4.12.1 db {main unlocked temp unlocked file2 unlocked} |
︙ | ︙ |