示例#1
0
        /// <summary>
        /// Enter in Shared lock mode.
        /// </summary>
        public LockControl Read()
        {
            // if read or write
            if (_thread.IsReadLockHeld || _thread.IsWriteLockHeld)
            {
                return(new LockControl(() => { }));
            }

            // 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}", Thread.CurrentThread.ManagedThreadId);

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

            this.DetectDatabaseChanges();

            return(new LockControl(() =>
            {
                // 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}", Thread.CurrentThread.ManagedThreadId);
            }));
        }
示例#2
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");
                });
            }
        }
示例#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>
        ///     Commit the transaction - increese
        /// </summary>
        public void Commit()
        {
            if (_trans == false)
            {
                throw new Exception("No begin transaction");
            }

            if (_cache.HasDirtyPages)
            {
                // save dirty pages
                Save();

                // clear all pages in cache
                _cache.Clear();
            }

            // delete journal file - datafile is consist here
            _disk.DeleteJournal();

            // unlock datafile
            _disk.Unlock();

            _trans = false;
        }