Example #1
0
            public static void SatisfyWaitForAll(
                ThreadWaitInfo waitInfo,
                WaitableObject[] waitedObjects,
                int waitedCount,
                int signaledWaitedObjectIndex)
            {
                Debug.Assert(waitInfo != null);
                Debug.Assert(waitInfo.Thread != RuntimeThread.CurrentThread);
                Debug.Assert(waitedObjects != null);
                Debug.Assert(waitedObjects.Length >= waitedCount);
                Debug.Assert(waitedCount > 1);
                Debug.Assert(signaledWaitedObjectIndex >= 0);
                Debug.Assert(signaledWaitedObjectIndex <= WaitHandle.MaxWaitHandles);

                for (int i = 0; i < waitedCount; ++i)
                {
                    Debug.Assert(waitedObjects[i] != null);
                    if (i == signaledWaitedObjectIndex)
                    {
                        continue;
                    }

                    WaitableObject waitedObject = waitedObjects[i];
                    if (waitedObject.IsSignaled)
                    {
                        waitedObject.AcceptSignal(waitInfo);
                        continue;
                    }

                    Debug.Assert(waitedObject.IsMutex);
                    OwnershipInfo ownershipInfo = waitedObject._ownershipInfo;
                    Debug.Assert(ownershipInfo.Thread == waitInfo.Thread);
                    ownershipInfo.IncrementReacquireCount();
                }
            }
Example #2
0
 public SelectionCriteria(bool isAgent, bool isBuilding, bool isControlable, OwnershipInfo ownership)
 {
     this.isAgent       = isAgent;
     this.isBuilding    = isBuilding;
     this.isControlable = isControlable;
     this.ownership     = ownership;
 }
            public static bool WouldWaitForAllBeSatisfiedOrAborted(
                RuntimeThread waitingThread,
                WaitableObject[] waitedObjects,
                int waitedCount,
                int signaledWaitedObjectIndex,
                ref bool wouldAnyMutexReacquireCountOverflow,
                ref bool isAnyAbandonedMutex)
            {
                s_lock.VerifyIsLocked();
                Debug.Assert(waitingThread != null);
                Debug.Assert(waitingThread != RuntimeThread.CurrentThread);
                Debug.Assert(waitedObjects != null);
                Debug.Assert(waitedObjects.Length >= waitedCount);
                Debug.Assert(waitedCount > 1);
                Debug.Assert(signaledWaitedObjectIndex >= 0);
                Debug.Assert(signaledWaitedObjectIndex <= WaitHandle.MaxWaitHandles);
                Debug.Assert(!wouldAnyMutexReacquireCountOverflow);

                for (int i = 0; i < waitedCount; ++i)
                {
                    Debug.Assert(waitedObjects[i] != null);
                    if (i == signaledWaitedObjectIndex)
                    {
                        continue;
                    }

                    WaitableObject waitedObject = waitedObjects[i];
                    if (waitedObject.IsSignaled)
                    {
                        if (!isAnyAbandonedMutex && waitedObject.IsAbandonedMutex)
                        {
                            isAnyAbandonedMutex = true;
                        }
                        continue;
                    }

                    if (waitedObject.IsMutex)
                    {
                        OwnershipInfo ownershipInfo = waitedObject._ownershipInfo;
                        if (ownershipInfo.Thread == waitingThread)
                        {
                            if (!ownershipInfo.CanIncrementReacquireCount)
                            {
                                // This will cause the wait to be aborted without accepting any signals
                                wouldAnyMutexReacquireCountOverflow = true;
                                return(true);
                            }
                            continue;
                        }
                    }

                    return(false);
                }

                return(true);
            }
