예제 #1
0
 /// <summary>
 /// Commits the transaction.
 /// </summary>
 /// <remarks>
 /// After a successful call to this method, this context instance should be disposed.
 /// </remarks>
 public void Commit()
 {
     try
     {
         if (_transactionCommitted)
         {
             throw new InvalidOperationException("Transaction already committed.");
         }
         _context.SubmitChanges();
         if (_transaction != null)
         {
             _transaction.Commit();
         }
         _transactionCommitted = true;
     }
     catch (ChangeConflictException)
     {
         foreach (ObjectChangeConflict occ in _context.ChangeConflicts)
         {
             MetaTable metatable = _context.Mapping.GetTable(occ.Object.GetType());
             Platform.Log(LogLevel.Warn, "Change Conflict with update to table: {0}", metatable.TableName);
         }
         throw;
     }
     finally
     {
         if (_mutex != null)
         {
             _mutex.Unlock();
             _mutex.Dispose();
             _mutex = null;
         }
     }
 }
예제 #2
0
            protected override void Execute()
            {
                var start  = Environment.TickCount;
                var random = new Random(TesterId);

                do
                {
                    // for simulating a broken lock to verify that this test does what is intended, use x as conditional on _lock calls
                    // var x = _testerId != random.Next(0, 1000);

                    var @lock = ExclusiveLock.CreateFileSystemLock(typeof(InstanceFileSystemLockTester).FullName);
                    @lock.Lock();
                    Interlocked.Increment(ref _counter);
                    try
                    {
                        Thread.Sleep(random.Next(1, 20));                         // add some variability to iteration length so that threads aren't just running in lock step
                        Assert.AreEqual(1, _counter, @"Tester {0} entered lock while another tester has lock", TesterId);
                        FlagFailed(_counter != 1);
                    }
                    finally
                    {
                        Interlocked.Decrement(ref _counter);
                        @lock.Unlock();
                    }
                } while (Environment.TickCount - start < TestLengthMs);
            }
예제 #3
0
        /// <summary>
        /// Activate the options on the file appender.
        /// </summary>
        /// <remarks>
        /// <para>
        /// This is part of the <see cref="IOptionHandler"/> delayed object
        /// activation scheme. The <see cref="ActivateOptions"/> method must
        /// be called on this object after the configuration properties have
        /// been set. Until <see cref="ActivateOptions"/> is called this
        /// object is in an undefined state and must not be used.
        /// </para>
        /// <para>
        /// If any of the configuration properties are modified then
        /// <see cref="ActivateOptions"/> must be called again.
        /// </para>
        /// <para>
        /// This will cause the file to be opened.
        /// </para>
        /// </remarks>
        override public void ActivateOptions()
        {
            base.ActivateOptions();

            if (m_securityContext == null)
            {
                m_securityContext = SecurityContextProvider.DefaultProvider.CreateSecurityContext(this);
            }

            if (m_lockingModel == null)
            {
                m_lockingModel = new ExclusiveLock();
            }

            m_lockingModel.CurrentAppender = this;

            using (SecurityContext.Impersonate(this))
            {
                m_fileName = ConvertToFullPath(m_fileName.Trim());
            }

            if (m_fileName != null)
            {
                SafeOpenFile(m_fileName, m_appendToFile);
            }
            else
            {
                LogLog.Warn(declaringType, "FileAppender: File option not set for appender [" + Name + "].");
                LogLog.Warn(declaringType, "FileAppender: Are you using FileAppender instead of ConsoleAppender?");
            }
        }
예제 #4
0
        public void Dispose()
        {
            if (_disposed)
            {
                throw new InvalidOperationException("Already disposed.");
            }

            _disposed = true;

            if (!_transactionCommitted && _transaction != null)
            {
                _transaction.Rollback();
            }

            _context.Dispose();
            _connection.Close();
            _connection.Dispose();

            if (_mutex != null)
            {
                _mutex.Unlock();
                _mutex.Dispose();
                _mutex = null;
            }
        }
예제 #5
0
        /// <summary>
        /// 写日志以前的准备工作
        /// </summary>
        override public void ActivateAppender()
        {
            if (m_lockingModel == null)
            {
                switch (LogConfig.Instance.LockType)
                {
                //独占锁
                case LockingType.Exclusive:
                    m_lockingModel = new ExclusiveLock();
                    break;

                //跨进程文件锁定
                case LockingType.InterProcess:
                    m_lockingModel = new InterProcessLock();
                    break;

                //最小时间锁
                case LockingType.Minimal:
                    m_lockingModel = new MinimalLock();
                    break;
                }
            }

            m_lockingModel.CurrentAppender = this;

            if (m_fileName != null)
            {
                PrepareWriter();
            }
        }
예제 #6
0
        public void Acquire_completes_sync_then_release_succeeds()
        {
            ExclusiveLock l = new ExclusiveLock();

            ExclusiveLock.Token token = AssertTaskCompleted(l.AcquireAsync());

            l.Release(token);
        }
