/// <summary> /// Adds the specified event to the state machine's event queue. /// </summary> /// <param name="nsfEvent">The event to queue.</param> /// <param name="isPriorityEvent">Flag indicating if the event should be queued to the back of the queue (false) or the front of the queue (true).</param> /// <param name="logEventQueued">Flag indicating if an event queued trace should be added to the trace log.</param> private void queueEvent(NSFEvent nsfEvent, bool isPriorityEvent, bool logEventQueued) { if (!isTopStateMachine()) { TopStateMachine.queueEvent(nsfEvent, isPriorityEvent, logEventQueued); return; } lock (stateMachineMutex) { // Do not allow events to be queued if terminating or terminated, // except for run to completion event, which may be queued if terminating to allow proper semantics to continue until terminated. if ((TerminationStatus == NSFEventHandlerTerminationStatus.EventHandlerTerminated) || ((TerminationStatus == NSFEventHandlerTerminationStatus.EventHandlerTerminating) && (nsfEvent != runToCompletionEvent))) { return; } // Handle special case of terminate event by setting status and queuing a single terminate event. // Terminate event must be the last event queued to guarantee safe deletion when it is handled. if (nsfEvent == terminateEvent) { if (TerminationStatus == NSFEventHandlerTerminationStatus.EventHandlerReady) { TerminationStatus = NSFEventHandlerTerminationStatus.EventHandlerTerminating; } } // Event limit detection looks for too many events queued for the state machine. // If more than the specified number of events are queued, the state machine will remove // its queued events, call the event limit actions, and stop after executing any events queued // by the limit actions. if ((EventLimitDetectionEnabled) && (QueuedEvents == EventLimit)) { EventThread.removeEventsFor(this); QueuedEvents = 0; EventLimitActions.execute(new NSFStateMachineContext(this, null, null, null, nsfEvent)); // Stop the state machine so that no more event processing occurs until started again stopStateMachine(); NSFTraceLog.PrimaryTraceLog.addTrace(NSFTraceTags.ErrorTag, NSFTraceTags.SourceTag, Name, NSFTraceTags.MessageTag, "EventLimit"); return; } nsfEvent.Destination = this; EventThread.queueEvent(nsfEvent, isPriorityEvent, logEventQueued); ++QueuedEvents; } }
public void queueEvent(NSFEvent nsfEvent) { lock (eventHandlerMutex) { // Do not allow events to be queued if terminating or terminated (i.e. not ready) if (TerminationStatus != NSFEventHandlerTerminationStatus.EventHandlerReady) { return; } // Handle special case of terminate event by setting status and queuing a single terminate event. // Terminate event must be the last event queued to guarantee safe deletion when it is handled. if (nsfEvent == terminateEvent) { if (TerminationStatus == NSFEventHandlerTerminationStatus.EventHandlerReady) { TerminationStatus = NSFEventHandlerTerminationStatus.EventHandlerTerminating; } } nsfEvent.Destination = this; EventThread.queueEvent(nsfEvent, false, LoggingEnabled); } }