Пример #1
0
        /// <summary>
        /// Try enter in shared lock (read) - Call action if request a new lock
        /// [Non ThreadSafe]
        /// </summary>
        private Action LockShared()
        {
            lock (_disk)
            {
                if (_state != LockState.Unlocked)
                {
                    return () => { }
                }
                ;

                _disk.Lock(LockState.Shared, _timeout);

                _state  = LockState.Shared;
                _shared = true;

                _log.Write(Logger.LOCK, "entered in shared lock mode");

                this.AvoidDirtyRead();

                return(() =>
                {
                    _shared = false;
                    _disk.Unlock(LockState.Shared);
                    _state = LockState.Unlocked;

                    _log.Write(Logger.LOCK, "exited shared lock mode");
                });
            }
        }
Пример #2
0
        /// <summary>
        /// Enter in Shared lock mode.
        /// </summary>
        public LockControl Read()
        {
            // if read or write
            if (_thread.IsReadLockHeld || _thread.IsWriteLockHeld)
            {
                return(new LockControl(false, () => { }));
            }

            // try enter in read mode
            if (!_thread.TryEnterReadLock(_timeout))
            {
                throw LiteException.LockTimeout(_timeout);
            }

            _log.Write(Logger.LOCK, "entered in read lock mode in thread #{0}", this.ThreadId);

            // lock disk in shared mode
            var position = _disk.Lock(LockState.Read, _timeout);

            var changed = this.DetectDatabaseChanges();

            return(new LockControl(changed, () =>
            {
                // exit disk lock mode
                _disk.Unlock(LockState.Read, position);

                // exit thread lock mode
                _thread.ExitReadLock();

                _log.Write(Logger.LOCK, "exited read lock mode in thread #{0}", this.ThreadId);
            }));
        }
Пример #3
0
        /// <summary>
        /// Try enter in shared lock (read) - Call action if request a new lock
        /// </summary>
        public LockControl Shared(Action actionIfNewLock)
        {
            lock (_disk)
            {
                if (_state != LockState.Unlocked)
                {
                    return(new LockControl(null));
                }

                _log.Write(Logger.DISK, "enter in shared lock mode");

                _disk.Lock(LockState.Shared);

                _state  = LockState.Shared;
                _shared = true;

                actionIfNewLock();

                return(new LockControl(() =>
                {
                    _log.Write(Logger.DISK, "exit shared lock mode");

                    _shared = false;
                    _state = LockState.Unlocked;

                    _disk.Unlock(LockState.Shared);
                }));
            }
        }
Пример #4
0
        /// <summary>
        /// Initialize LiteEngine using custom disk service implementation and full engine options
        /// </summary>
        public LiteEngine(IDiskService disk, string password = null, TimeSpan?timeout = null, int cacheSize = 5000, Logger log = null, bool utcDate = false)
        {
            if (disk == null)
            {
                throw new ArgumentNullException("disk");
            }

            _timeout    = timeout ?? TimeSpan.FromMinutes(1);
            _cacheSize  = cacheSize;
            _disk       = disk;
            _log        = log ?? new Logger();
            _bsonReader = new BsonReader(utcDate);

            try
            {
                // initialize datafile (create) and set log instance
                _disk.Initialize(_log, password);

                // lock disk (read mode) before read header
                var position = _disk.Lock(LockState.Read, _timeout);

                var buffer = _disk.ReadPage(0);

                _disk.Unlock(LockState.Read, position);

                // create header instance from array bytes
                var header = BasePage.ReadPage(buffer) as HeaderPage;

                // hash password with sha1 or keep as empty byte[20]
                var sha1 = password == null ? new byte[20] : AesEncryption.HashSHA1(password);

                // compare header password with user password even if not passed password (datafile can have password)
                if (sha1.BinaryCompareTo(header.Password) != 0)
                {
                    throw LiteException.DatabaseWrongPassword();
                }

                // initialize AES encryptor
                if (password != null)
                {
                    _crypto = new AesEncryption(password, header.Salt);
                }

                // initialize all services
                this.InitializeServices();

                // if header are marked with recovery, do it now
                if (header.Recovery)
                {
                    _trans.Recovery();
                }
            }
            catch (Exception)
            {
                // explicit dispose
                this.Dispose();
                throw;
            }
        }
        /// <summary>
        ///     Starts a new transaction - lock database to garantee that only one processes is in a transaction
        /// </summary>
        public void Begin()
        {
            if (_trans)
            {
                throw new Exception("Begin transaction already exists");
            }

            // lock (or try to) datafile
            _disk.Lock();

            _trans = true;
        }