public void Put(E body) { MonitorUtilities.EnterUninterruptedly(this.monitor, out _); var message = new Message <E>(body); producers.Add(message);; Monitor.Exit(this.monitor); }
public void Await(object monitor, int timeToWait) { MonitorUtilities.EnterUninterruptedly(this.condition, out _); Monitor.Exit(monitor); Monitor.Wait(this.condition, timeToWait); MonitorUtilities.EnterUninterruptedly(monitor, out _); }
public List <T> TakeMessagePacket(int timeout) { Packet <T> packet = default; try { MonitorUtilities.EnterUninterruptedly(this.monitor, out var interrupted); packet = this.packets.FirstOrDefault(existingPacket => existingPacket.IsComplete() && !existingPacket.hasWaiter); if (packet == default) { packet = new Packet <T>(packetSize); this.packets.Add(packet); } packet.hasWaiter = true; var timer = new CrossCutting.Timer(timeout); while (true) { if (packet.IsComplete()) { this.packets.Remove(packet); return(packet.messages); } if (timer.IsExpired()) { packet.hasWaiter = false; return(null); } packet.Await(monitor, timer.GetTimeToWait()); } } catch (ThreadInterruptedException) { if (packet.IsComplete()) { this.packets.Remove(packet); Thread.CurrentThread.Interrupt(); return(packet.messages); } packet.hasWaiter = false; throw; } finally { Monitor.Exit(monitor); } }
public bool Transfer(E body, int timeout) { Message <E> message = default; try { MonitorUtilities.EnterUninterruptedly(monitor, out _); message = this.consumers.First(); if (message != default) { this.consumers.Remove(message); Monitor.Exit(this.monitor); message.body = body; message.NotifyWaiter(); return(true); } message = new Message <E>(body, condition: new object()); this.producers.Add(message); var timer = new CrossCutting.Timer(timeout); while (true) { Monitor.Wait(timeout); if (message.body != default) { Monitor.Exit(this.monitor); return(true); } if (timer.IsExpired()) { this.producers.Remove(message); Monitor.Exit(this.monitor); return(false); } } } catch (ThreadInterruptedException) { if (message?.body != default) { Monitor.Exit(this.monitor); Thread.CurrentThread.Interrupt(); return(true); } Monitor.Exit(this.monitor); throw; } }
public void PutMessage(T message) { MonitorUtilities.EnterUninterruptedly(this.monitor, out _); var packet = this.packets.FirstOrDefault(p => !p.IsComplete()); if (packet == default) { packet = new Packet <T>(this.packetSize); this.packets.Add(packet); } packet.messages.Add(message); if (packet.hasWaiter && packet.IsComplete()) { this.packets.Remove(packet); packet.NotifyWaiter(); } Monitor.Exit(this.monitor); }
public E Take(int timeout) { Message <E> message = default; try { MonitorUtilities.EnterUninterruptedly(monitor, out _); message = this.producers.First(); if (message != default) { this.producers.Remove(message); Monitor.Exit(this.monitor); //condition might be default if it was added to the producers queue by Put() if (message.condition != default) { message.NotifyWaiter(); } return(message.body); } message = new Message <E>(default, condition: new object());
public void NotifyWaiter() { MonitorUtilities.EnterUninterruptedly(this.condition, out _); Monitor.Pulse(this.condition); Monitor.Exit(this.condition); }