#include <winpr/crt.h>
#include <winpr/pool.h>
+#include "pool.h"
+
#ifdef _WIN32
static BOOL module_initialized = FALSE;
#include <winpr/crt.h>
#include <winpr/pool.h>
+#include "pool.h"
+
#ifdef _WIN32
static BOOL module_initialized = FALSE;
PTP_CLEANUP_GROUP CreateThreadpoolCleanupGroup()
{
+ PTP_CLEANUP_GROUP cleanupGroup = NULL;
#ifdef _WIN32
module_init();
if (pCreateThreadpoolCleanupGroup)
return pCreateThreadpoolCleanupGroup();
#else
+ cleanupGroup = (PTP_CLEANUP_GROUP) malloc(sizeof(TP_CLEANUP_GROUP));
#endif
- return NULL;
+ return cleanupGroup;
}
VOID CloseThreadpoolCleanupGroupMembers(PTP_CLEANUP_GROUP ptpcg, BOOL fCancelPendingCallbacks, PVOID pvCleanupContext)
if (pCloseThreadpoolCleanupGroupMembers)
pCloseThreadpoolCleanupGroupMembers(ptpcg, fCancelPendingCallbacks, pvCleanupContext);
#else
+
#endif
}
if (pCloseThreadpoolCleanupGroup)
pCloseThreadpoolCleanupGroup(ptpcg);
#else
+ free(ptpcg);
#endif
}
static void* thread_pool_work_func(void* arg)
{
+ DWORD status;
PTP_POOL pool;
PTP_WORK work;
+ HANDLE events[2];
PTP_CALLBACK_INSTANCE callbackInstance;
pool = (PTP_POOL) arg;
- while (WaitForSingleObject(Queue_Event(pool->PendingQueue), INFINITE) == WAIT_OBJECT_0)
+ events[0] = pool->TerminateEvent;
+ events[1] = Queue_Event(pool->PendingQueue);
+
+ while (1)
{
+ status = WaitForMultipleObjects(2, events, FALSE, INFINITE);
+
+ if (status == WAIT_OBJECT_0)
+ break;
+
+ if (status != (WAIT_OBJECT_0 + 1))
+ break;
+
callbackInstance = (PTP_CALLBACK_INSTANCE) Queue_Dequeue(pool->PendingQueue);
if (callbackInstance)
return NULL;
}
-PTP_POOL GetDefaultThreadpool()
+void InitializeThreadpool(PTP_POOL pool)
{
int index;
- PTP_POOL pool = NULL;
-
- pool = &DEFAULT_POOL;
+ HANDLE thread;
if (!pool->Threads)
{
- pool->ThreadCount = 4;
- pool->Threads = (HANDLE*) malloc(pool->ThreadCount * sizeof(HANDLE));
+ pool->Minimum = 0;
+ pool->Maximum = 500;
+
+ pool->Threads = ArrayList_New(TRUE);
pool->PendingQueue = Queue_New(TRUE, -1, -1);
pool->WorkComplete = CountdownEvent_New(0);
- for (index = 0; index < pool->ThreadCount; index++)
+ pool->TerminateEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
+
+ for (index = 0; index < 4; index++)
{
- pool->Threads[index] = CreateThread(NULL, 0,
+ thread = CreateThread(NULL, 0,
(LPTHREAD_START_ROUTINE) thread_pool_work_func,
(void*) pool, 0, NULL);
+
+ ArrayList_Add(pool->Threads, thread);
}
}
+}
+
+PTP_POOL GetDefaultThreadpool()
+{
+ PTP_POOL pool = NULL;
+
+ pool = &DEFAULT_POOL;
+
+ InitializeThreadpool(pool);
return pool;
}
pool = (PTP_POOL) malloc(sizeof(TP_POOL));
if (pool)
- {
- pool->Minimum = 0;
- pool->Maximum = 500;
- }
+ InitializeThreadpool(pool);
#endif
return pool;
if (pCloseThreadpool)
pCloseThreadpool(ptpp);
#else
+ int index;
+ HANDLE thread;
+
+ SetEvent(ptpp->TerminateEvent);
+
+ index = ArrayList_Count(ptpp->Threads) - 1;
+
+ while (index >= 0)
+ {
+ thread = (HANDLE) ArrayList_GetItem(ptpp->Threads, index);
+ WaitForSingleObject(thread, INFINITE);
+ index--;
+ }
+
+ ArrayList_Free(ptpp->Threads);
+ Queue_Free(ptpp->PendingQueue);
+ CountdownEvent_Free(ptpp->WorkComplete);
+ CloseHandle(ptpp->TerminateEvent);
+
free(ptpp);
#endif
}
{
DWORD Minimum;
DWORD Maximum;
- HANDLE* Threads;
- DWORD ThreadCount;
+ wArrayList* Threads;
wQueue* PendingQueue;
+ HANDLE TerminateEvent;
wCountdownEvent* WorkComplete;
};
void* dummy;
};
+struct _TP_CLEANUP_GROUP
+{
+ void* dummy;
+};
+
#ifndef _WIN32
PTP_POOL GetDefaultThreadpool();
void test_WorkCallback(PTP_CALLBACK_INSTANCE instance, void* context, PTP_WORK work)
{
- printf("Hello %s: %d\n", context, count++);
+ int index;
+ BYTE a[1024];
+ BYTE b[1024];
+ BYTE c[1024];
+
+ printf("Hello %s: %d (thread: %d)\n", context, count++, GetCurrentThreadId());
+
+ for (index = 0; index < 100; index++)
+ {
+ ZeroMemory(a, 1024);
+ ZeroMemory(b, 1024);
+ ZeroMemory(c, 1024);
+ FillMemory(a, 1024, 0xAA);
+ FillMemory(b, 1024, 0xBB);
+ CopyMemory(c, a, 1024);
+ CopyMemory(c, b, 1024);
+ }
}
int TestPoolWork(int argc, char* argv[])
if (Type == HANDLE_TYPE_THREAD)
{
+ int status;
WINPR_THREAD* thread;
+ void* thread_status = NULL;
if (dwMilliseconds != INFINITE)
printf("WaitForSingleObject: timeout not implemented for thread wait\n");
thread = (WINPR_THREAD*) Object;
- pthread_join(thread->thread, NULL);
+ status = pthread_join(thread->thread, &thread_status);
+
+ if (status != 0)
+ printf("WaitForSingleObject: pthread_join failure: %d\n", status);
}
if (Type == HANDLE_TYPE_MUTEX)
{
pthread_attr_t attr;
pthread_attr_init(&attr);
- pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
+ pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
if (thread->dwStackSize > 0)
pthread_attr_setstacksize(&attr, (size_t) thread->dwStackSize);