Example #4
0
        private void ParcelObjectOwnersRequestHandler(Packet packet, LLAgent agent)
        {
            ParcelObjectOwnersRequestPacket request = (ParcelObjectOwnersRequestPacket)packet;

            SceneParcel parcel;

            if (m_parcels.TryGetParcel(request.ParcelData.LocalID, out parcel))
            {
                ParcelObjectOwnersReplyPacket    reply  = new ParcelObjectOwnersReplyPacket();
                Dictionary <UUID, OwnershipInfo> owners = new Dictionary <UUID, OwnershipInfo>();

                lock (parcel.ParcelEntities)
                {
                    foreach (ISceneEntity entity in parcel.ParcelEntities.Values)
                    {
                        // Skip child entities
                        if (entity is ILinkable && ((ILinkable)entity).Parent != null)
                        {
                            continue;
                        }

                        OwnershipInfo count;
                        if (!owners.TryGetValue(entity.OwnerID, out count))
                        {
                            count = new OwnershipInfo();
                            count.IsGroupOwned = false; // FIXME: Need to track group ownership
                            count.OnlineStatus = false; // FIXME: m_permissions.IsOnline(agent.ID, entity.OwnerID);

                            owners.Add(entity.OwnerID, count);
                        }

                        ++count.Count;
                    }
                }

                reply.Data = new ParcelObjectOwnersReplyPacket.DataBlock[owners.Count];
                int i = 0;
                foreach (KeyValuePair <UUID, OwnershipInfo> kvp in owners)
                {
                    reply.Data[i++] = new ParcelObjectOwnersReplyPacket.DataBlock
                    {
                        Count        = kvp.Value.Count,
                        OwnerID      = kvp.Key,
                        IsGroupOwned = kvp.Value.IsGroupOwned,
                        OnlineStatus = kvp.Value.OnlineStatus
                    };
                }

                m_udp.SendPacket(agent, reply, ThrottleCategory.Task, true);
            }
            else
            {
                m_log.Warn(agent.Name + " requested object owners for unknown parcel " + request.ParcelData.LocalID);
            }
        }
            private WaitableObject(
                WaitableObjectType type,
                int initialSignalCount,
                int maximumSignalCount,
                OwnershipInfo ownershipInfo)
            {
                Debug.Assert(initialSignalCount >= 0);
                Debug.Assert(maximumSignalCount > 0);
                Debug.Assert(initialSignalCount <= maximumSignalCount);

                _type               = type;
                _signalCount        = initialSignalCount;
                _maximumSignalCount = maximumSignalCount;
                _ownershipInfo      = ownershipInfo;
            }
 public SelectionCriteria(bool isAgent, bool isBuilding, bool isControllable, ECondition condition, OwnershipInfo ownership)
 {
     this._isAgent        = isAgent;
     this._isBuilding     = isBuilding;
     this._isControllable = isControllable;
     if (condition == ECondition.And)
     {
         this._op = (a, b) => a & b;
     }
     else
     {
         this._op = (a, b) => a | b;
     }
     this._ownership = ownership;
 }
            public static int Wait(
                WaitableObject[] waitableObjects,
                int count,
                bool waitForAll,
                ThreadWaitInfo waitInfo,
                int timeoutMilliseconds,
                bool interruptible,
                bool prioritize,
                WaitHandle[] waitHandlesForAbandon)
            {
                s_lock.VerifyIsNotLocked();
                Debug.Assert(waitInfo != null);
                Debug.Assert(waitInfo.Thread == RuntimeThread.CurrentThread);

                Debug.Assert(waitableObjects != null);
                Debug.Assert(waitableObjects.Length >= count);
                Debug.Assert(count > 1);
                Debug.Assert(timeoutMilliseconds >= -1);

                bool needToWait = false;

                s_lock.Acquire();
                try
                {
                    if (interruptible && waitInfo.CheckAndResetPendingInterrupt)
                    {
                        throw new ThreadInterruptedException();
                    }

                    if (!waitForAll)
                    {
                        // Check if any is already signaled
                        for (int i = 0; i < count; ++i)
                        {
                            WaitableObject waitableObject = waitableObjects[i];
                            Debug.Assert(waitableObject != null);

                            if (waitableObject.IsSignaled)
                            {
                                bool isAbandoned = waitableObject.IsAbandonedMutex;
                                waitableObject.AcceptSignal(waitInfo);
                                if (isAbandoned)
                                {
                                    if (waitHandlesForAbandon == null)
                                    {
                                        throw new AbandonedMutexException();
                                    }
                                    else
                                    {
                                        throw new AbandonedMutexException(i, waitHandlesForAbandon[i]);
                                    }
                                }
                                return(i);
                            }

                            if (waitableObject.IsMutex)
                            {
                                OwnershipInfo ownershipInfo = waitableObject._ownershipInfo;
                                if (ownershipInfo.Thread == waitInfo.Thread)
                                {
                                    if (!ownershipInfo.CanIncrementReacquireCount)
                                    {
                                        throw new OverflowException(SR.Overflow_MutexReacquireCount);
                                    }
                                    ownershipInfo.IncrementReacquireCount();
                                    return(i);
                                }
                            }
                        }
                    }
                    else
                    {
                        // Check if all are already signaled
                        bool areAllSignaled      = true;
                        bool isAnyAbandonedMutex = false;
                        for (int i = 0; i < count; ++i)
                        {
                            WaitableObject waitableObject = waitableObjects[i];
                            Debug.Assert(waitableObject != null);

                            if (waitableObject.IsSignaled)
                            {
                                if (!isAnyAbandonedMutex && waitableObject.IsAbandonedMutex)
                                {
                                    isAnyAbandonedMutex = true;
                                }
                                continue;
                            }

                            if (waitableObject.IsMutex)
                            {
                                OwnershipInfo ownershipInfo = waitableObject._ownershipInfo;
                                if (ownershipInfo.Thread == waitInfo.Thread)
                                {
                                    if (!ownershipInfo.CanIncrementReacquireCount)
                                    {
                                        throw new OverflowException(SR.Overflow_MutexReacquireCount);
                                    }
                                    continue;
                                }
                            }

                            areAllSignaled = false;
                            break;
                        }

                        if (areAllSignaled)
                        {
                            for (int i = 0; i < count; ++i)
                            {
                                WaitableObject waitableObject = waitableObjects[i];
                                if (waitableObject.IsSignaled)
                                {
                                    waitableObject.AcceptSignal(waitInfo);
                                    continue;
                                }

                                Debug.Assert(waitableObject.IsMutex);
                                OwnershipInfo ownershipInfo = waitableObject._ownershipInfo;
                                Debug.Assert(ownershipInfo.Thread == waitInfo.Thread);
                                ownershipInfo.IncrementReacquireCount();
                            }

                            if (isAnyAbandonedMutex)
                            {
                                throw new AbandonedMutexException();
                            }
                            return(0);
                        }
                    }

                    if (timeoutMilliseconds == 0)
                    {
                        return(WaitHandle.WaitTimeout);
                    }

                    waitableObjects = null; // no need to clear this anymore, RegisterWait / Wait will take over from here
                    waitInfo.RegisterWait(count, prioritize, waitForAll);
                    needToWait = true;
                }
                finally
                {
                    if (waitableObjects != null)
                    {
                        for (int i = 0; i < count; ++i)
                        {
                            waitableObjects[i] = null;
                        }
                    }

                    // Once the wait function is called, it will release the lock
                    if (!needToWait)
                    {
                        s_lock.Release();
                    }
                }

                return(waitInfo.Wait(timeoutMilliseconds, interruptible, waitHandlesForAbandon, isSleep: false));
            }
            public static int Wait(
                WaitableObject?[]?waitableObjects,
                int count,
                bool waitForAll,
                ThreadWaitInfo waitInfo,
                int timeoutMilliseconds,
                bool interruptible,
                bool prioritize)
            {
                s_lock.VerifyIsNotLocked();
                Debug.Assert(waitInfo != null);
                Debug.Assert(waitInfo.Thread == Thread.CurrentThread);

                Debug.Assert(waitableObjects != null);
                Debug.Assert(waitableObjects.Length >= count);
                Debug.Assert(count > 1);
                Debug.Assert(timeoutMilliseconds >= -1);

                var lockHolder = new LockHolder(s_lock);

                try
                {
                    if (interruptible && waitInfo.CheckAndResetPendingInterrupt)
                    {
                        lockHolder.Dispose();
                        throw new ThreadInterruptedException();
                    }

                    if (!waitForAll)
                    {
                        // Check if any is already signaled
                        for (int i = 0; i < count; ++i)
                        {
                            WaitableObject waitableObject = waitableObjects[i] !;
                            Debug.Assert(waitableObject != null);

                            if (waitableObject.IsSignaled)
                            {
                                bool isAbandoned = waitableObject.IsAbandonedMutex;
                                waitableObject.AcceptSignal(waitInfo);
                                if (isAbandoned)
                                {
                                    return(WaitHandle.WaitAbandoned + i);
                                }
                                return(WaitHandle.WaitSuccess + i);
                            }

                            if (waitableObject.IsMutex)
                            {
                                OwnershipInfo ownershipInfo = waitableObject._ownershipInfo !;
                                if (ownershipInfo.Thread == waitInfo.Thread)
                                {
                                    if (!ownershipInfo.CanIncrementReacquireCount)
                                    {
                                        lockHolder.Dispose();
                                        throw new OverflowException(SR.Overflow_MutexReacquireCount);
                                    }
                                    ownershipInfo.IncrementReacquireCount();
                                    return(WaitHandle.WaitSuccess + i);
                                }
                            }
                        }
                    }
                    else
                    {
                        // Check if all are already signaled
                        bool areAllSignaled      = true;
                        bool isAnyAbandonedMutex = false;
                        for (int i = 0; i < count; ++i)
                        {
                            WaitableObject waitableObject = waitableObjects[i] !;
                            Debug.Assert(waitableObject != null);

                            if (waitableObject.IsSignaled)
                            {
                                if (!isAnyAbandonedMutex && waitableObject.IsAbandonedMutex)
                                {
                                    isAnyAbandonedMutex = true;
                                }
                                continue;
                            }

                            if (waitableObject.IsMutex)
                            {
                                OwnershipInfo ownershipInfo = waitableObject._ownershipInfo !;
                                if (ownershipInfo.Thread == waitInfo.Thread)
                                {
                                    if (!ownershipInfo.CanIncrementReacquireCount)
                                    {
                                        lockHolder.Dispose();
                                        throw new OverflowException(SR.Overflow_MutexReacquireCount);
                                    }
                                    continue;
                                }
                            }

                            areAllSignaled = false;
                            break;
                        }

                        if (areAllSignaled)
                        {
                            for (int i = 0; i < count; ++i)
                            {
                                WaitableObject waitableObject = waitableObjects[i] !;
                                if (waitableObject.IsSignaled)
                                {
                                    waitableObject.AcceptSignal(waitInfo);
                                    continue;
                                }

                                Debug.Assert(waitableObject.IsMutex);
                                OwnershipInfo ownershipInfo = waitableObject._ownershipInfo !;
                                Debug.Assert(ownershipInfo.Thread == waitInfo.Thread);
                                ownershipInfo.IncrementReacquireCount();
                            }

                            if (isAnyAbandonedMutex)
                            {
                                lockHolder.Dispose();
                                throw new AbandonedMutexException();
                            }
                            return(WaitHandle.WaitSuccess);
                        }
                    }

                    if (timeoutMilliseconds == 0)
                    {
                        return(WaitHandle.WaitTimeout);
                    }

                    waitableObjects = null; // no need to clear this anymore, RegisterWait / Wait will take over from here

                    waitInfo.RegisterWait(count, prioritize, waitForAll);
                    return(waitInfo.Wait(timeoutMilliseconds, interruptible, isSleep: false, ref lockHolder));
                }
                finally
                {
                    lockHolder.Dispose();

                    if (waitableObjects != null)
                    {
                        for (int i = 0; i < count; ++i)
                        {
                            waitableObjects[i] = null;
                        }
                    }
                }
            }
 /// <summary>
 /// OwnershipInfoOrProduct as OwnershipInfo.
 /// </summary>
 /// <param name="ownershipInfo">OwnershipInfoOrProduct as OwnershipInfo.</param>
 public OwnershipInfoOrProduct(OwnershipInfo ownershipInfo)
 {
     AsOwnershipInfo = ownershipInfo;
 }
