internal void BeganTouching(DetectorVolumePairHandler pair) { locker.Enter(); containmentChanges.Enqueue(new ContainmentChange { Change = ContainmentChangeType.BeganTouching, Entity = pair.Collidable.entity }); locker.Exit(); }
/// <summary>Takes an array from the bucket. If the bucket is empty, returns null.</summary> internal T[] Rent() { T[][] buffers = this._buffers; T[] buffer = null; // While holding the lock, grab whatever is at the next available index and // update the index. We do as little work as possible while holding the spin // lock to minimize contention with other threads. The try/finally is // necessary to properly handle thread aborts on platforms which have them. #if SERVERSIDE bool lockTaken = false; #endif bool allocateBuffer = false; try { #if SERVERSIDE _lock.Enter(ref lockTaken); #endif if (this._index < buffers.Length) { buffer = buffers[this._index]; buffers[this._index++] = null; allocateBuffer = buffer == null; } } finally { #if SERVERSIDE if (lockTaken) { _lock.Exit(false); } #endif } // While we were holding the lock, we grabbed whatever was at the next available index, if // there was one. If we tried and if we got back null, that means we hadn't yet allocated // for that slot, in which case we should do so now. if (allocateBuffer) { buffer = new T[this.bufferLength]; #if SERVERSIDE var log = ArrayPoolEventSource.Log; if (log.IsEnabled()) { log.BufferAllocated(buffer.GetHashCode(), _bufferLength, _poolId, Id, ArrayPoolEventSource.BufferAllocatedReason.Pooled); } #endif } return(buffer); }
void UpdateEntry(int i) { //Compute the current cells occupied by the entry. var entry = entries.Elements[i]; Int2 min, max; ComputeCell(ref entry.item.boundingBox.Min, out min); ComputeCell(ref entry.item.boundingBox.Max, out max); //For any cell that used to be occupied (defined by the previous min/max), //remove the entry. for (int j = entry.previousMin.Y; j <= entry.previousMax.Y; j++) { for (int k = entry.previousMin.Z; k <= entry.previousMax.Z; k++) { if (j >= min.Y && j <= max.Y && k >= min.Z && k <= max.Z) { continue; //This cell is currently occupied, do not remove. } var index = new Int2 { Y = j, Z = k }; bool taken = false; cellSetLocker.Enter(ref taken); //cellSetLocker.Enter(); cellSet.Remove(ref index, entry); cellSetLocker.Exit(); } } //For any cell that is newly occupied (was not previously contained), //add the entry. for (int j = min.Y; j <= max.Y; j++) { for (int k = min.Z; k <= max.Z; k++) { if (j >= entry.previousMin.Y && j <= entry.previousMax.Y && k >= entry.previousMin.Z && k <= entry.previousMax.Z) { continue; //This cell is already occupied, do not add. } var index = new Int2 { Y = j, Z = k }; bool taken = false; cellSetLocker.Enter(ref taken); //cellSetLocker.Enter(); cellSet.Add(ref index, entry); cellSetLocker.Exit(); } } entry.previousMin = min; entry.previousMax = max; }
/// <summary> /// Enters spinlock /// </summary> public bool Enter() { bool lockTaken = false; spinlock.Enter(ref lockTaken); return(lockTaken); }
void TryToCompressIslandHierarchy() { var currentSimulationIsland = simulationIsland; if (currentSimulationIsland != null) { if (currentSimulationIsland.immediateParent != currentSimulationIsland) { //Only remove ourselves from the owning simulation island, not all the way up the chain. //The change locker must be obtained first to prevent kinematic notifications in the candidacy update //from attempting to evaluate the SimulationIsland while we are reorganizing things. simulationIslandChangeLocker.Enter(); lock (currentSimulationIsland) currentSimulationIsland.Remove(this); currentSimulationIsland = currentSimulationIsland.Parent; //Add ourselves to the new owner. lock (currentSimulationIsland) currentSimulationIsland.Add(this); simulationIslandChangeLocker.Exit(); //TODO: Should it activate the new island? This might avoid a possible corner case. //It could interfere with the activated event meaningfulness, since that is triggered //at the end of the update candidacy loop.. //currentSimulationIsland.isActive = true; } } }
public ulong Next() { ulong result = 0; System.Threading.SpinLock slock = new System.Threading.SpinLock(); bool gotLock = false; try { while (!gotLock) { slock.Enter(ref gotLock); if (gotLock) { ulong cms = (ulong)mWatch.Elapsed.TotalMilliseconds - InitMillisecond; if (cms != mCurrentMillisecond) { mSeed = 0; mCurrentMillisecond = cms; } result = ((ulong)Group << 48) | (mCurrentMillisecond << 8) | (ulong)mSeed; mSeed++; } } } finally { if (gotLock) { slock.Exit(); } } return(result); }
///<summary> /// Adds a solver updateable to the solver. ///</summary> ///<param name="item">Updateable to add.</param> ///<exception cref="ArgumentException">Thrown when the item already belongs to a solver.</exception> public void Add(SolverUpdateable item) { if (item.Solver == null) { item.Solver = this; bool taken = false; addRemoveLocker.Enter(ref taken); //addRemoveLocker.Enter(); item.solverIndex = solverUpdateables.Count; solverUpdateables.Add(item); addRemoveLocker.Exit(); DeactivationManager.Add(item.simulationIslandConnection); item.OnAdditionToSolver(this); } else { throw new ArgumentException("Solver updateable already belongs to something; it can't be added.", "item"); } }
//TODO: SPEED UP THESE ENQUEUES! public void Enqueue(T item) { //bool taken = false; //locker.Enter(ref taken); locker.Enter(); try { //Enqueues go to the tail only; it's like a queue. //head ----> tail if (count == array.Length) { //Resize //TODO: Better shift-resize T[] oldArray = array; array = new T[Math.Max(4, oldArray.Length * 2)]; //Copy the old first-end to the first part of the new array. Array.Copy(oldArray, firstIndex, array, 0, oldArray.Length - firstIndex); //Copy the old begin-first to the second part of the new array. Array.Copy(oldArray, 0, array, oldArray.Length - firstIndex, firstIndex); firstIndex = 0; lastIndex = count - 1; } lastIndex++; if (lastIndex == array.Length) { lastIndex = 0; } array[lastIndex] = item; count++; } finally { locker.Exit(); //locker.Exit(); } }
public static bool Lock(string userID) { bool isEnable = false; bool gotLock = false; try { SLock.Enter(ref gotLock); if (RequestLockSet.Add(userID)) { isEnable = true; } } finally { if (gotLock) { SLock.Exit(); } } return(isEnable); }
private bool TryGet(out T instance) { instance = null; bool lockTaken = false; try { poolLock.Enter(ref lockTaken); if (freeIndex < pool.Length) { instance = pool[freeIndex]; pool[freeIndex] = null; freeIndex++; } } finally { if (lockTaken) { poolLock.Exit(); } } return(instance != null); }
///<summary> /// Adds a simulation island connection to the deactivation manager. ///</summary> ///<param name="connection">Connection to add.</param> ///<exception cref="ArgumentException">Thrown if the connection already belongs to a manager.</exception> public void Add(SimulationIslandConnection connection) { //DO A MERGE IF NECESSARY if (connection.DeactivationManager == null) { bool taken = false; addLocker.Enter(ref taken); //addLocker.Enter(); connection.DeactivationManager = this; if (connection.entries.Count > 0) { var island = connection.entries.Elements[0].Member.SimulationIsland; for (int i = 1; i < connection.entries.Count; i++) { SimulationIsland opposingIsland; if (island != (opposingIsland = connection.entries.Elements[i].Member.SimulationIsland)) { //Need to do a merge between the two islands. //Note that this merge may eliminate the need for a merge with subsequent connection if they belong to the same island. island = Merge(island, opposingIsland); } } //If it was slated for removal, that means the flush stage will try to split it. //Since it was just added back, splitting is known to be pointless. //Just set the flag and the flush will ignore the split attempt. if (connection.SlatedForRemoval) { connection.SlatedForRemoval = false; } else { //If the connection was NOT slated for removal, that means the reference don't currently exist. //(If the connection was slated for removal, that would imply the connection existed previously, so it must have had references.) connection.AddReferencesToConnectedMembers(); } } addLocker.Exit(); } else { throw new ArgumentException("Cannot add connection to deactivation manager; it already belongs to one."); } }
/// <summary> /// 搜索指定的对象,并返回整个 System.Collections.Generic.List<T> 中第一个匹配项的从零开始的索引。 /// </summary> /// <param name="item">对像</param> /// <returns></returns> public int IndexOf(T item) { bool gotLock = false; try { splock.Enter(ref gotLock); return(list.IndexOf(item)); } finally { if (gotLock) { splock.Exit(); } } }
private void EnterLock() { bool lockToken = false; spinLock.Enter(ref lockToken); }
protected internal void AddOverlap(BroadPhaseOverlap overlap) { overlapAddLock.Enter(); overlaps.Add(overlap); overlapAddLock.Exit(); }
/// <summary> /// 为SwitchsErrors加锁 /// </summary> public static void SwitchsErrors_EnterLock() { bool e = false; hashset_switchs_error_lock.Enter(ref e); }
/// <summary> /// 为SwitchsDisables加锁 /// </summary> public static void SwitchsDisables_EnterLock() { bool e = false; hashset_switchs_disables_lock.Enter(ref e); }