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; } }