예제 #1
0
        internal void OnSyncEnd(WorkSyncContext sync)
        {
            // when synched work finshed, resume work loop again
            lock (_lock)
            {
                if (_waitingSync.Source == sync)
                {
                    _waitingSync = null;

                    if (_isWorkLoopSpawned == false)
                    {
                        _isWorkLoopSpawned = true;
                        ThreadPool.UnsafeQueueUserWorkItem(WorkLoop, null);
                    }
                }
                else
                {
                    throw new InvalidOperationException("Waiting state doesn't match with event source");
                }
            }
        }
예제 #2
0
        internal void QueueSync(WorkSyncContext source)
        {
            var work = new WorkSync
            {
                Source  = source,
                Options = WorkOptions.Sync
            };

            bool willSpawn = false;

            lock (_lock)
            {
                _workQueue.Enqueue(work);
                if (_isWorkLoopSpawned == false)
                {
                    _isWorkLoopSpawned = true;
                    willSpawn          = true;
                }
            }
            if (willSpawn)
            {
                WorkLoop(null);
            }
        }
예제 #3
0
        private void WorkLoop(object state)
        {
            using (new SynchronizationContextSwitcher(_synchronizationContext))
            {
                while (true)
                {
                    Work work;
                    lock (_lock)
                    {
                        if (_waitingSync != null || _waitingSyncedWork != null)
                        {
                            _isWorkLoopSpawned = false;
                            break;
                        }
                        if (_workQueue.Count == 0)
                        {
                            _isWorkLoopSpawned = false;
                            break;
                        }

                        work = _workQueue.Dequeue();
                        if (work.Sync != null)
                        {
                            _waitingSyncedWork = work;
                            work.Sync.OnOwnerEnter(this);
                            continue;
                        }

                        if (work.Options.HasFlag(WorkOptions.Atomic))
                        {
                            if (_isInAtomic)
                            {
                                throw new InvalidOperationException("Already in atomic");
                            }

                            _isInAtomic = true;
                            _atomicWork = work;
                            Swap(ref _workQueue, ref _pendingWorkQueue);
                            if (_workQueue == null)
                            {
                                _workQueue = new Queue <Work>();
                            }
                        }
                        else if (work.Options.HasFlag(WorkOptions.Barrier))
                        {
                            if (_runningTaskCount > 0)
                            {
                                _waitingBarrier = work;
                            }
                            else
                            {
                                OnBarrierComplete(work);
                            }
                            continue;
                        }
                        else if (work.Options.HasFlag(WorkOptions.Sync))
                        {
                            _waitingSync = (WorkSync)work;
                            var source = _waitingSync.Source;
                            source.OnWaiterEnter(this);
                            continue;
                        }
                    }

                    ProcessWork(work);
                }
            }
        }