Ejemplo n.º 1
0
        /// <summary>
        /// Logs all the messages that the tool wrote to either stderr or stdout.
        /// The messages are read out of the given data queue. This method is a
        /// helper for the <see cref="LogMessagesFromStandardError"/>() and <see
        /// cref="LogMessagesFromStandardOutput"/>() methods.
        /// </summary>
        /// <param name="dataQueue"></param>
        /// <param name="dataAvailableSignal"></param>
        /// <param name="messageImportance"></param>
        /// <param name="queueType"></param>
        private static void LogMessagesFromStandardErrorOrOutput
        (
            Queue dataQueue,
            ManualResetEvent dataAvailableSignal,
            //MessageImportance messageImportance,
            StandardOutputOrErrorQueueType queueType
        )
        {
            //ErrorUtilities.VerifyThrow(dataQueue != null,
            //    "The data queue must be available.");

            // synchronize access to the queue -- this is a producer-consumer problem
            // NOTE: the synchronization problem here is actually not about the queue
            // at all -- if we only cared about reading from and writing to the queue,
            // we could use a synchronized wrapper around the queue, and things would
            // work perfectly; the synchronization problem here is actually around the
            // ManualResetEvent -- while a ManualResetEvent itself is a thread-safe
            // type, the information we infer from the state of a ManualResetEvent is
            // not thread-safe; because a ManualResetEvent does not have a ref count,
            // we cannot safely set (or reset) it outside of a synchronization block;
            // therefore instead of using synchronized queue wrappers, we just lock the
            // entire queue, empty it, and reset the ManualResetEvent before releasing
            // the lock; this also allows proper alternation between the stderr and
            // stdout queues -- otherwise we would continuously read from one queue and
            // starve the other; locking out the producer allows the consumer to
            // alternate between the queues
            lock (dataQueue.SyncRoot)
            {
                while (dataQueue.Count > 0)
                {
                    string errorOrOutMessage = dataQueue.Dequeue() as String;
                    Console.WriteLine(errorOrOutMessage);
                    //if (!LogStandardErrorAsError || queueType == StandardOutputOrErrorQueueType.StandardOutput)
                    //{
                    //    this.LogEventsFromTextOutput(errorOrOutMessage, messageImportance);
                    //}
                    //else if (LogStandardErrorAsError && queueType == StandardOutputOrErrorQueueType.StandardError)
                    //{
                    //    Log.LogError(errorOrOutMessage);
                    //}
                }

                //ErrorUtilities.VerifyThrow(dataAvailableSignal != null,
                //    "The signalling event must be available.");

                // the queue is empty, so reset the notification
                // NOTE: intentionally, do the reset inside the lock, because
                // ManualResetEvents don't have ref counts, and we want to make
                // sure we don't reset the notification just after the producer
                // signals it
                dataAvailableSignal.Reset();
            }
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Logs all the messages that the tool wrote to either stderr or stdout.
        /// The messages are read out of the given data queue. This method is a
        /// helper for the <see cref="LogMessagesFromStandardError"/>() and <see
        /// cref="LogMessagesFromStandardOutput"/>() methods.
        /// </summary>
        /// <param name="dataQueue"></param>
        /// <param name="dataAvailableSignal"></param>
        /// <param name="messageImportance"></param>
        private void LogMessagesFromStandardErrorOrOutput
        (
            Queue dataQueue,
            ManualResetEvent dataAvailableSignal,
            MessageImportance messageImportance,
            StandardOutputOrErrorQueueType queueType
        )
        {
            ErrorUtilities.VerifyThrow(dataQueue != null,
                "The data queue must be available.");

            // synchronize access to the queue -- this is a producer-consumer problem
            // NOTE: the synchronization problem here is actually not about the queue
            // at all -- if we only cared about reading from and writing to the queue,
            // we could use a synchronized wrapper around the queue, and things would
            // work perfectly; the synchronization problem here is actually around the
            // ManualResetEvent -- while a ManualResetEvent itself is a thread-safe
            // type, the information we infer from the state of a ManualResetEvent is
            // not thread-safe; because a ManualResetEvent does not have a ref count,
            // we cannot safely set (or reset) it outside of a synchronization block;
            // therefore instead of using synchronized queue wrappers, we just lock the
            // entire queue, empty it, and reset the ManualResetEvent before releasing
            // the lock; this also allows proper alternation between the stderr and
            // stdout queues -- otherwise we would continuously read from one queue and
            // starve the other; locking out the producer allows the consumer to
            // alternate between the queues
            lock (dataQueue.SyncRoot)
            {
                while (dataQueue.Count > 0)
                {
                    string errorOrOutMessage = dataQueue.Dequeue() as String;
                    if (!LogStandardErrorAsError || queueType == StandardOutputOrErrorQueueType.StandardOutput)
                    {
                        this.LogEventsFromTextOutput(errorOrOutMessage, messageImportance);
                    }
                    else if (LogStandardErrorAsError && queueType == StandardOutputOrErrorQueueType.StandardError)
                    {
                        Log.LogError(errorOrOutMessage);
                    }
                }

                ErrorUtilities.VerifyThrow(dataAvailableSignal != null,
                    "The signalling event must be available.");

                // the queue is empty, so reset the notification
                // NOTE: intentionally, do the reset inside the lock, because
                // ManualResetEvents don't have ref counts, and we want to make
                // sure we don't reset the notification just after the producer
                // signals it
                dataAvailableSignal.Reset();
            }
        }
Ejemplo n.º 3
0
 private void LogMessagesFromStandardErrorOrOutput(Queue dataQueue, ManualResetEvent dataAvailableSignal, MessageImportance messageImportance, StandardOutputOrErrorQueueType queueType)
 {
     ErrorUtilities.VerifyThrow(dataQueue != null, "The data queue must be available.");
     lock (dataQueue.SyncRoot)
     {
         while (dataQueue.Count > 0)
         {
             string singleLine = dataQueue.Dequeue() as string;
             if (!this.LogStandardErrorAsError || (queueType == StandardOutputOrErrorQueueType.StandardOutput))
             {
                 this.LogEventsFromTextOutput(singleLine, messageImportance);
             }
             else if (this.LogStandardErrorAsError && (queueType == StandardOutputOrErrorQueueType.StandardError))
             {
                 base.Log.LogError(singleLine, new object[0]);
             }
         }
         ErrorUtilities.VerifyThrow(dataAvailableSignal != null, "The signalling event must be available.");
         dataAvailableSignal.Reset();
     }
 }
Ejemplo n.º 4
0
 private void LogMessagesFromStandardErrorOrOutput(Queue dataQueue, ManualResetEvent dataAvailableSignal, MessageImportance messageImportance, StandardOutputOrErrorQueueType queueType)
 {
     ErrorUtilities.VerifyThrow(dataQueue != null, "The data queue must be available.");
     lock (dataQueue.SyncRoot)
     {
         while (dataQueue.Count > 0)
         {
             string singleLine = dataQueue.Dequeue() as string;
             if (!this.LogStandardErrorAsError || (queueType == StandardOutputOrErrorQueueType.StandardOutput))
             {
                 this.LogEventsFromTextOutput(singleLine, messageImportance);
             }
             else if (this.LogStandardErrorAsError && (queueType == StandardOutputOrErrorQueueType.StandardError))
             {
                 base.Log.LogError(singleLine, new object[0]);
             }
         }
         ErrorUtilities.VerifyThrow(dataAvailableSignal != null, "The signalling event must be available.");
         dataAvailableSignal.Reset();
     }
 }