public virtual RC Unlock(LOCK locktype) { Debug.Assert(locktype <= LOCK.SHARED); #if DEBUG SysEx.OSTRACE("UNLOCK {0} to {1} was {2}({3})", S.GetHashCode(), locktype, this.Locktype, SharedLockByte); #endif var rc = RC.OK; var type = this.Locktype; if (type >= LOCK.EXCLUSIVE) { lockingStrategy.UnlockFile(this, SHARED_FIRST, SHARED_SIZE); if (locktype == LOCK.SHARED && getReadLock() == 0) { // This should never happen. We should always be able to reacquire the read lock rc = winLogError(RC.IOERR_UNLOCK, "winUnlock", Path); } } if (type >= LOCK.RESERVED) { try { lockingStrategy.UnlockFile(this, RESERVED_BYTE, 1); } catch (Exception) { } } if (locktype == LOCK.NO && type >= LOCK.SHARED) { unlockReadLock(); } if (type >= LOCK.PENDING) { try { lockingStrategy.UnlockFile(this, PENDING_BYTE, 1); } catch (Exception) { } } this.Locktype = locktype; return(rc); }
public int Chunk; // Chunk size configured by FCNTL_CHUNK_SIZE public void Clear() { S = null; Locktype = 0; SharedLockByte = 0; LastErrno = 0; _sectorSize = 0; }
public Button(Sprite sprite, MouseInput mouseInput) { _buttonSprite = sprite; _buttonSprite.BindParent(this); _mouseInput = mouseInput; _state = BUTTON_STATE.RELEASED; _selection = BUTTON_SELECT.NONE; _lock = LOCK.LOCKED; }
public Button(Sprite sprite, MouseInput mouseInput) { _buttonSprite = sprite; _buttonSprite.BindParent(this); _mouseInput = mouseInput; _state = BUTTON_STATE.RELEASED; _selection = BUTTON_SELECT.NONE; _lock = LOCK.LOCKED; }
static bool hasSharedCacheTableLock(Btree btree, Pid root, bool isIndex, LOCK lockType) { // If this database is not shareable, or if the client is reading and has the read-uncommitted flag set, then no lock is required. // Return true immediately. if (!btree.Sharable_ || (lockType == LOCK.READ && (btree.Ctx.Flags & BContext.FLAG.ReadUncommitted) != 0)) return true; // If the client is reading or writing an index and the schema is not loaded, then it is too difficult to actually check to see if // the correct locks are held. So do not bother - just return true. This case does not come up very often anyhow. var schema = btree.Bt.Schema; if (isIndex && (schema == null || (schema.Flags & SCHEMA_.SchemaLoaded) == 0)) return true; // Figure out the root-page that the lock should be held on. For table b-trees, this is just the root page of the b-tree being read or // written. For index b-trees, it is the root page of the associated table. Pid table = 0; if (isIndex) throw new NotImplementedException(); //for (var p = sqliteHashFirst(schema.IdxHash); p != null; p = sqliteHashNext(p)) //{ // var idx = (Index)sqliteHashData(p); // if (idx.TID == (int)root) // table = idx.Table.TID; //} else table = root; // Search for the required lock. Either a write-lock on root-page iTab, a write-lock on the schema table, or (if the client is reading) a // read-lock on iTab will suffice. Return 1 if any of these are found. for (var lock_ = btree.Bt.Lock; lock_ != null; lock_ = lock_.Next) if (lock_.Btree == btree && (lock_.Table == table || (lock_.Lock == LOCK.WRITE && lock_.Table == 1)) && lock_.Lock >= lockType) return true; // Failed to find the required lock. return false; }
protected virtual void OnLock() { _lock = LOCK.LOCKED; OnDeselect(); }
static RC querySharedCacheTableLock(Btree p, Pid table, LOCK lock_) { return RC.OK; }
static RC querySharedCacheTableLock(Btree p, Pid table, LOCK lockType) { Debug.Assert(p.HoldsMutex()); Debug.Assert(lockType == LOCK.READ || lockType == LOCK.WRITE); Debug.Assert(p.Ctx != null); Debug.Assert((p.Ctx.Flags & BContext.FLAG.ReadUncommitted) == 0 || lockType == LOCK.WRITE || table == 1); // If requesting a write-lock, then the Btree must have an open write transaction on this file. And, obviously, for this to be so there // must be an open write transaction on the file itself. var bt = p.Bt; Debug.Assert(lockType == LOCK.READ || (p == bt.Writer && p.InTrans == TRANS.WRITE)); Debug.Assert(lockType == LOCK.READ || bt.InTransaction == TRANS.WRITE); // This routine is a no-op if the shared-cache is not enabled if (!p.Sharable_) return RC.OK; // If some other connection is holding an exclusive lock, the requested lock may not be obtained. if (bt.Writer != p && (bt.BtsFlags & BTS.EXCLUSIVE) != 0) { BContext.ConnectionBlocked(p.Ctx, bt.Writer.Ctx); return RC.LOCKED_SHAREDCACHE; } for (var iter = bt.Lock; iter != null; iter = iter.Next) { // The condition (pIter->eLock!=eLock) in the following if(...) statement is a simplification of: // // (eLock==WRITE_LOCK || pIter->eLock==WRITE_LOCK) // // since we know that if eLock==WRITE_LOCK, then no other connection may hold a WRITE_LOCK on any table in this file (since there can // only be a single writer). Debug.Assert(iter.Lock == LOCK.READ || iter.Lock == LOCK.WRITE); Debug.Assert(lockType == LOCK.READ || iter.Btree == p || iter.Lock == LOCK.READ); if (iter.Btree != p && iter.Table == table && iter.Lock != lockType) { BContext.ConnectionBlocked(p.Ctx, iter.Btree.Ctx); if (lockType == LOCK.WRITE) { Debug.Assert(p == bt.Writer); bt.BtsFlags |= BTS.PENDING; } return RC.LOCKED_SHAREDCACHE; } } return RC.OK; }
static RC setSharedCacheTableLock(Btree p, Pid table, LOCK lock_) { Debug.Assert(p.HoldsMutex()); Debug.Assert(lock_ == LOCK.READ || lock_ == LOCK.WRITE); Debug.Assert(p.Ctx != 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((p.Ctx.Flags & BContext.FLAG.ReadUncommitted) == 0 || lock_ == 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. var bt = p.Bt; Debug.Assert(p.Sharable_); Debug.Assert(RC.OK == querySharedCacheTableLock(p, table, lock_)); // First search the list for an existing lock on this table. BtLock newLock = null; for (var iter = bt.Lock; iter != null; iter = iter.Next) if (iter.Table == table && iter.Btree == p) { newLock = iter; break; } // 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 (newLock == null) { newLock = new BtLock(); newLock.Table = table; newLock.Btree = p; newLock.Next = bt.Lock; bt.Lock = newLock; } // 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 (lock_ > newLock.Lock) newLock.Lock = lock_; return RC.OK; }
public virtual RC Lock(LOCK locktype) { #if DEBUG SysEx.OSTRACE("LOCK {0} {1} was {2}({3})", S.GetHashCode(), locktype, this.Locktype, SharedLockByte); #endif // If there is already a lock of this type or more restrictive on the OsFile, do nothing. Don't use the end_lock: exit path, as sqlite3OsEnterMutex() hasn't been called yet. if (this.Locktype >= locktype) return RC.OK; // Make sure the locking sequence is correct Debug.Assert(this.Locktype != LOCK.NO || locktype == LOCK.SHARED); Debug.Assert(locktype != LOCK.PENDING); Debug.Assert(locktype != LOCK.RESERVED || this.Locktype == LOCK.SHARED); // 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. uint error = 0; var res = 1; // Result of a windows lock call var gotPendingLock = false; // True if we acquired a PENDING lock this time var newLocktype = this.Locktype; if (this.Locktype == LOCK.NO || (locktype == LOCK.EXCLUSIVE && this.Locktype == LOCK.RESERVED)) { res = 0; var cnt = 3; while (cnt-- > 0 && res == 0) try { lockingStrategy.LockFile(this, PENDING_BYTE, 1); res = 1; } catch (Exception) { // Try 3 times to get the pending lock. The pending lock might be held by another reader process who will release it momentarily. #if DEBUG SysEx.OSTRACE("could not get a PENDING lock. cnt={0}", cnt); #endif Thread.Sleep(1); } gotPendingLock = (res != 0); if (0 == res) error = (uint)Marshal.GetLastWin32Error(); } // Acquire a shared lock if (locktype == LOCK.SHARED && res != 0) { Debug.Assert(this.Locktype == LOCK.NO); res = getReadLock(); if (res != 0) newLocktype = LOCK.SHARED; else error = (uint)Marshal.GetLastWin32Error(); } // Acquire a RESERVED lock if (locktype == LOCK.RESERVED && res != 0) { Debug.Assert(this.Locktype == LOCK.SHARED); try { lockingStrategy.LockFile(this, RESERVED_BYTE, 1); newLocktype = LOCK.RESERVED; res = 1; } catch (Exception) { res = 0; error = (uint)Marshal.GetLastWin32Error(); } if (res != 0) newLocktype = LOCK.RESERVED; else error = (uint)Marshal.GetLastWin32Error(); } // Acquire a PENDING lock if (locktype == LOCK.EXCLUSIVE && res != 0) { newLocktype = LOCK.PENDING; gotPendingLock = false; } // Acquire an EXCLUSIVE lock if (locktype == LOCK.EXCLUSIVE && res != 0) { Debug.Assert(this.Locktype >= LOCK.SHARED); res = unlockReadLock(); #if DEBUG SysEx.OSTRACE("unreadlock = {0}", res); #endif try { lockingStrategy.LockFile(this, SHARED_FIRST, SHARED_SIZE); newLocktype = LOCK.EXCLUSIVE; res = 1; } catch (Exception) { res = 0; } if (res != 0) newLocktype = LOCK.EXCLUSIVE; else { error = (uint)Marshal.GetLastWin32Error(); #if DEBUG SysEx.OSTRACE("error-code = {0}", error); #endif getReadLock(); } } // If we are holding a PENDING lock that ought to be released, then release it now. if (gotPendingLock && locktype == LOCK.SHARED) lockingStrategy.UnlockFile(this, PENDING_BYTE, 1); // Update the state of the lock has held in the file descriptor then return the appropriate result code. var rc = RC.OK; if (res != 0) rc = RC.OK; else { #if DEBUG SysEx.OSTRACE("LOCK FAILED {0} trying for {1} but got {2}", S.GetHashCode(), locktype, newLocktype); #endif LastErrno = error; rc = RC.BUSY; } this.Locktype = newLocktype; return rc; }
public override RC Unlock(LOCK locktype) { return(RC.OK); }
public virtual void Lock() { _lock = LOCK.LOCKED; OnLock(); }
public virtual RC Lock(LOCK locktype) { #if DEBUG SysEx.OSTRACE("LOCK {0} {1} was {2}({3})", S.GetHashCode(), locktype, this.Locktype, SharedLockByte); #endif // If there is already a lock of this type or more restrictive on the OsFile, do nothing. Don't use the end_lock: exit path, as sqlite3OsEnterMutex() hasn't been called yet. if (this.Locktype >= locktype) { return(RC.OK); } // Make sure the locking sequence is correct Debug.Assert(this.Locktype != LOCK.NO || locktype == LOCK.SHARED); Debug.Assert(locktype != LOCK.PENDING); Debug.Assert(locktype != LOCK.RESERVED || this.Locktype == LOCK.SHARED); // 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. uint error = 0; var res = 1; // Result of a windows lock call var gotPendingLock = false; // True if we acquired a PENDING lock this time var newLocktype = this.Locktype; if (this.Locktype == LOCK.NO || (locktype == LOCK.EXCLUSIVE && this.Locktype == LOCK.RESERVED)) { res = 0; var cnt = 3; while (cnt-- > 0 && res == 0) { try { lockingStrategy.LockFile(this, PENDING_BYTE, 1); res = 1; } catch (Exception) { // Try 3 times to get the pending lock. The pending lock might be held by another reader process who will release it momentarily. #if DEBUG SysEx.OSTRACE("could not get a PENDING lock. cnt={0}", cnt); #endif Thread.Sleep(1); } } gotPendingLock = (res != 0); if (0 == res) { error = (uint)Marshal.GetLastWin32Error(); } } // Acquire a shared lock if (locktype == LOCK.SHARED && res != 0) { Debug.Assert(this.Locktype == LOCK.NO); res = getReadLock(); if (res != 0) { newLocktype = LOCK.SHARED; } else { error = (uint)Marshal.GetLastWin32Error(); } } // Acquire a RESERVED lock if (locktype == LOCK.RESERVED && res != 0) { Debug.Assert(this.Locktype == LOCK.SHARED); try { lockingStrategy.LockFile(this, RESERVED_BYTE, 1); newLocktype = LOCK.RESERVED; res = 1; } catch (Exception) { res = 0; error = (uint)Marshal.GetLastWin32Error(); } if (res != 0) { newLocktype = LOCK.RESERVED; } else { error = (uint)Marshal.GetLastWin32Error(); } } // Acquire a PENDING lock if (locktype == LOCK.EXCLUSIVE && res != 0) { newLocktype = LOCK.PENDING; gotPendingLock = false; } // Acquire an EXCLUSIVE lock if (locktype == LOCK.EXCLUSIVE && res != 0) { Debug.Assert(this.Locktype >= LOCK.SHARED); res = unlockReadLock(); #if DEBUG SysEx.OSTRACE("unreadlock = {0}", res); #endif try { lockingStrategy.LockFile(this, SHARED_FIRST, SHARED_SIZE); newLocktype = LOCK.EXCLUSIVE; res = 1; } catch (Exception) { res = 0; } if (res != 0) { newLocktype = LOCK.EXCLUSIVE; } else { error = (uint)Marshal.GetLastWin32Error(); #if DEBUG SysEx.OSTRACE("error-code = {0}", error); #endif getReadLock(); } } // If we are holding a PENDING lock that ought to be released, then release it now. if (gotPendingLock && locktype == LOCK.SHARED) { lockingStrategy.UnlockFile(this, PENDING_BYTE, 1); } // Update the state of the lock has held in the file descriptor then return the appropriate result code. var rc = RC.OK; if (res != 0) { rc = RC.OK; } else { #if DEBUG SysEx.OSTRACE("LOCK FAILED {0} trying for {1} but got {2}", S.GetHashCode(), locktype, newLocktype); #endif LastErrno = error; rc = RC.BUSY; } this.Locktype = newLocktype; return(rc); }
protected virtual void OnLock() { _lock = LOCK.LOCKED; OnDeselect(); }
protected virtual void OnUnlock() { _lock = LOCK.UNLOCKED; }
public override RC Lock(LOCK locktype) { return RC.OK; }
public virtual RC Lock(LOCK lock_) { return(RC.OK); }
public virtual RC Unlock(LOCK locktype) { Debug.Assert(locktype <= LOCK.SHARED); #if DEBUG SysEx.OSTRACE("UNLOCK {0} to {1} was {2}({3})", S.GetHashCode(), locktype, this.Locktype, SharedLockByte); #endif var rc = RC.OK; var type = this.Locktype; if (type >= LOCK.EXCLUSIVE) { lockingStrategy.UnlockFile(this, SHARED_FIRST, SHARED_SIZE); if (locktype == LOCK.SHARED && getReadLock() == 0) // This should never happen. We should always be able to reacquire the read lock rc = winLogError(RC.IOERR_UNLOCK, "winUnlock", Path); } if (type >= LOCK.RESERVED) try { lockingStrategy.UnlockFile(this, RESERVED_BYTE, 1); } catch (Exception) { } if (locktype == LOCK.NO && type >= LOCK.SHARED) unlockReadLock(); if (type >= LOCK.PENDING) { try { lockingStrategy.UnlockFile(this, PENDING_BYTE, 1); } catch (Exception) { } } this.Locktype = locktype; return rc; }
protected virtual void OnUnlock() { _lock = LOCK.UNLOCKED; }
public virtual void Unlock() { _lock = LOCK.UNLOCKED; OnUnlock(); }
public virtual void Lock() { _lock = LOCK.LOCKED; OnLock(); }
public void Clear() { S = null; Locktype = 0; SharedLockByte = 0; LastErrno = 0; _sectorSize = 0; }
public virtual void Unlock() { _lock = LOCK.UNLOCKED; OnUnlock(); }
public virtual RC Unlock(LOCK lock_) { return RC.OK; }