/// <summary> /// Get the lock. If taken the current thread will enter a queue for the lock. /// </summary> public virtual void TakeRead() { _lock.Take(); ReadLocked = true; ++_readCount; _lock.Release(); }
/// <summary> /// Return a task if there is one. /// </summary> public override bool Next(out ActionAct task) { // has the needle been paused or is the lock already taken? if (_paused) { // yes, return no task task = null; return(false); } // if currently running if (_running) { // try get the A side lock if (_lockA.TryTake) { var tasks = _tasks.A; // get the next task while (tasks.Next() && !tasks.Loop) { if (tasks.Current.Remove) { tasks.RemoveCurrent(); tasks.Current.Remove = false; } task = tasks.Current; // should the task be run? if (task.ToRun && task.Ready) { _current = task; // set the current item task.Ready = false; _lockA.Release(); return(true); } } if (_flip) { _flip = false; _lockB.Take(); _tasks.Flip(); _lockB.Release(); tasks = _tasks.A; // get the next task while (tasks.Next() && !tasks.Loop) { if (tasks.Current.Remove) { tasks.RemoveCurrent(); tasks.Current.Remove = false; } task = tasks.Current; // should the task be run? if (task.ToRun && task.Ready) { _current = task; // set the current item task.Ready = false; _lockA.Release(); return(true); } } } // return to wait for delta time _running = false; // release the a lock _lockA.Release(); } else { task = null; return(false); } } if (!_lockA.TryTake) { task = null; return(false); } // if delta is greater than target it's time for another loop of tasks if (Time.Timestamp >= _nextTimestamp) { // add the target number of ticks _nextTimestamp = _nextTimestamp + _targetTicks; // this is running _running = true; _flip = true; // log of target ticks vs actual // if(Delta == 1000) { // Log.D(System.Threading.Thread.CurrentThread.Name + " Offset " + (_nextTimestamp - _targetTicks - Time.Timestamp)); // } var tasks = _tasks.A; // get the next task while (tasks.Next() && !tasks.Loop) { if (tasks.Current.Remove) { tasks.RemoveCurrent(); tasks.Current.Remove = false; } task = tasks.Current; // should the task be run? if (task.ToRun && task.Ready) { _current = task; // set the current item task.Ready = false; _lockA.Release(); return(true); } } if (_flip) { _flip = false; _lockB.Take(); _tasks.Flip(); _lockB.Release(); tasks = _tasks.A; // get the next task while (tasks.Next() && !tasks.Loop) { if (tasks.Current.Remove) { tasks.RemoveCurrent(); tasks.Current.Remove = false; } task = tasks.Current; // should the task be run? if (task.ToRun && task.Ready) { _current = task; // set the current item task.Ready = false; _lockA.Release(); return(true); } } } _running = false; } // release the a lock _lockA.Release(); // no task return task = null; return(false); }
/// <summary> /// Add an Task to be called in order on this needle. /// </summary> public override void AddUpdate(ActionAct task) { _lock.Take(); _tasks.Enqueue(task); _lock.Release(); }
/// <summary> /// Ensures the current value is only accessible in the current thread. /// </summary> public T TakeItem() { Locker.Take(); return(_item); }