Skip to content

Instantly share code, notes, and snippets.

@rbmm
Created February 22, 2026 09:09
Show Gist options
  • Select an option

  • Save rbmm/2167d2ee35e877d48db5b4a5917046c5 to your computer and use it in GitHub Desktop.

Select an option

Save rbmm/2167d2ee35e877d48db5b4a5917046c5 to your computer and use it in GitHub Desktop.
namespace std
{
class latch
{
HANDLE _hEvent;
volatile LONG _Counter;
public:
latch(LONG Expected) : _Counter(Expected), _hEvent(CreateEventW(0,0,0,0))
{
}
~latch()
{
NtClose(_hEvent);
}
void count_down()
{
if (!InterlockedDecrement(&_Counter))
{
SetEvent(_hEvent);
}
}
void wait()
{
WaitForSingleObject(_hEvent, INFINITE);
}
};
};
void work_thread(std::latch* pl)
{
MessageBoxW(0, L"do some work", L"worked thread", MB_ICONINFORMATION);
pl->count_down();
}
VOID NTAPI work_cb (
_Inout_ PTP_CALLBACK_INSTANCE /*Instance*/,
_Inout_opt_ PVOID Context,
_Inout_ PTP_WORK Work
)
{
work_thread(reinterpret_cast<std::latch*>(Context));
TpReleaseWork(Work);
}
bool create_thread(PVOID arg)
{
PTP_WORK Work;
if (0 <= TpAllocWork(&Work, work_cb, arg, 0))
{
TpPostWork(Work);
return true;
}
return false;
}
void demo(ULONG n)
{
ASSERT(n);
std::latch l(n);
do
{
if (!create_thread(&l))
{
l.count_down();
}
} while (--n);
MessageBoxW(0, L"do some work", L"main thread", MB_ICONWARNING);
l.wait();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment