示例#1
0
 internal void BeganTouching(DetectorVolumePairHandler pair)
 {
     locker.Enter();
     containmentChanges.Enqueue(new ContainmentChange
     {
         Change = ContainmentChangeType.BeganTouching,
         Entity = pair.Collidable.entity
     });
     locker.Exit();
 }
示例#2
0
            /// <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);
            }
示例#3
0
        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;
        }
示例#4
0
        /// <summary>
        /// Enters spinlock
        /// </summary>
        public bool Enter()
        {
            bool lockTaken = false;

            spinlock.Enter(ref lockTaken);
            return(lockTaken);
        }
示例#5
0
        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;
                }
            }
        }
示例#6
0
        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);
        }
示例#7
0
        ///<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");
            }
        }
示例#8
0
        //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);
        }
示例#10
0
        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);
        }
示例#11
0
        ///<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.");
            }
        }
示例#12
0
        /// <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();
                }
            }
        }
示例#13
0
        private void EnterLock()
        {
            bool lockToken = false;

            spinLock.Enter(ref lockToken);
        }
示例#14
0
 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);
        }