예제 #1
0
        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);
            }
        }
예제 #4
0
        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);
        }
예제 #6
0
        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);
 }