예제 #7
0
 private ExclusiveLock CreateLock(string baseName, bool useGlobalPrefix)
 {
     if (useGlobalPrefix)
     {
         return(new NamedMutexLock(@"Global\" + baseName));
     }
     return(ExclusiveLock.CreateFileSystemLock(baseName));
 }
 static void RotateList(L2List list)
 {
     using (ExclusiveLock xl = new ExclusiveLock(list))
     {
         L2Elem last = list.head.prev;
         last.unlink();
         last.linkAfter(list.head);
     }
 }
예제 #9
0
        public void Release_same_token_twice_throws_InvalidOperation()
        {
            ExclusiveLock l = new ExclusiveLock();

            ExclusiveLock.Token token = AssertTaskCompleted(l.AcquireAsync());

            l.Release(token);

            Assert.Throws <InvalidOperationException>(() => l.Release(token));
        }
예제 #10
0
        public void First_acquire_completes_sync_next_acquire_is_pending_until_first_release()
        {
            ExclusiveLock l = new ExclusiveLock();

            ExclusiveLock.Token token = AssertTaskCompleted(l.AcquireAsync());

            Task <ExclusiveLock.Token> nextAcquireTask = AssertTaskPending(l.AcquireAsync());

            l.Release(token);

            AssertTaskCompleted(nextAcquireTask);
        }
예제 #11
0
        public void Acquire_and_release_three_times_in_a_row_completes_sync_each_time()
        {
            ExclusiveLock l = new ExclusiveLock();

            ExclusiveLock.Token token1 = AssertTaskCompleted(l.AcquireAsync());
            l.Release(token1);

            ExclusiveLock.Token token2 = AssertTaskCompleted(l.AcquireAsync());
            l.Release(token2);

            ExclusiveLock.Token token3 = AssertTaskCompleted(l.AcquireAsync());
            l.Release(token3);
        }
예제 #12
0
        /// <summary>
        /// 打开文件为写日志操作做准备
        /// </summary>
        /// <param name="fileName">文件名</param>
        /// <param name="append">是否添加日志信息到文件尾</param>
        virtual protected void OpenFile(string fileName, bool append)
        {
            lock (this)
            {
                //先进行关闭之前打开的文件
                Reset();

                // 保存这些后, 允许重试如果打开文件失败
                m_fileName     = fileName;
                m_appendToFile = append;

                switch (LogConfig.Instance.LockType)
                {
                //独占
                case LockingType.Exclusive:
                    m_lockingModel = new ExclusiveLock();
                    break;

                //跨进程文件锁
                case LockingType.InterProcess:
                    m_lockingModel = new InterProcessLock();
                    break;

                //最小时间
                case LockingType.Minimal:
                    m_lockingModel = new MinimalLock();
                    break;
                }
                //
                LockingModel.CurrentAppender = this;
                //打开文件
                LockingModel.OpenFile(fileName, append, m_encoding);

                m_stream = new LockingStream(LockingModel);

                if (m_stream != null)
                {
                    m_stream.AcquireLock();

                    try
                    {
                        SetQWForFiles(new StreamWriter(m_stream, m_encoding));
                    }
                    finally
                    {
                        m_stream.ReleaseLock();
                    }
                }
            }
        }
예제 #13
0
        public void Three_acquires_first_completes_sync_next_acquires_are_pending_until_previous_owners_release()
        {
            ExclusiveLock l = new ExclusiveLock();

            ExclusiveLock.Token token1 = AssertTaskCompleted(l.AcquireAsync());

            Task <ExclusiveLock.Token> acquireTask1 = AssertTaskPending(l.AcquireAsync());
            Task <ExclusiveLock.Token> acquireTask2 = AssertTaskPending(l.AcquireAsync());

            l.Release(token1);

            ExclusiveLock.Token token2 = AssertTaskCompleted(acquireTask1);

            l.Release(token2);

            AssertTaskCompleted(acquireTask2);
        }
예제 #14
0
		internal DataAccessContext(string mutexName, string databaseFilename)
		{
			if (!string.IsNullOrEmpty(mutexName))
			{
				_mutex = ExclusiveLock.CreateFileSystemLock(SqlCeDatabaseHelper<DicomStoreDataContext>.GetDatabaseFilePath(mutexName + databaseFilename));
				_mutex.Lock();
			}

			try
			{
				// initialize a connection and transaction
				_databaseFilename = databaseFilename;
				_connection = CreateConnection();
				_transaction = _connection.BeginTransaction(IsolationLevel.ReadCommitted);
				_context = new DicomStoreDataContext(_connection);
				//_context.Log = Console.Out;
			}
			catch
			{
				_mutex.Unlock();
				_mutex.Dispose();
				_mutex = null;

				throw;
			}

			lock (_syncLock)
			{
				if (_staticConnection == null)
				{
					// This is done for performance reasons.  It forces a connection to remain open while the 
					// the app domain is running, so that the database is kept in memory.
					try
					{
						_staticConnection = CreateConnection();
					}
					catch (Exception ex)
					{
						Platform.Log(LogLevel.Debug, ex, "Failed to initialize static connection to data store database");
					}
				}
			}
		}
예제 #15
0
        internal DataAccessContext(string mutexName, string databaseFilename)
        {
            if (!string.IsNullOrEmpty(mutexName))
            {
                _mutex = ExclusiveLock.CreateFileSystemLock(SqlCeDatabaseHelper <DicomStoreDataContext> .GetDatabaseFilePath(mutexName + databaseFilename));
                _mutex.Lock();
            }

            try
            {
                // initialize a connection and transaction
                _databaseFilename = databaseFilename;
                _connection       = CreateConnection();
                _transaction      = _connection.BeginTransaction(IsolationLevel.ReadCommitted);
                _context          = new DicomStoreDataContext(_connection);
                //_context.Log = Console.Out;
            }
            catch
            {
                _mutex.Unlock();
                _mutex.Dispose();
                _mutex = null;

                throw;
            }

            lock (_syncLock)
            {
                if (_staticConnection == null)
                {
                    // This is done for performance reasons.  It forces a connection to remain open while the
                    // the app domain is running, so that the database is kept in memory.
                    try
                    {
                        _staticConnection = CreateConnection();
                    }
                    catch (Exception ex)
                    {
                        Platform.Log(LogLevel.Debug, ex, "Failed to initialize static connection to data store database");
                    }
                }
            }
        }
예제 #16
0
        static void Main(string[] args)
        {
            var serviceCollection = new ServiceCollection();

            serviceCollection.AddLogging();

            var serviceProvider         = serviceCollection.BuildServiceProvider();
            var loggerFactory           = serviceProvider.GetService <ILoggerFactory>();
            var cancellationTokenSource = new CancellationTokenSource();

            using (var exclusiveLock = new ExclusiveLock("localhost:2181", "/dlock-example", 5000, cancellationTokenSource.Token, loggerFactory.CreateLogger("dlock.console")))
            {
                var dlock = exclusiveLock.Wait().GetAwaiter().GetResult();

                Console.WriteLine(dlock);

                if (dlock.result)
                {
                    SpinWait.SpinUntil(() => dlock.cancellationToken.IsCancellationRequested);

                    Console.WriteLine("Releasing lock, cancellation requested");
                }
            }
        }
예제 #17
0
        /// <summary>
        /// Activate the options on the file appender. 
        /// </summary>
        /// <remarks>
        /// <para>
        /// This is part of the <see cref="IOptionHandler"/> delayed object
        /// activation scheme. The <see cref="ActivateOptions"/> method must 
        /// be called on this object after the configuration properties have
        /// been set. Until <see cref="ActivateOptions"/> is called this
        /// object is in an undefined state and must not be used. 
        /// </para>
        /// <para>
        /// If any of the configuration properties are modified then 
        /// <see cref="ActivateOptions"/> must be called again.
        /// </para>
        /// <para>
        /// This will cause the file to be opened.
        /// </para>
        /// </remarks>
        public override void ActivateOptions()
        {
            base.ActivateOptions();

            if (m_securityContext == null)
                m_securityContext = SecurityContextProvider.DefaultProvider.CreateSecurityContext(this);

            if (m_lockingModel == null)
                m_lockingModel = new ExclusiveLock();

            m_lockingModel.CurrentAppender = this;

            using (SecurityContext.Impersonate(this))
            {
                m_fileName = ConvertToFullPath(m_fileName.Trim());
            }

            if (m_fileName != null)
                SafeOpenFile(m_fileName, m_appendToFile);
            else
            {
                LogLog.Warn("FileAppender: File option not set for appender [" + Name + "].");
                LogLog.Warn("FileAppender: Are you using FileAppender instead of ConsoleAppender?");
            }
        }
예제 #18
0
	    /// <summary>
		/// Commits the transaction.
		/// </summary>
		/// <remarks>
		/// After a successful call to this method, this context instance should be disposed.
		/// </remarks>
		public void Commit()
		{
            try
            {
                if (_transactionCommitted)
                    throw new InvalidOperationException("Transaction already committed.");
                _context.SubmitChanges();
                if (_transaction != null)
                    _transaction.Commit();
                _transactionCommitted = true;
            }
            catch (ChangeConflictException)
            {
                foreach (ObjectChangeConflict occ in _context.ChangeConflicts)
                {
                    MetaTable metatable = _context.Mapping.GetTable(occ.Object.GetType());
                    Platform.Log(LogLevel.Warn, "Change Conflict with update to table: {0}",  metatable.TableName);
                }
                throw;
            }
            finally
            {
                if (_mutex != null)
                {
                    _mutex.Unlock();
                    _mutex.Dispose();
                    _mutex = null;
                }
            }
		}
예제 #19
0
		public void Dispose()
		{
			if(_disposed)
				throw new InvalidOperationException("Already disposed.");

			_disposed = true;

			if(!_transactionCommitted && _transaction != null)
			{
				_transaction.Rollback();
			}

			_context.Dispose();
			_connection.Close();
			_connection.Dispose();

            if (_mutex != null)
            {
                _mutex.Unlock();
                _mutex.Dispose();
                _mutex = null;
            }
		}
예제 #20
0
        public void Release_invalid_token_throws_InvalidOperation()
        {
            ExclusiveLock l = new ExclusiveLock();

            Assert.Throws <InvalidOperationException>(() => l.Release(new MyToken()));
        }