public bool TryEnqueue(T item, int timeoutMilliseconds = 0) { if (item == null) { return(false); } //The method only throws exception on thread lock timeout using (IWaitable syncLock = SyncRoot.Enter(timeoutMilliseconds) as IWaitable) { if (IsDisposing || IsDisposed) { return(false); } if (m_count == m_size) { return(false); } m_items[m_tail++] = item; // Place the new item immediately after tail, then increment tail pos m_tail %= m_size; // Modulus new tail pos with size so queue items will wrap around m_count++; // Count will never be more than size after incrementing here //Signal that an item has been enqueued to unblock waiting //dequeue threads syncLock.PulseAll(); return(true); } }
public bool TryDequeue(out T item, int timeoutMilliseconds = 0) { //This method only throws exception on thread lock timeout using (IWaitable syncRoot = SyncRoot.Enter(timeoutMilliseconds) as IWaitable) { if (IsDisposing || IsDisposed) { item = null; return(false); } if (m_count == 0) { item = null; return(false); } item = m_items[m_head]; // Get item at head of queue m_items[m_head++] = null; // Clear item at head of queue then increment head pos m_head %= m_size; // Modulus new head pos with size so queue items will wrap around m_count--; // Count will never be less than zero after decrementing here //Signal that an item has been dequeued to unblock waiting //enqueue threads syncRoot.PulseAll(); return(true); } }
void IDisposable.Dispose() { using (SyncRoot.Enter()) { if (IsDisposed || IsDisposing) { return; } IsDisposing = true; } try { Dispose(true); } catch (Exception) { // Disposing so not much we can do with this exception } finally { IsDisposed = true; } }
public void Set(T token) { using (SyncRoot.Enter()) { var signal = GetSignal(token); signal.Set(); } }
protected override void Dispose(bool disposing) { using (SyncRoot.Enter()) { Clear(); m_items = null; } }
private AutoResetEvent GetSignal(T token) { using (SyncRoot.Enter()) { if (!m_signals.ContainsKey(token)) { m_signals[token] = new AutoResetEvent(false); } return(m_signals[token]); } }
public void Clear() { using (IWaitable syncLock = SyncRoot.Enter() as IWaitable) { //Unblock waiting threads syncLock.PulseAll(); m_count = 0; m_head = 0; m_tail = 0; m_items = new T[m_size]; } }
/// <summary> /// <c>Release</c> an object and add it back into the pool - increases pool size if the pool is full /// </summary> /// <param name="item">the object released back into the pool</param> /// <exception cref="ObjectDisposedException">throws when accessed during or after disposal</exception> public override void Release(T item) { if (!TryRelease(item)) //Tf the pool is full { using (SyncRoot.Enter()) { if (IsDisposing || IsDisposed) { throw new ObjectDisposedException(nameof(PrimitiveObjectPool <T>)); } m_internalStorage.Add(item); //This will increment storage bag count Size++; } } }
public void Enqueue(T item, int timeoutMilliseconds = -1) { if (item == null) { throw new ArgumentNullException("item", "item cannot be null"); } if (IsDisposing || IsDisposed) { throw new ObjectDisposedException(nameof(BoundedBlockingQueue <T>)); } using (IWaitable syncLock = SyncRoot.Enter(timeoutMilliseconds) as IWaitable) { //While the queue is full, wait for an empty space //Timeout won't be exact if multiple enqueues are blocked on a full queue //So a dequeue could be followed by a different enqueue so this will wait //for another loop while (m_count == m_size) { //Wait for a pulse from a dequeue if (!syncLock.Wait(timeoutMilliseconds)) { throw new TimeoutException("Enqueue timed out while waiting for available queue space"); } //Double check not disposed since waiting for available space if (IsDisposing || IsDisposed) { throw new ObjectDisposedException(nameof(BoundedBlockingQueue <T>)); } } m_items[m_tail++] = item; // Place the new item immediately after tail, then increment tail pos m_tail %= m_size; // Modulus new tail pos with size so queue items will wrap around m_count++; // Count will never be more than size after incrementing here //Signal that an item has been enqueued to unblock waiting //dequeue threads syncLock.PulseAll(); } }
/// <summary> /// Adds a new arena team member /// Calls ArenaTeamMgr.OnJoinTeam /// </summary> /// <param name="chr">character to add</param> /// <returns>ArenaTeamMember of new member</returns> public ArenaTeamMember AddMember(CharacterRecord chr) { ArenaTeamMember newMember; if (Members.Count >= Type * 2) { return(null); } SyncRoot.Enter(); try { if (Members.TryGetValue(chr.EntityLowId, out newMember)) { return(newMember); } newMember = new ArenaTeamMember(chr, this, false); newMember.Character.SetArenaTeamInfoField(Slot, ArenaTeamInfoType.ARENA_TEAM_ID, Id); newMember.Character.SetArenaTeamInfoField(Slot, ArenaTeamInfoType.ARENA_TEAM_MEMBER, 1); Members.Add(newMember.Id, newMember); newMember.Create(); Update(); } catch (Exception e) { LogUtil.ErrorException(e, string.Format("Could not add member {0} to arena team {1}", chr, this)); return(null); } finally { SyncRoot.Exit(); } ArenaMgr.RegisterArenaTeamMember(newMember); //ArenaTeamHandler.SendEventToTeam(this, ArenaTeamEvents.JOINED_SS, newMember); return(newMember); }
/// <summary> /// <c>Obtain</c> and remove an object from the pool - increases pool size if the pool is empty /// </summary> /// <returns>returns an object of type <typeparamref name="T"/> from the pool</returns> /// <exception cref="ObjectDisposedException">throws when accessed during or after disposal</exception> public override T Obtain() { if (TryObtain(out T item)) { return(item); } else //If the pool is empty { using (SyncRoot.Enter()) { if (IsDisposing || IsDisposed) { throw new ObjectDisposedException(nameof(PrimitiveObjectPool <T>)); } InUse++; Size++; //Increment Size so releasing item will just add to pool in TryRelease return(new T()); //Create new item } } }
public bool TryPeek(out T item, int timeoutMilliseconds = 0) { //This method only throws exception on thread lock timeout using (SyncRoot.Enter(timeoutMilliseconds)) { if (IsDisposing || IsDisposed) { item = null; return(false); } if (m_count == 0) { item = null; return(false); } item = m_items[m_head]; return(true); } }
/// <summary> /// <c>TryObtain</c> an object and remove it from the pool - does not throw an exception if pool is empty /// </summary> /// <param name="item">the object obtained from the pool, if successful - null if unsuccessful</param> /// <returns>returns true if successful, false if unsuccessful i.e. pool is empty</returns> /// <exception cref="ObjectDisposedException">throws when accessed during or after disposal</exception> public bool TryObtain(out T item) { using (SyncRoot.Enter()) { //This is called from Obtain so only need to check dispose state here if (IsDisposing || IsDisposed) { throw new ObjectDisposedException(nameof(PrimitiveObjectPool <T>)); } if (m_internalStorage.TryTake(out item)) //This will decrement count { InUse++; return(true); } else //if bag is empty { return(false); } } }
public T Peek(int timeoutMilliseconds = -1, bool waitForEnqueue = false) { using (IWaitable syncLock = SyncRoot.Enter(timeoutMilliseconds) as IWaitable) { if (IsDisposing || IsDisposed) { throw new ObjectDisposedException(nameof(BoundedBlockingQueue <T>)); } if (m_count == 0) { if (waitForEnqueue) { //While queue is empty, wait for an item to enqueue while (m_count == 0) { //Wait for a signal from an enqueue if (!syncLock.Wait(timeoutMilliseconds)) { throw new TimeoutException("Dequeue timed out while waiting for queue item to dequeue"); } //Double check not disposed since waiting for item to be enqueued if (IsDisposing || IsDisposed) { throw new ObjectDisposedException(nameof(BoundedBlockingQueue <T>)); } } } else { throw new InvalidOperationException("Bounded Blocking Queue is empty"); } } T value = m_items[m_head]; return(value); } }
public T Dequeue(int timeoutMilliseconds = -1) { if (IsDisposing || IsDisposed) { throw new ObjectDisposedException(nameof(BoundedBlockingQueue <T>)); } using (IWaitable syncLock = SyncRoot.Enter(timeoutMilliseconds) as IWaitable) { //Similar reasoning for here from Enqueue method //While queue is empty, wait for an item to enqueue while (m_count == 0) { //Wait for a signal from an enqueue if (!syncLock.Wait(timeoutMilliseconds)) { throw new TimeoutException("Dequeue timed out while waiting for queue item to dequeue"); } //Double check not disposed since waiting for item to be enqueued if (IsDisposing || IsDisposed) { throw new ObjectDisposedException(nameof(BoundedBlockingQueue <T>)); } } T value = m_items[m_head]; // Get item at head of queue m_items[m_head++] = null; // Clear item at head of queue then increment head pos m_head %= m_size; // Modulus new head pos with size so queue items will wrap around m_count--; // Count will never be less than zero after decrementing here //Signal that an item has been dequeued to unblock waiting //enqueue threads syncLock.PulseAll(); return(value); } }
/// <summary> /// <c>TryRelease</c> an object and add it back into the pool - does not throw exception if pool is full /// </summary> /// <param name="item">the object released back into the pool</param> /// <returns>returns true if successful, false if successful i.e. if pool is full</returns> /// <exception cref="ObjectDisposedException">throws when accessed during or after disposal</exception> public bool TryRelease(T item) { using (SyncRoot.Enter()) { //This is called from Obtain so only need to check dispose state here if (IsDisposing || IsDisposed) { throw new ObjectDisposedException(nameof(PrimitiveObjectPool <T>)); } //If storage bag is full i.e., equal to initial size, don't release item into bag if (m_internalStorage.Count == Size) { return(false); } else { m_internalStorage.Add(item); //This will increment storage bag count InUse--; return(true); } } }
public void Enter() { SyncRoot.Enter(); }