Пример #1
0
        public void TestAllThreadWakeUpOnSignalAll()
        {
            using (var testInst = new MonitorObject())
            {
                int         exitCount = 0;
                int         state     = 0;
                List <Task> tasks     = new List <Task>();
                for (int i = 0; i < 6; i++)
                {
                    var task = Task.Run(() =>
                    {
                        using (var waiter = testInst.Enter())
                        {
                            waiter.Wait(_ => { return(Volatile.Read(ref state) > 0); }, (object)null);
                            Interlocked.Increment(ref exitCount);
                        }
                    });
                    tasks.Add(task);
                }


                TimingAssert.AreEqual(10000, 6, () => testInst.WaiterCount);
                Interlocked.Increment(ref state);

                testInst.PulseAll();
                TimingAssert.AreEqual(10000, 0, () => testInst.WaiterCount);
                TimingAssert.AreEqual(10000, 6, () => Volatile.Read(ref exitCount));

                Task.WaitAll(tasks.ToArray());
            }
        }
Пример #2
0
        /// <summary>
        /// Removes completed segments
        /// </summary>
        /// <param name="allowNotification">Allows to send notification for adders (only when called from background thread)</param>
        private void Compact(bool allowNotification)
        {
            if (_isDisposed)
            {
                return;
            }

            List <DiskQueueSegmentWrapper <T> > _segmentsToCleanUp = null;
            bool shouldNotifyWaiters = false;

            lock (_segmentOperationsLock)
            {
                if (_isDisposed)
                {
                    return;
                }

                VerifyConsistency();

                shouldNotifyWaiters = allowNotification && _segments.Count >= _maxSegmentCount;

                MoveHeadToNonCompletedSegment(); // Correct head segment
                while (_segments.Count > 1 && _headSegment != _segments[0] && _segments[0].IsCompleted)
                {
                    _segmentsToCleanUp = _segmentsToCleanUp ?? new List <DiskQueueSegmentWrapper <T> >();
                    _segmentsToCleanUp.Add(_segments.RemoveFirst());
                }
            }

            if (_segmentsToCleanUp != null)
            {
                if (shouldNotifyWaiters)
                {
                    _addMonitor.PulseAll(); // Segment allocation is now possible
                }
                foreach (var segment in _segmentsToCleanUp)
                {
                    segment.Dispose(DiskQueueSegmentDisposeBehaviour.Delete);
                }
            }
        }
Пример #3
0
 /// <summary>
 /// Notifies about item addition
 /// </summary>
 private void NotifyItemAdded()
 {
     Interlocked.Increment(ref _itemCount);
     _takeMonitor.Pulse();
     _peekMonitor.PulseAll();
 }