167 lines
5.5 KiB
C#
167 lines
5.5 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Diagnostics;
|
|
using System.Linq;
|
|
using System.Threading;
|
|
using System.Windows.Forms;
|
|
using DTS.Common.Utilities.Logging;
|
|
|
|
namespace DTS.Common.Utils
|
|
{
|
|
public class SecureQueue<T> : IDisposable where T : new()
|
|
{
|
|
public enum NullPolicy
|
|
{
|
|
DenyNull, // throw an exception if try to Enqueue null or zero length
|
|
SkipNull, // don't complain but don't enqueue null or zero length
|
|
AllowNull // let null's in too
|
|
}
|
|
|
|
protected Queue<T[]> ByteQueue;
|
|
protected object ByteQueueLock;
|
|
protected ManualResetEvent ByteQueueEvent;
|
|
protected NullPolicy _NullPolicy;
|
|
protected string Name;
|
|
protected Stopwatch StopWatch;
|
|
|
|
public SecureQueue(NullPolicy policy, string name)
|
|
{
|
|
StopWatch = new Stopwatch();
|
|
StopWatch.Start();
|
|
ByteQueue = new Queue<T[]>();
|
|
ByteQueueLock = new object();
|
|
ByteQueueEvent = new ManualResetEvent(false);
|
|
_NullPolicy = policy;
|
|
Name = name;
|
|
}
|
|
|
|
public void ResetEvent()
|
|
{
|
|
//latestReset = GetCaller();
|
|
ByteQueueEvent.Reset();
|
|
}
|
|
|
|
public void Enqueue(T[] newData)
|
|
{
|
|
try
|
|
{
|
|
lock (ByteQueueLock)
|
|
{
|
|
if (newData == null || newData.Length == 0)
|
|
{
|
|
switch (_NullPolicy)
|
|
{
|
|
case NullPolicy.DenyNull:
|
|
throw new ArgumentException("SecureQueue_Enqueue_Err1");
|
|
case NullPolicy.SkipNull:
|
|
return;
|
|
}
|
|
}
|
|
ByteQueue.Enqueue((T[])newData?.Clone());
|
|
if (Enums.DASFactory.DFConstantsAndEnums.ExtraCommunicationLogging)
|
|
{
|
|
APILogger.Log("Enqueing data", newData);
|
|
}
|
|
ByteQueueEvent.Set();
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
APILogger.LogString("SecureQueue.Enqueue: The queue(" + Name + ") threw an exception. " + ex.Message + " " + ex.StackTrace);
|
|
throw;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Wait for TimeoutMillisec milliseconds for data to arrive in the buffer. Returns false if it times out.
|
|
/// </summary>
|
|
/// <param name="timeoutMillisec"></param>
|
|
/// <returns>true if data has arrived, false if it times out</returns>
|
|
public bool WaitForData(int timeoutMillisec)
|
|
{
|
|
try
|
|
{
|
|
var result = ByteQueueEvent.WaitOne(timeoutMillisec, false);
|
|
return result;
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
APILogger.LogString("SecureQueue.WaitForData: The queue(" + Name + ") threw an exception. " + ex.Message + " " + ex.StackTrace);
|
|
}
|
|
return false;
|
|
}
|
|
|
|
public WaitHandle QueueWaitHandle => ByteQueueEvent;
|
|
|
|
public T[] Dequeue(bool resetEvent)
|
|
{
|
|
try
|
|
{
|
|
lock (ByteQueueLock)
|
|
{
|
|
ByteQueueEvent = new ManualResetEvent(false);
|
|
|
|
if (ByteQueue.Count == 0)
|
|
{
|
|
return new T[0];
|
|
}
|
|
if (ByteQueue.Count == 1)
|
|
{
|
|
var ret = ByteQueue.Dequeue();
|
|
return ret;
|
|
}
|
|
|
|
// count how much data we have
|
|
var totalBytes = ByteQueue.Sum(arr => arr.Length);
|
|
if (totalBytes == 0)
|
|
{
|
|
APILogger.LogString("SecureQueue.Dequeue: The queue(" + Name + ") has 0 bytes!");
|
|
}
|
|
// allocate that much
|
|
var result = new T[totalBytes];
|
|
var index = 0;
|
|
// now make one large array
|
|
while (ByteQueue.Any())
|
|
{
|
|
var element = ByteQueue.Dequeue();
|
|
Array.Copy(element, 0, result, index, element.Length);
|
|
index += element.Length;
|
|
}
|
|
return result;
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
APILogger.LogString("SecureQueue.Dequeue: The queue(" + Name + ") threw an exception. " + ex.Message + " " + ex.StackTrace);
|
|
}
|
|
return new T[0];
|
|
}
|
|
|
|
public void Flush()
|
|
{
|
|
try
|
|
{
|
|
lock (ByteQueueLock)
|
|
{
|
|
//latestFlush = GetCaller();
|
|
ByteQueueEvent = new ManualResetEvent(false);
|
|
ByteQueue.Clear();
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
APILogger.LogString("SecureQueue.Flush: The queue(" + Name + ") threw an exception. " + ex.Message + " " + ex.StackTrace);
|
|
}
|
|
}
|
|
|
|
public bool IsEmpty()
|
|
{
|
|
return ByteQueue.Count == 0;
|
|
}
|
|
|
|
public void Dispose()
|
|
{
|
|
}
|
|
}
|
|
}
|