internal RC querySharedCacheTableLock(Pgno iTab, BtreeLock.LOCK eLock)
internal RC setSharedCacheTableLock(Pgno tableID, LOCK eLock)
Debug.Assert(eLock == LOCK.READ || eLock == LOCK.WRITE);
Debug.Assert(DB != null);
// A connection with the read-uncommitted flag set will never try to obtain a read-lock using this function. The only read-lock obtained
// by a connection in read-uncommitted mode is on the sqlite_master table, and that lock is obtained in BtreeBeginTrans().
Debug.Assert((DB.flags & sqlite3b.SQLITE.ReadUncommitted) == 0 || eLock == LOCK.WRITE);
// This function should only be called on a sharable b-tree after it has been determined that no other b-tree holds a conflicting lock.
Debug.Assert(querySharedCacheTableLock(tableID, eLock) == RC.OK);
// First search the list for an existing lock on this table.
BtreeLock pLock = null;
for (var @lock = Shared.Locks; @lock != null; @lock = @lock.Next)
if (@lock.TableID == tableID && @lock.Tree == this)
pLock = @lock;
// If the above search did not find a BtLock struct associating Btree p with table iTable, allocate one and link it into the list.
if (pLock == null)
var shared = Shared;
pLock = new BtreeLock();
pLock.TableID = tableID;
pLock.Tree = this;
pLock.Next = shared.Locks;
shared.Locks = pLock;
// Set the BtLock.eLock variable to the maximum of the current lock and the requested lock. This means if a write-lock was already held
// and a read-lock requested, we don't incorrectly downgrade the lock.
Debug.Assert(LOCK.WRITE > LOCK.READ);
if (eLock > pLock.Lock)
pLock.Lock = eLock;