Example #10
0
        private void ParcelObjectOwnersRequestHandler(Packet packet, LLAgent agent)
        {
            ParcelObjectOwnersRequestPacket request = (ParcelObjectOwnersRequestPacket)packet;

            SceneParcel parcel;
            if (m_parcels.TryGetParcel(request.ParcelData.LocalID, out parcel))
            {
                ParcelObjectOwnersReplyPacket reply = new ParcelObjectOwnersReplyPacket();
                Dictionary<UUID, OwnershipInfo> owners = new Dictionary<UUID, OwnershipInfo>();

                lock (parcel.ParcelEntities)
                {
                    foreach (ISceneEntity entity in parcel.ParcelEntities.Values)
                    {
                        // Skip child entities
                        if (entity is ILinkable && ((ILinkable)entity).Parent != null)
                            continue;

                        OwnershipInfo count;
                        if (!owners.TryGetValue(entity.OwnerID, out count))
                        {
                            count = new OwnershipInfo();
                            count.IsGroupOwned = false; // FIXME: Need to track group ownership
                            count.OnlineStatus = false; // FIXME: m_permissions.IsOnline(agent.ID, entity.OwnerID);

                            owners.Add(entity.OwnerID, count);
                        }

                        ++count.Count;

                    }
                }

                reply.Data = new ParcelObjectOwnersReplyPacket.DataBlock[owners.Count];
                int i = 0;
                foreach (KeyValuePair<UUID, OwnershipInfo> kvp in owners)
                {
                    reply.Data[i++] = new ParcelObjectOwnersReplyPacket.DataBlock
                    {
                        Count = kvp.Value.Count,
                        OwnerID = kvp.Key,
                        IsGroupOwned = kvp.Value.IsGroupOwned,
                        OnlineStatus = kvp.Value.OnlineStatus
                    };
                }

                m_udp.SendPacket(agent, reply, ThrottleCategory.Task, true);
            }
            else
            {
                m_log.Warn(agent.Name + " requested object owners for unknown parcel " + request.ParcelData.LocalID);
            }
        }