Beispiel #1
0
            public volatile int lastSeqNumOut; // sequence number of the last message to have been taken from the queue (queue is likely empty if they are both the same)

            #endregion Fields

            #region Constructors

            public QueuedMesgSeqNumRange(ref QueuedMesgSeqNumRange rhs)
            {
                // grab the out sequence number before the in so that we are most inclusive when making a copy of another QueuedMesgSeqNumRange value.
                // order matters here since these are volatile (values may be written in the background by other threads while reading..)

                lastSeqNumOut = rhs.lastSeqNumOut;
                lastSeqNumIn = rhs.lastSeqNumIn;
            }
Beispiel #2
0
            public bool IsMessageStillInQueue(int testSeqNum)
            {
                lock (queueMutex)
                {
                    QueuedMesgSeqNumRange queuedMesgSeqNumRangeSnapshot = new QueuedMesgSeqNumRange(ref queuedMesgSeqNumRange);

                    return(queuedMesgSeqNumRangeSnapshot.IsMesgSeqNumInRange(testSeqNum));
                }
            }
Beispiel #3
0
            public bool IsMessageStillInQueue(int testSeqNum)
            {
                lock (queueMutex)
                {
                    QueuedMesgSeqNumRange queuedMesgSeqNumRangeSnapshot = new QueuedMesgSeqNumRange(ref queuedMesgSeqNumRange);

                    return queuedMesgSeqNumRangeSnapshot.IsMesgSeqNumInRange(testSeqNum);
                }
            }
Beispiel #4
0
                const double minDeliveryThreadSpinWaitPeriod = 0.050;           // 20 Hz

                /// <summary>
                /// This gives the method that is called by the internal service thread to pull messages from the back of the message queue and deliver them to the
                /// target LMH instances.
                /// </summary>
                protected void MainThreadFcn()
                {
                    if (targetLMHArray == null || !mesgQueue.IsEnabled || threadWakeupEvent == null)
                    {
                        mesgQueue.DisableQueue();

                        foreach (var lmh in targetLMHArray ?? emptyLMHArray)
                        {
                            lmh.Shutdown();
                        }

                        Utils.Asserts.TakeBreakpointAfterFault("QLMH thread Startup test failed");
                        return;
                    }

                    foreach (var lmh in targetLMHArray)
                    {
                        lmh.StartIfNeeded();
                    }

                    while (mesgQueue.IsEnabled)
                    {
                        threadWakeupEvent.Reset();

                        bool didAnything = false;

                        // process messages from a non-empty queue (or full)
                        if (mesgQueue.QueueCount != 0 || mesgQueue.IsQueueFull())
                        {
                            didAnything = true;
                            ServiceQueueDelivery(maxMessagesToDequePerIteration);
                        }

                        // detect seqNum based flush request and ask underlying lmh to flush after
                        // given seqNum is no longer in the mesgQueue
                        int flushReqSeqNumSnapshot = flushAfterSeqNum;
                        QueuedMesgSeqNumRange mesgQueueSeqNumRangeSnapshot = mesgQueueSeqNumRange;

                        if (NullMessageSeqNum != flushReqSeqNumSnapshot &&
                            !mesgQueueSeqNumRangeSnapshot.IsMesgSeqNumInRange(flushReqSeqNumSnapshot))
                        {
                            flushRequested   = true;
                            flushAfterSeqNum = NullMessageSeqNum;
                        }

                        if (flushRequested)     // when queue is empty then process flush request
                        {
                            didAnything    = true;
                            flushRequested = false;

                            foreach (var lmh in targetLMHArray)
                            {
                                lmh.Flush();
                            }
                        }

                        if (!didAnything)
                        {
                            threadWakeupEvent.WaitSec(minDeliveryThreadSpinWaitPeriod);
                        }
                    }

                    // service the queue until it is empty
                    while (mesgQueue.QueueCount != 0 || mesgQueue.IsQueueFull())
                    {
                        ServiceQueueDelivery(maxMessagesToDequePerIteration);
                    }

                    uint totalDroppedMesgs = mesgQueue.TotalDroppedMesgCount;

                    if (totalDroppedMesgs != 0)
                    {
                        LogShutdownDroppedMessagesMesg(totalDroppedMesgs);
                    }

                    foreach (var lmh in targetLMHArray)
                    {
                        lmh.Shutdown();
                    }
                }
Beispiel #5
0
                /// <summary>Query method that may be used to tell if message delivery for a given message is still in progress on this handler.</summary>
                public override bool IsMessageDeliveryInProgress(int testMesgSeqNum)
                {
                    QueuedMesgSeqNumRange mesgQueueSeqNumRangeSnapshot = mesgQueueSeqNumRange;

                    return(mesgQueueSeqNumRangeSnapshot.IsMesgSeqNumInRange(testMesgSeqNum));
                }
Beispiel #6
0
 /// <summary>
 /// Copy constructor.
 /// <para/>grab the out sequence number before the in so that we are most inclusive when making a copy of another QueuedMesgSeqNumRange value.
 /// order matters here since these are volatile (values may be written in the background by other threads while reading..)
 /// </summary>
 public QueuedMesgSeqNumRange(ref QueuedMesgSeqNumRange rhs)
 {
     lastSeqNumOut = rhs.lastSeqNumOut;
     lastSeqNumIn  = rhs.lastSeqNumIn;
 }