using System;
using System.Threading;
using ZB.MOM.WW.MxGateway.Worker.Sta;
namespace ZB.MOM.WW.MxGateway.Worker.Tests.TestSupport;
///
/// Test that counts pump calls and can be armed
/// to throw from the next pump, so tests can observe the STA loop's pump
/// interleaving and drive a post-start loop death without a real Win32
/// message queue. The idle wait blocks on the command wake event exactly
/// like the production pump's MsgWaitForMultipleObjectsEx does.
///
internal sealed class ControllableMessagePump : IStaMessagePump
{
private int pumpCount;
private Exception? throwOnNextPump;
/// Gets the number of calls so far.
public int PumpCount => Volatile.Read(ref pumpCount);
/// Arms the pump to throw from its next pump call.
/// The exception to throw once.
public void ThrowOnNextPump(Exception exception)
{
Volatile.Write(ref throwOnNextPump, exception);
}
///
public void WaitForWorkOrMessages(WaitHandle commandWakeEvent, TimeSpan timeout)
{
commandWakeEvent.WaitOne(timeout);
}
///
public int PumpPendingMessages()
{
Interlocked.Increment(ref pumpCount);
Exception? exception = Interlocked.Exchange(ref throwOnNextPump, null);
if (exception is not null)
{
throw exception;
}
return 0;
}
}