private bool Wait(long position, long comparand, int ms, bool isInt32, out bool comparandEquals) { object syncRoot = this.SyncRoot; bool exitAtFinally = true; Monitor.Enter(syncRoot); try { // compare value with bytes in position as a signed int or long // because only Int32Array and BigInt64Array are waitable through the Atomics object comparandEquals = (isInt32 ? GetInt32(position) : GetInt64Shared(position)) == comparand; if (!comparandEquals) { return(false); } WaiterHandle handle = new WaiterHandle(); if (waiterLists == null) { waiterLists = new Dictionary <long, List <WaiterHandle> >(); } List <WaiterHandle> list; if (!waiterLists.TryGetValue(position, out list)) { list = new List <WaiterHandle>(); waiterLists.Add(position, list); } list.Add(handle); exitAtFinally = false; Monitor.Exit(syncRoot); // add extra millisecond to ensure that // thread does not wake up within a milliseconds before desired amount of time if (!handle.WaitOne(ms < 0 ? ms : ms + 1)) { lock (syncRoot) { list.Remove(handle); } return(false); } return(true); } finally { if (exitAtFinally) { Monitor.Exit(syncRoot); } } }
public int Notify(long position, int count) { lock (this.SyncRoot) { int remaining = count; if (waiterLists != null && waiterLists.TryGetValue(position, out List <WaiterHandle> list)) { while (remaining > 0 && list.Count > 0) { WaiterHandle handle = list[0]; if (handle.Set()) { remaining--; } list.RemoveAt(0); } } return(count - remaining); } }