fix(worker): StaWaitHelper regression tests + full-drain contract notes; consolidate wait P/Invoke
This commit is contained in:
@@ -0,0 +1,58 @@
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace ZB.MOM.WW.MxGateway.Worker.Sta;
|
||||
|
||||
/// <summary>
|
||||
/// The single declaration of the Win32 wait the worker's STA is built on.
|
||||
/// Both waiters use it: <see cref="StaMessagePump"/> for the runtime's outer
|
||||
/// idle wait, and <see cref="StaWaitHelper"/> for the inner completion waits
|
||||
/// a command performs while it already holds the apartment.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Deliberately one copy. This is the subtlest Win32 contract in the worker —
|
||||
/// the wake mask decides which events can wake the STA, and
|
||||
/// <see cref="MwmoInputAvailable"/> decides whether a message already seen by
|
||||
/// a <c>PeekMessage</c> still counts as a wake. Two copies of it could drift
|
||||
/// apart silently, and a divergence would show up only as COM events
|
||||
/// arriving late on a live provider.
|
||||
/// </remarks>
|
||||
internal static class StaNativeMethods
|
||||
{
|
||||
/// <summary>Return value of a failed wait (<c>WAIT_FAILED</c>).</summary>
|
||||
internal const uint MsgWaitFailed = 0xFFFFFFFF;
|
||||
|
||||
/// <summary>
|
||||
/// Wake even when the pending input has already been seen (but not
|
||||
/// removed) by an earlier <c>PeekMessage</c>. Both callers peek before
|
||||
/// they wait, so without this flag a message that arrived during the peek
|
||||
/// would not wake the wait that follows it.
|
||||
/// </summary>
|
||||
internal const uint MwmoInputAvailable = 0x0004;
|
||||
|
||||
/// <summary>Wake on any queued input, including sent and posted messages.</summary>
|
||||
internal const uint QsAllInput = 0x04FF;
|
||||
|
||||
/// <summary>
|
||||
/// Waits for the given handles, for queued input matching
|
||||
/// <paramref name="wakeMask"/>, or for the timeout — whichever comes
|
||||
/// first.
|
||||
/// </summary>
|
||||
/// <param name="count">Number of handles in <paramref name="handles"/>.</param>
|
||||
/// <param name="handles">Handles to wait on; marshaled as a pointer to the array.</param>
|
||||
/// <param name="milliseconds">Timeout in milliseconds; <c>0xFFFFFFFF</c> means INFINITE.</param>
|
||||
/// <param name="wakeMask">Input types that may wake the wait (<see cref="QsAllInput"/>).</param>
|
||||
/// <param name="flags">Wait flags (<see cref="MwmoInputAvailable"/>).</param>
|
||||
/// <returns>
|
||||
/// <c>WAIT_OBJECT_0 + i</c> for a signaled handle, <c>WAIT_OBJECT_0 + count</c>
|
||||
/// for available input, <c>WAIT_TIMEOUT</c> (258), or
|
||||
/// <see cref="MsgWaitFailed"/>.
|
||||
/// </returns>
|
||||
[DllImport("user32.dll", SetLastError = true)]
|
||||
internal static extern uint MsgWaitForMultipleObjectsEx(
|
||||
uint count,
|
||||
IntPtr[] handles,
|
||||
uint milliseconds,
|
||||
uint wakeMask,
|
||||
uint flags);
|
||||
}
|
||||
Reference in New Issue
Block a user