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"); } } }
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); } }
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); } } }