Blame winpr/libwinpr/pool/test/TestPoolWork.c

Packit Service fa4841
Packit Service fa4841
#include <winpr/crt.h>
Packit Service fa4841
#include <winpr/pool.h>
Packit Service fa4841
#include <winpr/interlocked.h>
Packit Service fa4841
Packit Service fa4841
static LONG count = 0;
Packit Service fa4841
Packit Service fa4841
static void CALLBACK test_WorkCallback(PTP_CALLBACK_INSTANCE instance, void* context, PTP_WORK work)
Packit Service fa4841
{
Packit Service fa4841
	int index;
Packit Service fa4841
	BYTE a[1024];
Packit Service fa4841
	BYTE b[1024];
Packit Service fa4841
	BYTE c[1024];
Packit Service fa4841
	printf("Hello %s: %03" PRId32 " (thread: 0x%08" PRIX32 ")\n", (char*)context,
Packit Service fa4841
	       InterlockedIncrement(&count), GetCurrentThreadId());
Packit Service fa4841
Packit Service fa4841
	for (index = 0; index < 100; index++)
Packit Service fa4841
	{
Packit Service fa4841
		ZeroMemory(a, 1024);
Packit Service fa4841
		ZeroMemory(b, 1024);
Packit Service fa4841
		ZeroMemory(c, 1024);
Packit Service fa4841
		FillMemory(a, 1024, 0xAA);
Packit Service fa4841
		FillMemory(b, 1024, 0xBB);
Packit Service fa4841
		CopyMemory(c, a, 1024);
Packit Service fa4841
		CopyMemory(c, b, 1024);
Packit Service fa4841
	}
Packit Service fa4841
}
Packit Service fa4841
Packit Service fa4841
static BOOL test1(void)
Packit Service fa4841
{
Packit Service fa4841
	int index;
Packit Service fa4841
	PTP_WORK work;
Packit Service fa4841
	printf("Global Thread Pool\n");
Packit Service fa4841
	work = CreateThreadpoolWork(test_WorkCallback, "world", NULL);
Packit Service fa4841
Packit Service fa4841
	if (!work)
Packit Service fa4841
	{
Packit Service fa4841
		printf("CreateThreadpoolWork failure\n");
Packit Service fa4841
		return FALSE;
Packit Service fa4841
	}
Packit Service fa4841
Packit Service fa4841
	/**
Packit Service fa4841
	 * You can post a work object one or more times (up to MAXULONG) without waiting for prior
Packit Service fa4841
	 * callbacks to complete. The callbacks will execute in parallel. To improve efficiency, the
Packit Service fa4841
	 * thread pool may throttle the threads.
Packit Service fa4841
	 */
Packit Service fa4841
Packit Service fa4841
	for (index = 0; index < 10; index++)
Packit Service fa4841
		SubmitThreadpoolWork(work);
Packit Service fa4841
Packit Service fa4841
	WaitForThreadpoolWorkCallbacks(work, FALSE);
Packit Service fa4841
	CloseThreadpoolWork(work);
Packit Service fa4841
	return TRUE;
Packit Service fa4841
}
Packit Service fa4841
Packit Service fa4841
static BOOL test2(void)
Packit Service fa4841
{
Packit Service fa4841
	BOOL rc = FALSE;
Packit Service fa4841
	int index;
Packit Service fa4841
	PTP_POOL pool;
Packit Service fa4841
	PTP_WORK work;
Packit Service fa4841
	PTP_CLEANUP_GROUP cleanupGroup = NULL;
Packit Service fa4841
	TP_CALLBACK_ENVIRON environment;
Packit Service fa4841
	printf("Private Thread Pool\n");
Packit Service fa4841
Packit Service fa4841
	if (!(pool = CreateThreadpool(NULL)))
Packit Service fa4841
	{
Packit Service fa4841
		printf("CreateThreadpool failure\n");
Packit Service fa4841
		return FALSE;
Packit Service fa4841
	}
Packit Service fa4841
Packit Service fa4841
	if (!SetThreadpoolThreadMinimum(pool, 4))
Packit Service fa4841
	{
Packit Service fa4841
		printf("SetThreadpoolThreadMinimum failure\n");
Packit Service fa4841
		goto fail;
Packit Service fa4841
	}
Packit Service fa4841
Packit Service fa4841
	SetThreadpoolThreadMaximum(pool, 8);
Packit Service fa4841
	InitializeThreadpoolEnvironment(&environment);
Packit Service fa4841
	SetThreadpoolCallbackPool(&environment, pool);
Packit Service fa4841
	cleanupGroup = CreateThreadpoolCleanupGroup();
Packit Service fa4841
Packit Service fa4841
	if (!cleanupGroup)
Packit Service fa4841
	{
Packit Service fa4841
		printf("CreateThreadpoolCleanupGroup failure\n");
Packit Service fa4841
		goto fail;
Packit Service fa4841
	}
Packit Service fa4841
Packit Service fa4841
	SetThreadpoolCallbackCleanupGroup(&environment, cleanupGroup, NULL);
Packit Service fa4841
	work = CreateThreadpoolWork(test_WorkCallback, "world", &environment);
Packit Service fa4841
Packit Service fa4841
	if (!work)
Packit Service fa4841
	{
Packit Service fa4841
		printf("CreateThreadpoolWork failure\n");
Packit Service fa4841
		goto fail;
Packit Service fa4841
	}
Packit Service fa4841
Packit Service fa4841
	for (index = 0; index < 10; index++)
Packit Service fa4841
		SubmitThreadpoolWork(work);
Packit Service fa4841
Packit Service fa4841
	WaitForThreadpoolWorkCallbacks(work, FALSE);
Packit Service fa4841
	rc = TRUE;
Packit Service fa4841
fail:
Packit Service fa4841
Packit Service fa4841
	if (cleanupGroup)
Packit Service fa4841
	{
Packit Service fa4841
		CloseThreadpoolCleanupGroupMembers(cleanupGroup, TRUE, NULL);
Packit Service fa4841
		CloseThreadpoolCleanupGroup(cleanupGroup);
Packit Service fa4841
		DestroyThreadpoolEnvironment(&environment);
Packit Service fa4841
		/**
Packit Service fa4841
		 * See Remarks at
Packit Service fa4841
		 * https://msdn.microsoft.com/en-us/library/windows/desktop/ms682043(v=vs.85).aspx If there
Packit Service fa4841
		 * is a cleanup group associated with the work object, it is not necessary to call
Packit Service fa4841
		 * CloseThreadpoolWork ! calling the CloseThreadpoolCleanupGroupMembers function releases
Packit Service fa4841
		 * the work, wait, and timer objects associated with the cleanup group.
Packit Service fa4841
		 */
Packit Service fa4841
#if 0
Packit Service fa4841
		CloseThreadpoolWork(work); // this would segfault, see comment above. */
Packit Service fa4841
#endif
Packit Service fa4841
	}
Packit Service fa4841
Packit Service fa4841
	CloseThreadpool(pool);
Packit Service fa4841
	return rc;
Packit Service fa4841
}
Packit Service fa4841
Packit Service fa4841
int TestPoolWork(int argc, char* argv[])
Packit Service fa4841
{
Packit Service fa4841
	if (!test1())
Packit Service fa4841
		return -1;
Packit Service fa4841
Packit Service fa4841
	if (!test2())
Packit Service fa4841
		return -1;
Packit Service fa4841
Packit Service fa4841
	return 0;
Packit Service fa4841
}