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