1
0
mirror of https://github.com/sqlite/sqlite.git synced 2025-10-27 08:52:26 +03:00

Do not require a RESERVED lock when transitioning from SHARED to EXCLUSIVE. (CVS 1542)

FossilOrigin-Name: 4dfdea7373f3471d17498da3d6c3aaf926a72d4b
This commit is contained in:
drh
2004-06-08 00:47:47 +00:00
parent 3f41e976e8
commit b3e043463d
4 changed files with 73 additions and 54 deletions

View File

@@ -686,15 +686,17 @@ int sqlite3OsCheckWriteLock(OsFile *id){
** (3) PENDING_LOCK
** (4) EXCLUSIVE_LOCK
**
** Locks are are hierarchical. Getting a lock N implies getting all locks
** N-1, N-2, N-3, .... So, for example, getting a PENDING lock
** implies a SHARED and a RESERVED lock. This routine adds locks one
** at a time until the desired lock is acheived. A locking failure might
** occur at any point. When a failure occurs intermediate locks are
** retained. For example, if a SHARED lock is held and this routine
** is called with EXCLUSIVE, it might obtain a RESERVED and PENDING lock
** but fail to get the EXCLUSIVE lock. In that case, the file would be
** left in the PENDING lock state - it does not revert to SHARED.
** Sometimes when requesting one lock state, additional lock states
** are inserted in between. The locking might fail on one of the later
** transitions leaving the lock state different from what it started but
** still short of its goal. The following chart shows the allowed
** transitions and the inserted intermediate states:
**
** UNLOCKED -> SHARED
** SHARED -> RESERVED
** SHARED -> (PENDING) -> EXCLUSIVE
** RESERVED -> (PENDING) -> EXCLUSIVE
** PENDING -> EXCLUSIVE
**
** This routine will only increase a lock. The sqlite3OsUnlock() routine
** erases all locks at once and returns us immediately to locking level 0.
@@ -718,20 +720,15 @@ int sqlite3OsLock(OsFile *id, int locktype){
return SQLITE_OK;
}
/* Make sure locking is sequential. In other words, make sure we have
** SHARED before trying for RESERVED, and that we have RESERVED before
** trying for PENDING, and that we have PENDING before trying for
** EXCLUSIVE.
/* Make sure the locking sequence is correct
*/
while( locktype>id->locktype+1 ){
rc = sqlite3OsLock(id, id->locktype+1);
if( rc!=SQLITE_OK ){
return rc;
}
}
assert( locktype==id->locktype+1 );
assert( id->locktype!=NO_LOCK || locktype==SHARED_LOCK );
assert( locktype!=PENDING_LOCK );
assert( locktype!=RESERVED_LOCK || id->locktype==SHARED_LOCK );
sqlite3OsEnterMutex(); /* Needed because pLock is shared across threads */
/* This mutex is needed because id->pLock is shared across threads
*/
sqlite3OsEnterMutex();
/* If some thread using this PID has a lock via a different OsFile*
** handle that precludes the requested lock, return BUSY.