Example #1
0
 void Enqueue(FilePacketArray filePacket)
 {
     filePacket.CopyTo(packetQueue[nextBufIndexToProduce]);
     nextBufIndexToProduce++;
     if (nextBufIndexToProduce == queueDepth)
     {
         nextBufIndexToProduce = 0;
     }
     queueFilledCount++;
 }
Example #2
0
        ReaderCompressorSharedState(int queueDepth, int packetSize)
        {
            this.queueDepth = queueDepth;
            this.packetSize = packetSize;
            packetQueue     = new FilePacketArray[queueDepth];
            for (var i = 0; i < queueDepth; i++)
            {
                packetQueue[i] = new FilePacketArray(0, packetSize);
            }

            eventsForProducer[(int)EventsForProducer.SpaceAppeared] = eventForNewSpaceInQueue;
            eventsForProducer[(int)EventsForProducer.Cancel]        = eventForWorkCancellation;

            eventsForConsumer[(int)EventsForConsumer.PacketAppeared] = eventForFirstPacketInQueue;
            eventsForConsumer[(int)EventsForConsumer.ReadCompleted]  = eventForInputCompletion;
            eventsForConsumer[(int)EventsForConsumer.Cancel]         = eventForWorkCancellation;
        }
Example #3
0
        /// <summary>
        /// Thread&apos;s execution body
        /// </summary>
        void RunThread()
        {
            try
            {
                using (var fileStream = File.OpenRead(file))
                {
                    int bytesRead;
                    var packet = new FilePacketArray(0, bufSize);
                    var count  = 0;

                    while ((bytesRead = fileStream.Read(packet.Buffer, 0, bufSize)) > 0)
                    {
                        packet.FilledLength = bytesRead;
                        outputState.Produce(packet, out var cancel);
                        if (cancel)
                        {
                            return;
                        }
                        packet.IncIndex();
                        count++;
                    }

                    if (count == 0) // If file is empty
                    {
                        packet.FilledLength = 0;
                        outputState.Produce(packet, out var cancel);
                    }

                    outputState.ReadCompleted();
                }
            }
            catch (IOException)
            {
                SafeCancel();
                Console.WriteLine("Could not read the file.");
            }
            catch (Exception ex)
            {
                SafeCancel();
                Console.WriteLine("Error in file reading thread: " + ex.ToString());
            }
        }
Example #4
0
        /// <summary>
        /// Saving &quot;packet&quot; of file
        /// </summary>
        /// <param name="filePacket">Piece of source file</param>
        /// <param name="cancel">Cancellation flag</param>
        public void Produce(FilePacketArray filePacket, out bool cancel)
        {
            Debug.Assert(filePacket != null, $"{nameof(filePacket)} is null");
            Debug.Assert(filePacket.Index >= 0, $"{nameof(filePacket)}.{nameof(filePacket.Index)} must be not negative zero-based index");

            var taken = true;

            mutex.WaitOne();
            try
            {
                cancel = cancelled;
                if (cancelled)
                {
                    return;
                }

                var eventType = EventsForProducer.SpaceExists;
                // If queue is full, start awaiting for free space
                while (queueFilledCount == queueDepth)
                {
                    taken = false;
                    mutex.ReleaseMutex();

                    eventType = (EventsForProducer)WaitHandle.WaitAny(eventsForProducer);
                    mutex.WaitOne();
                    taken = true;

                    if ((eventType == EventsForProducer.SpaceAppeared && queueFilledCount != queueDepth) ||
                        eventType == EventsForProducer.Cancel)
                    {
                        break;
                    }
                }
                switch (eventType)
                {
                case EventsForProducer.SpaceExists:
                case EventsForProducer.SpaceAppeared:
                    Enqueue(filePacket);
                    if (queueFilledCount == 1)     // If it is a first packet in queue, setting signal for consumers
                    {
                        eventForFirstPacketInQueue.Set();
                    }
                    if (eventType == EventsForProducer.SpaceAppeared && queueFilledCount == queueDepth)
                    {
                        eventForNewSpaceInQueue.Reset();     // Resetting our signal about appearing of free space
                    }
                    break;

                case EventsForProducer.Cancel:
                    cancel = true;
                    break;

                default:
                    Debug.Write($"Unsupported event type for producer: {Enum.GetName(typeof(EventsForProducer), eventType)}");
                    break;
                }
            }
            finally
            {
                if (taken)
                {
                    mutex.ReleaseMutex();
                }
            }
        }