Exemple #1
0
        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);
        }
Exemple #2
0
        public int Chunk;             // Chunk size configured by FCNTL_CHUNK_SIZE

        public void Clear()
        {
            S              = null;
            Locktype       = 0;
            SharedLockByte = 0;
            LastErrno      = 0;
            _sectorSize    = 0;
        }
Exemple #3
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;
 }
Exemple #5
0
        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();
 }
Exemple #7
0
 static RC querySharedCacheTableLock(Btree p, Pid table, LOCK lock_) { return RC.OK; }
Exemple #8
0
        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;
        }
Exemple #9
0
        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;
        }
Exemple #10
0
 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;
 }
Exemple #11
0
 public override RC Unlock(LOCK locktype)
 {
     return(RC.OK);
 }
Exemple #12
0
 public virtual void Lock()
 {
     _lock = LOCK.LOCKED;
     OnLock();
 }
Exemple #13
0
        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);
        }
Exemple #14
0
 protected virtual void OnLock()
 {
     _lock = LOCK.LOCKED; OnDeselect();
 }
Exemple #15
0
 protected virtual void OnUnlock()
 {
     _lock = LOCK.UNLOCKED;
 }
 public override RC Lock(LOCK locktype)
 {
     return RC.OK;
 }
Exemple #17
0
 public virtual RC Lock(LOCK lock_)
 {
     return(RC.OK);
 }
Exemple #18
0
 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;
 }
Exemple #19
0
 protected virtual void OnUnlock()
 {
     _lock = LOCK.UNLOCKED;
 }
Exemple #20
0
 public virtual void Unlock()
 {
     _lock = LOCK.UNLOCKED;
     OnUnlock();
 }
Exemple #21
0
 public virtual void Lock()
 {
     _lock = LOCK.LOCKED;
     OnLock();
 }
Exemple #22
0
 public void Clear()
 {
     S = null;
     Locktype = 0;
     SharedLockByte = 0;
     LastErrno = 0;
     _sectorSize = 0;
 }
Exemple #23
0
 public virtual void Unlock()
 {
     _lock = LOCK.UNLOCKED;
     OnUnlock();
 }
Exemple #24
0
 public virtual RC Unlock(LOCK lock_)
 {
     return RC.OK;
 }