summaryrefslogtreecommitdiffstats
path: root/winpr/libwinpr/pool/test
diff options
context:
space:
mode:
Diffstat (limited to 'winpr/libwinpr/pool/test')
-rw-r--r--winpr/libwinpr/pool/test/CMakeLists.txt30
-rw-r--r--winpr/libwinpr/pool/test/TestPoolIO.c8
-rw-r--r--winpr/libwinpr/pool/test/TestPoolSynch.c8
-rw-r--r--winpr/libwinpr/pool/test/TestPoolThread.c41
-rw-r--r--winpr/libwinpr/pool/test/TestPoolTimer.c8
-rw-r--r--winpr/libwinpr/pool/test/TestPoolWork.c136
6 files changed, 231 insertions, 0 deletions
diff --git a/winpr/libwinpr/pool/test/CMakeLists.txt b/winpr/libwinpr/pool/test/CMakeLists.txt
new file mode 100644
index 0000000..9758fff
--- /dev/null
+++ b/winpr/libwinpr/pool/test/CMakeLists.txt
@@ -0,0 +1,30 @@
+
+set(MODULE_NAME "TestPool")
+set(MODULE_PREFIX "TEST_POOL")
+
+set(${MODULE_PREFIX}_DRIVER ${MODULE_NAME}.c)
+
+set(${MODULE_PREFIX}_TESTS
+ TestPoolIO.c
+ TestPoolSynch.c
+ TestPoolThread.c
+ TestPoolTimer.c
+ TestPoolWork.c)
+
+create_test_sourcelist(${MODULE_PREFIX}_SRCS
+ ${${MODULE_PREFIX}_DRIVER}
+ ${${MODULE_PREFIX}_TESTS})
+
+add_executable(${MODULE_NAME} ${${MODULE_PREFIX}_SRCS})
+
+target_link_libraries(${MODULE_NAME} winpr)
+
+set_target_properties(${MODULE_NAME} PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${TESTING_OUTPUT_DIRECTORY}")
+
+foreach(test ${${MODULE_PREFIX}_TESTS})
+ get_filename_component(TestName ${test} NAME_WE)
+ add_test(${TestName} ${TESTING_OUTPUT_DIRECTORY}/${MODULE_NAME} ${TestName})
+endforeach()
+
+set_property(TARGET ${MODULE_NAME} PROPERTY FOLDER "WinPR/Test")
+
diff --git a/winpr/libwinpr/pool/test/TestPoolIO.c b/winpr/libwinpr/pool/test/TestPoolIO.c
new file mode 100644
index 0000000..d68586e
--- /dev/null
+++ b/winpr/libwinpr/pool/test/TestPoolIO.c
@@ -0,0 +1,8 @@
+
+#include <winpr/crt.h>
+#include <winpr/pool.h>
+
+int TestPoolIO(int argc, char* argv[])
+{
+ return 0;
+}
diff --git a/winpr/libwinpr/pool/test/TestPoolSynch.c b/winpr/libwinpr/pool/test/TestPoolSynch.c
new file mode 100644
index 0000000..4d6f381
--- /dev/null
+++ b/winpr/libwinpr/pool/test/TestPoolSynch.c
@@ -0,0 +1,8 @@
+
+#include <winpr/crt.h>
+#include <winpr/pool.h>
+
+int TestPoolSynch(int argc, char* argv[])
+{
+ return 0;
+}
diff --git a/winpr/libwinpr/pool/test/TestPoolThread.c b/winpr/libwinpr/pool/test/TestPoolThread.c
new file mode 100644
index 0000000..d006ae6
--- /dev/null
+++ b/winpr/libwinpr/pool/test/TestPoolThread.c
@@ -0,0 +1,41 @@
+
+#include <winpr/crt.h>
+#include <winpr/pool.h>
+
+/**
+ * Improve Scalability With New Thread Pool APIs:
+ * http://msdn.microsoft.com/en-us/magazine/cc16332.aspx
+ *
+ * Developing with Thread Pool Enhancements:
+ * http://msdn.microsoft.com/en-us/library/cc308561.aspx
+ *
+ * Introduction to the Windows Threadpool:
+ * http://blogs.msdn.com/b/harip/archive/2010/10/11/introduction-to-the-windows-threadpool-part-1.aspx
+ * http://blogs.msdn.com/b/harip/archive/2010/10/12/introduction-to-the-windows-threadpool-part-2.aspx
+ */
+
+int TestPoolThread(int argc, char* argv[])
+{
+ TP_POOL* pool = NULL;
+
+ WINPR_UNUSED(argc);
+ WINPR_UNUSED(argv);
+
+ if (!(pool = CreateThreadpool(NULL)))
+ {
+ printf("CreateThreadpool failed\n");
+ return -1;
+ }
+
+ if (!SetThreadpoolThreadMinimum(pool, 8)) /* default is 0 */
+ {
+ printf("SetThreadpoolThreadMinimum failed\n");
+ return -1;
+ }
+
+ SetThreadpoolThreadMaximum(pool, 64); /* default is 500 */
+
+ CloseThreadpool(pool);
+
+ return 0;
+}
diff --git a/winpr/libwinpr/pool/test/TestPoolTimer.c b/winpr/libwinpr/pool/test/TestPoolTimer.c
new file mode 100644
index 0000000..c749bc7
--- /dev/null
+++ b/winpr/libwinpr/pool/test/TestPoolTimer.c
@@ -0,0 +1,8 @@
+
+#include <winpr/crt.h>
+#include <winpr/pool.h>
+
+int TestPoolTimer(int argc, char* argv[])
+{
+ return 0;
+}
diff --git a/winpr/libwinpr/pool/test/TestPoolWork.c b/winpr/libwinpr/pool/test/TestPoolWork.c
new file mode 100644
index 0000000..ec50a22
--- /dev/null
+++ b/winpr/libwinpr/pool/test/TestPoolWork.c
@@ -0,0 +1,136 @@
+
+#include <winpr/wtypes.h>
+#include <winpr/crt.h>
+#include <winpr/pool.h>
+#include <winpr/interlocked.h>
+
+static LONG count = 0;
+
+static void CALLBACK test_WorkCallback(PTP_CALLBACK_INSTANCE instance, void* context, PTP_WORK work)
+{
+ printf("Hello %s: %03" PRId32 " (thread: 0x%08" PRIX32 ")\n", (char*)context,
+ InterlockedIncrement(&count), GetCurrentThreadId());
+
+ for (int index = 0; index < 100; index++)
+ {
+ BYTE a[1024];
+ BYTE b[1024];
+ BYTE c[1024] = { 0 };
+
+ FillMemory(a, ARRAYSIZE(a), 0xAA);
+ FillMemory(b, ARRAYSIZE(b), 0xBB);
+
+ CopyMemory(c, a, ARRAYSIZE(a));
+ CopyMemory(c, b, ARRAYSIZE(b));
+ }
+}
+
+static BOOL test1(void)
+{
+ PTP_WORK work = NULL;
+ printf("Global Thread Pool\n");
+ work = CreateThreadpoolWork(test_WorkCallback, "world", NULL);
+
+ if (!work)
+ {
+ printf("CreateThreadpoolWork failure\n");
+ return FALSE;
+ }
+
+ /**
+ * You can post a work object one or more times (up to MAXULONG) without waiting for prior
+ * callbacks to complete. The callbacks will execute in parallel. To improve efficiency, the
+ * thread pool may throttle the threads.
+ */
+
+ for (int index = 0; index < 10; index++)
+ SubmitThreadpoolWork(work);
+
+ WaitForThreadpoolWorkCallbacks(work, FALSE);
+ CloseThreadpoolWork(work);
+ return TRUE;
+}
+
+static BOOL test2(void)
+{
+ BOOL rc = FALSE;
+ PTP_POOL pool = NULL;
+ PTP_WORK work = NULL;
+ PTP_CLEANUP_GROUP cleanupGroup = NULL;
+ TP_CALLBACK_ENVIRON environment;
+ printf("Private Thread Pool\n");
+
+ if (!(pool = CreateThreadpool(NULL)))
+ {
+ printf("CreateThreadpool failure\n");
+ return FALSE;
+ }
+
+ if (!SetThreadpoolThreadMinimum(pool, 4))
+ {
+ printf("SetThreadpoolThreadMinimum failure\n");
+ goto fail;
+ }
+
+ SetThreadpoolThreadMaximum(pool, 8);
+ InitializeThreadpoolEnvironment(&environment);
+ SetThreadpoolCallbackPool(&environment, pool);
+ cleanupGroup = CreateThreadpoolCleanupGroup();
+
+ if (!cleanupGroup)
+ {
+ printf("CreateThreadpoolCleanupGroup failure\n");
+ goto fail;
+ }
+
+ SetThreadpoolCallbackCleanupGroup(&environment, cleanupGroup, NULL);
+ work = CreateThreadpoolWork(test_WorkCallback, "world", &environment);
+
+ if (!work)
+ {
+ printf("CreateThreadpoolWork failure\n");
+ goto fail;
+ }
+
+ for (int index = 0; index < 10; index++)
+ SubmitThreadpoolWork(work);
+
+ WaitForThreadpoolWorkCallbacks(work, FALSE);
+ rc = TRUE;
+fail:
+
+ if (cleanupGroup)
+ {
+ CloseThreadpoolCleanupGroupMembers(cleanupGroup, TRUE, NULL);
+ CloseThreadpoolCleanupGroup(cleanupGroup);
+ DestroyThreadpoolEnvironment(&environment);
+ /**
+ * See Remarks at
+ * https://msdn.microsoft.com/en-us/library/windows/desktop/ms682043(v=vs.85).aspx If there
+ * is a cleanup group associated with the work object, it is not necessary to call
+ * CloseThreadpoolWork ! calling the CloseThreadpoolCleanupGroupMembers function releases
+ * the work, wait, and timer objects associated with the cleanup group.
+ */
+#if 0
+ CloseThreadpoolWork(work); // this would segfault, see comment above. */
+#endif
+ }
+
+ CloseThreadpool(pool);
+ return rc;
+}
+
+int TestPoolWork(int argc, char* argv[])
+{
+
+ WINPR_UNUSED(argc);
+ WINPR_UNUSED(argv);
+
+ if (!test1())
+ return -1;
+
+ if (!test2())
+ return -1;
+
+ return 0;
+}