ntdll-Vista_Threadpool: Move code to threadpool.c, some minor cleanup.

This commit is contained in:
Sebastian Lackner 2015-03-25 06:20:43 +01:00
parent 79b46b851a
commit 44094b9175
21 changed files with 680 additions and 787 deletions

View File

@ -1,33 +1,19 @@
From 674272bb028c74d513416d2f776c1ecd6b229c7f Mon Sep 17 00:00:00 2001
From 4693a9204a3131172e0d1be292ecbe70777057de Mon Sep 17 00:00:00 2001
From: Sebastian Lackner <sebastian@fds-team.de>
Date: Tue, 24 Feb 2015 05:42:07 +0100
Subject: ntdll: Implement TpSimpleTryPost and basic threadpool infrastructure.
---
dlls/ntdll/Makefile.in | 1 +
dlls/ntdll/ntdll.spec | 3 +
dlls/ntdll/tests/threadpool.c | 3 +-
dlls/ntdll/threadpool2.c | 424 ++++++++++++++++++++++++++++++++++++++++++
4 files changed, 430 insertions(+), 1 deletion(-)
create mode 100644 dlls/ntdll/threadpool2.c
dlls/ntdll/threadpool.c | 370 ++++++++++++++++++++++++++++++++++++++++++
3 files changed, 375 insertions(+), 1 deletion(-)
diff --git a/dlls/ntdll/Makefile.in b/dlls/ntdll/Makefile.in
index ed4bb94..2cecac6 100644
--- a/dlls/ntdll/Makefile.in
+++ b/dlls/ntdll/Makefile.in
@@ -47,6 +47,7 @@ C_SRCS = \
tape.c \
thread.c \
threadpool.c \
+ threadpool2.c \
time.c \
version.c \
virtual.c \
diff --git a/dlls/ntdll/ntdll.spec b/dlls/ntdll/ntdll.spec
index 9355d04..aa16021 100644
index c3307b2..d9aafdd 100644
--- a/dlls/ntdll/ntdll.spec
+++ b/dlls/ntdll/ntdll.spec
@@ -967,6 +967,9 @@
@@ -968,6 +968,9 @@
@ stdcall RtlxOemStringToUnicodeSize(ptr) RtlOemStringToUnicodeSize
@ stdcall RtlxUnicodeStringToAnsiSize(ptr) RtlUnicodeStringToAnsiSize
@ stdcall RtlxUnicodeStringToOemSize(ptr) RtlUnicodeStringToOemSize
@ -58,60 +44,36 @@ index 2e31b34..6f164e9 100644
ok(status == STATUS_INVALID_PARAMETER || broken(!status) /* Vista/2008 */,
"TpSimpleTryPost unexpectedly returned status %x\n", status);
if (!status)
diff --git a/dlls/ntdll/threadpool2.c b/dlls/ntdll/threadpool2.c
new file mode 100644
index 0000000..e912729
--- /dev/null
+++ b/dlls/ntdll/threadpool2.c
@@ -0,0 +1,424 @@
diff --git a/dlls/ntdll/threadpool.c b/dlls/ntdll/threadpool.c
index 513c13d..df92ef2 100644
--- a/dlls/ntdll/threadpool.c
+++ b/dlls/ntdll/threadpool.c
@@ -2,6 +2,7 @@
* Thread pooling
*
* Copyright (c) 2006 Robert Shearman
+ * Copyright (c) 2014-2015 Sebastian Lackner
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -37,6 +38,10 @@
WINE_DEFAULT_DEBUG_CHANNEL(threadpool);
+/*
+ * Object-oriented thread pool API
+ *
+ * Copyright 2014-2015 Sebastian Lackner
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ * Old thread pooling API
+ */
+
+#include "config.h"
+#include "wine/port.h"
+
+#include <assert.h>
+#include <stdarg.h>
+#include <limits.h>
+
+#define NONAMELESSUNION
+#include "ntstatus.h"
+#define WIN32_NO_STATUS
+#include "winternl.h"
+
+#include "wine/debug.h"
+#include "wine/list.h"
+
+#include "ntdll_misc.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(threadpool);
+
+static inline LONG interlocked_inc( PLONG dest )
+{
+ return interlocked_xchg_add( dest, 1 ) + 1;
+}
+
+static inline LONG interlocked_dec( PLONG dest )
+{
+ return interlocked_xchg_add( dest, -1 ) - 1;
+}
#define OLD_WORKER_TIMEOUT 30000 /* 30 seconds */
#define EXPIRE_NEVER (~(ULONGLONG)0)
#define TIMER_QUEUE_MAGIC 0x516d6954 /* TimQ */
@@ -127,6 +132,64 @@ struct timer_queue
HANDLE thread;
};
+/*
+ * New object-oriented thread pooling API
+ */
+
+#define THREADPOOL_WORKER_TIMEOUT 5000
+
@ -165,33 +127,15 @@ index 0000000..e912729
+}
+
+static void CALLBACK threadpool_worker_proc( void *param );
+static NTSTATUS tp_threadpool_alloc( struct threadpool **out );
+static void tp_threadpool_shutdown( struct threadpool *pool );
+static BOOL tp_threadpool_release( struct threadpool *pool );
+static void tp_object_submit( struct threadpool_object *object );
+static void tp_object_shutdown( struct threadpool_object *object );
+static BOOL tp_object_release( struct threadpool_object *object );
+
+static struct threadpool *default_threadpool = NULL;
+
+/* allocates or returns the default threadpool */
+static struct threadpool *get_default_threadpool( void )
+{
+ if (!default_threadpool)
+ {
+ struct threadpool *pool;
+
+ if (tp_threadpool_alloc( &pool ) != STATUS_SUCCESS)
+ return NULL;
+
+ if (interlocked_cmpxchg_ptr( (void *)&default_threadpool, pool, NULL ) != NULL)
+ {
+ tp_threadpool_shutdown( pool );
+ tp_threadpool_release( pool );
+ }
+ }
+ return default_threadpool;
+}
static inline LONG interlocked_inc( PLONG dest )
{
return interlocked_xchg_add( dest, 1 ) + 1;
@@ -1044,3 +1107,310 @@ NTSTATUS WINAPI RtlDeleteTimer(HANDLE TimerQueue, HANDLE Timer,
return status;
}
+
+/* allocate a new threadpool (with at least one worker thread) */
+static NTSTATUS tp_threadpool_alloc( struct threadpool **out )
@ -262,69 +206,23 @@ index 0000000..e912729
+ return TRUE;
+}
+
+/* threadpool worker function */
+static void CALLBACK threadpool_worker_proc( void *param )
+/* allocates or returns the default threadpool */
+static struct threadpool *get_default_threadpool( void )
+{
+ struct threadpool *pool = param;
+ LARGE_INTEGER timeout;
+ struct list *ptr;
+
+ RtlEnterCriticalSection( &pool->cs );
+ for (;;)
+ if (!default_threadpool)
+ {
+ while ((ptr = list_head( &pool->pool )))
+ struct threadpool *pool;
+
+ if (tp_threadpool_alloc( &pool ) != STATUS_SUCCESS)
+ return NULL;
+
+ if (interlocked_cmpxchg_ptr( (void *)&default_threadpool, pool, NULL ) != NULL)
+ {
+ struct threadpool_object *object = LIST_ENTRY( ptr, struct threadpool_object, pool_entry );
+ assert( object->num_pending_callbacks > 0 );
+
+ /* If further pending callbacks are queued, move the work item to
+ * the end of the pool list. Otherwise remove it from the pool. */
+ list_remove( &object->pool_entry );
+ if (--object->num_pending_callbacks)
+ list_add_tail( &pool->pool, &object->pool_entry );
+
+ /* Leave critical section and do the actual callback. */
+ object->num_running_callbacks++;
+ pool->num_busy_workers++;
+ RtlLeaveCriticalSection( &pool->cs );
+
+ switch (object->type)
+ {
+ case TP_OBJECT_TYPE_SIMPLE:
+ {
+ TRACE( "executing simple callback %p(NULL, %p)\n",
+ object->u.simple.callback, object->userdata );
+ object->u.simple.callback( NULL, object->userdata );
+ TRACE( "callback %p returned\n", object->u.simple.callback );
+ break;
+ }
+
+ default:
+ assert(0);
+ break;
+ }
+
+ RtlEnterCriticalSection( &pool->cs );
+ pool->num_busy_workers--;
+ object->num_running_callbacks--;
+ tp_object_release( object );
+ }
+
+ /* Shutdown worker thread if requested. */
+ if (pool->shutdown)
+ break;
+
+ /* Wait for new tasks or until timeout expires. Never terminate the last worker. */
+ timeout.QuadPart = (ULONGLONG)THREADPOOL_WORKER_TIMEOUT * -10000;
+ if (RtlSleepConditionVariableCS( &pool->update_event, &pool->cs, &timeout ) == STATUS_TIMEOUT &&
+ !list_head( &pool->pool ) && pool->num_workers > 1)
+ {
+ break;
+ tp_threadpool_shutdown( pool );
+ tp_threadpool_release( pool );
+ }
+ }
+ pool->num_workers--;
+ RtlLeaveCriticalSection( &pool->cs );
+ tp_threadpool_release( pool );
+ return default_threadpool;
+}
+
+/* initializes a new threadpool object */
@ -350,38 +248,6 @@ index 0000000..e912729
+ TRACE("allocated object %p of type %u\n", object, object->type);
+}
+
+/* allocates and submits a 'simple' threadpool task. */
+static NTSTATUS tp_object_submit_simple( PTP_SIMPLE_CALLBACK callback, PVOID userdata,
+ TP_CALLBACK_ENVIRON *environment )
+{
+ struct threadpool_object *object;
+ struct threadpool *pool = NULL;
+
+ if (environment)
+ pool = (struct threadpool *)environment->Pool;
+
+ if (!pool)
+ {
+ pool = get_default_threadpool();
+ if (!pool)
+ return STATUS_NO_MEMORY;
+ }
+
+ object = RtlAllocateHeap( GetProcessHeap(), 0, sizeof(*object) );
+ if (!object)
+ return STATUS_NO_MEMORY;
+
+ object->type = TP_OBJECT_TYPE_SIMPLE;
+ object->u.simple.callback = callback;
+ tp_object_initialize( object, pool, userdata, environment );
+
+ tp_object_submit( object );
+
+ tp_object_shutdown( object );
+ tp_object_release( object );
+ return STATUS_SUCCESS;
+}
+
+/* submits an object to a threadpool */
+static void tp_object_submit( struct threadpool_object *object )
+{
@ -446,6 +312,70 @@ index 0000000..e912729
+ return TRUE;
+}
+
+/* threadpool worker function */
+static void CALLBACK threadpool_worker_proc( void *param )
+{
+ struct threadpool *pool = param;
+ LARGE_INTEGER timeout;
+ struct list *ptr;
+
+ RtlEnterCriticalSection( &pool->cs );
+ for (;;)
+ {
+ while ((ptr = list_head( &pool->pool )))
+ {
+ struct threadpool_object *object = LIST_ENTRY( ptr, struct threadpool_object, pool_entry );
+ assert( object->num_pending_callbacks > 0 );
+
+ /* If further pending callbacks are queued, move the work item to
+ * the end of the pool list. Otherwise remove it from the pool. */
+ list_remove( &object->pool_entry );
+ if (--object->num_pending_callbacks)
+ list_add_tail( &pool->pool, &object->pool_entry );
+
+ /* Leave critical section and do the actual callback. */
+ object->num_running_callbacks++;
+ pool->num_busy_workers++;
+ RtlLeaveCriticalSection( &pool->cs );
+
+ switch (object->type)
+ {
+ case TP_OBJECT_TYPE_SIMPLE:
+ {
+ TRACE( "executing simple callback %p(NULL, %p)\n",
+ object->u.simple.callback, object->userdata );
+ object->u.simple.callback( NULL, object->userdata );
+ TRACE( "callback %p returned\n", object->u.simple.callback );
+ break;
+ }
+
+ default:
+ assert(0);
+ break;
+ }
+
+ RtlEnterCriticalSection( &pool->cs );
+ pool->num_busy_workers--;
+ object->num_running_callbacks--;
+ tp_object_release( object );
+ }
+
+ /* Shutdown worker thread if requested. */
+ if (pool->shutdown)
+ break;
+
+ /* Wait for new tasks or until timeout expires. Never terminate the last worker. */
+ timeout.QuadPart = (ULONGLONG)THREADPOOL_WORKER_TIMEOUT * -10000;
+ if (RtlSleepConditionVariableCS( &pool->update_event, &pool->cs, &timeout ) == STATUS_TIMEOUT &&
+ !list_head( &pool->pool ) && pool->num_workers > 1)
+ {
+ break;
+ }
+ }
+ pool->num_workers--;
+ RtlLeaveCriticalSection( &pool->cs );
+ tp_threadpool_release( pool );
+}
+
+/***********************************************************************
+ * TpAllocPool (NTDLL.@)
@ -484,10 +414,35 @@ index 0000000..e912729
+NTSTATUS WINAPI TpSimpleTryPost( PTP_SIMPLE_CALLBACK callback, PVOID userdata,
+ TP_CALLBACK_ENVIRON *environment )
+{
+ struct threadpool_object *object;
+ struct threadpool *pool = NULL;
+
+ TRACE("%p %p %p\n", callback, userdata, environment);
+
+ return tp_object_submit_simple( callback, userdata, environment );
+ if (environment)
+ pool = (struct threadpool *)environment->Pool;
+
+ if (!pool)
+ {
+ pool = get_default_threadpool();
+ if (!pool)
+ return STATUS_NO_MEMORY;
+ }
+
+ object = RtlAllocateHeap( GetProcessHeap(), 0, sizeof(*object) );
+ if (!object)
+ return STATUS_NO_MEMORY;
+
+ object->type = TP_OBJECT_TYPE_SIMPLE;
+ object->u.simple.callback = callback;
+ tp_object_initialize( object, pool, userdata, environment );
+
+ tp_object_submit( object );
+
+ tp_object_shutdown( object );
+ tp_object_release( object );
+ return STATUS_SUCCESS;
+}
--
2.3.0
2.3.3

View File

@ -1,18 +1,18 @@
From b2f107dc3bbde6a242f2ce0fc4b350728f8135f5 Mon Sep 17 00:00:00 2001
From 13635df17569be46833f21980ba22f2b4db85102 Mon Sep 17 00:00:00 2001
From: Sebastian Lackner <sebastian@fds-team.de>
Date: Wed, 4 Mar 2015 00:16:20 +0100
Subject: ntdll: Implement TpSetPool[Min|Max]Threads.
---
dlls/ntdll/ntdll.spec | 2 ++
dlls/ntdll/threadpool2.c | 33 +++++++++++++++++++++++++++++++++
dlls/ntdll/ntdll.spec | 2 ++
dlls/ntdll/threadpool.c | 33 +++++++++++++++++++++++++++++++++
2 files changed, 35 insertions(+)
diff --git a/dlls/ntdll/ntdll.spec b/dlls/ntdll/ntdll.spec
index aa16021..9a7ddeb 100644
index d9aafdd..88d915b 100644
--- a/dlls/ntdll/ntdll.spec
+++ b/dlls/ntdll/ntdll.spec
@@ -969,6 +969,8 @@
@@ -970,6 +970,8 @@
@ stdcall RtlxUnicodeStringToOemSize(ptr) RtlUnicodeStringToOemSize
@ stdcall TpAllocPool(ptr ptr)
@ stdcall TpReleasePool(ptr)
@ -21,11 +21,11 @@ index aa16021..9a7ddeb 100644
@ stdcall TpSimpleTryPost(ptr ptr ptr)
@ stdcall -ret64 VerSetConditionMask(int64 long long)
@ stdcall ZwAcceptConnectPort(ptr long ptr long long ptr) NtAcceptConnectPort
diff --git a/dlls/ntdll/threadpool2.c b/dlls/ntdll/threadpool2.c
index e912729..08bcde0 100644
--- a/dlls/ntdll/threadpool2.c
+++ b/dlls/ntdll/threadpool2.c
@@ -413,6 +413,39 @@ VOID WINAPI TpReleasePool( TP_POOL *pool )
diff --git a/dlls/ntdll/threadpool.c b/dlls/ntdll/threadpool.c
index df92ef2..16d9209 100644
--- a/dlls/ntdll/threadpool.c
+++ b/dlls/ntdll/threadpool.c
@@ -1380,6 +1380,39 @@ VOID WINAPI TpReleasePool( TP_POOL *pool )
}
/***********************************************************************
@ -66,5 +66,5 @@ index e912729..08bcde0 100644
*/
NTSTATUS WINAPI TpSimpleTryPost( PTP_SIMPLE_CALLBACK callback, PVOID userdata,
--
2.3.0
2.3.3

View File

@ -1,18 +1,18 @@
From c6e44243dba7ac4a57ccef25e83645fa09855b98 Mon Sep 17 00:00:00 2001
From 63ebc5c972502aaa60d50b1f6ca54f6a9646fca6 Mon Sep 17 00:00:00 2001
From: Sebastian Lackner <sebastian@fds-team.de>
Date: Wed, 4 Mar 2015 00:52:18 +0100
Subject: ntdll: Implement threadpool cleanup group functions.
---
dlls/ntdll/ntdll.spec | 3 +
dlls/ntdll/threadpool2.c | 261 ++++++++++++++++++++++++++++++++++++++++++++++-
2 files changed, 259 insertions(+), 5 deletions(-)
dlls/ntdll/ntdll.spec | 3 +
dlls/ntdll/threadpool.c | 259 +++++++++++++++++++++++++++++++++++++++++++++++-
2 files changed, 257 insertions(+), 5 deletions(-)
diff --git a/dlls/ntdll/ntdll.spec b/dlls/ntdll/ntdll.spec
index 9a7ddeb..6dad2bb 100644
index 88d915b..853ca09 100644
--- a/dlls/ntdll/ntdll.spec
+++ b/dlls/ntdll/ntdll.spec
@@ -967,7 +967,10 @@
@@ -968,7 +968,10 @@
@ stdcall RtlxOemStringToUnicodeSize(ptr) RtlOemStringToUnicodeSize
@ stdcall RtlxUnicodeStringToAnsiSize(ptr) RtlUnicodeStringToAnsiSize
@ stdcall RtlxUnicodeStringToOemSize(ptr) RtlUnicodeStringToOemSize
@ -23,11 +23,11 @@ index 9a7ddeb..6dad2bb 100644
@ stdcall TpReleasePool(ptr)
@ stdcall TpSetPoolMaxThreads(ptr long)
@ stdcall TpSetPoolMinThreads(ptr long)
diff --git a/dlls/ntdll/threadpool2.c b/dlls/ntdll/threadpool2.c
index 08bcde0..30f1e6d 100644
--- a/dlls/ntdll/threadpool2.c
+++ b/dlls/ntdll/threadpool2.c
@@ -78,9 +78,14 @@ struct threadpool_object
diff --git a/dlls/ntdll/threadpool.c b/dlls/ntdll/threadpool.c
index 16d9209..092fa6f 100644
--- a/dlls/ntdll/threadpool.c
+++ b/dlls/ntdll/threadpool.c
@@ -167,9 +167,14 @@ struct threadpool_object
/* read-only information */
enum threadpool_objtype type;
struct threadpool *pool;
@ -42,7 +42,7 @@ index 08bcde0..30f1e6d 100644
LONG num_pending_callbacks;
LONG num_running_callbacks;
/* arguments for callback */
@@ -93,11 +98,26 @@ struct threadpool_object
@@ -182,12 +187,30 @@ struct threadpool_object
} u;
};
@ -67,26 +67,64 @@ index 08bcde0..30f1e6d 100644
+}
+
static void CALLBACK threadpool_worker_proc( void *param );
static NTSTATUS tp_threadpool_alloc( struct threadpool **out );
static void tp_threadpool_shutdown( struct threadpool *pool );
@@ -105,6 +125,7 @@ static BOOL tp_threadpool_release( struct threadpool *pool );
static void tp_object_submit( struct threadpool_object *object );
static void tp_object_shutdown( struct threadpool_object *object );
static BOOL tp_object_release( struct threadpool_object *object );
+static BOOL tp_group_release( struct threadpool_group *group );
+static void tp_object_submit( struct threadpool_object *object );
+static void tp_object_shutdown( struct threadpool_object *object );
+static BOOL tp_object_release( struct threadpool_object *object );
static struct threadpool *default_threadpool = NULL;
@@ -241,6 +262,8 @@ static void CALLBACK threadpool_worker_proc( void *param )
RtlEnterCriticalSection( &pool->cs );
pool->num_busy_workers--;
object->num_running_callbacks--;
+ if (!object->num_pending_callbacks && !object->num_running_callbacks)
+ RtlWakeAllConditionVariable( &object->finished_event );
tp_object_release( object );
}
static inline LONG interlocked_inc( PLONG dest )
@@ -1196,27 +1219,111 @@ static struct threadpool *get_default_threadpool( void )
return default_threadpool;
}
@@ -265,23 +288,60 @@ static void CALLBACK threadpool_worker_proc( void *param )
+/* allocates a new cleanup group */
+static NTSTATUS tp_group_alloc( struct threadpool_group **out )
+{
+ struct threadpool_group *group;
+
+ group = RtlAllocateHeap( GetProcessHeap(), 0, sizeof(*group) );
+ if (!group)
+ return STATUS_NO_MEMORY;
+
+ group->refcount = 1;
+ group->shutdown = FALSE;
+
+ RtlInitializeCriticalSection( &group->cs );
+ group->cs.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": threadpool_group.cs");
+
+ list_init( &group->members );
+
+ TRACE("allocated group %p\n", group);
+
+ *out = group;
+ return STATUS_SUCCESS;
+}
+
+/* marks a cleanup group for shutdown */
+static void tp_group_shutdown( struct threadpool_group *group )
+{
+ group->shutdown = TRUE;
+}
+
+/* releases a reference to a cleanup group */
+static BOOL tp_group_release( struct threadpool_group *group )
+{
+ if (interlocked_dec( &group->refcount ))
+ return FALSE;
+
+ TRACE("destroying group %p\n", group);
+
+ assert( group->shutdown );
+ assert( list_empty( &group->members ) );
+
+ group->cs.DebugInfo->Spare[0] = 0;
+ RtlDeleteCriticalSection( &group->cs );
+
+ RtlFreeHeap( GetProcessHeap(), 0, group );
+ return TRUE;
+}
+
/* initializes a new threadpool object */
static void tp_object_initialize( struct threadpool_object *object, struct threadpool *pool,
PVOID userdata, TP_CALLBACK_ENVIRON *environment )
{
@ -147,19 +185,8 @@ index 08bcde0..30f1e6d 100644
+ }
}
/* allocates and submits a 'simple' threadpool task. */
@@ -309,10 +369,6 @@ static NTSTATUS tp_object_submit_simple( PTP_SIMPLE_CALLBACK callback, PVOID use
object->u.simple.callback = callback;
tp_object_initialize( object, pool, userdata, environment );
- tp_object_submit( object );
-
- tp_object_shutdown( object );
- tp_object_release( object );
return STATUS_SUCCESS;
}
@@ -355,6 +411,41 @@ out:
/* submits an object to a threadpool */
@@ -1258,6 +1365,41 @@ out:
RtlLeaveCriticalSection( &pool->cs );
}
@ -201,7 +228,7 @@ index 08bcde0..30f1e6d 100644
/* mark an object as 'shutdown', submitting is no longer possible */
static void tp_object_shutdown( struct threadpool_object *object )
{
@@ -373,6 +464,22 @@ static BOOL tp_object_release( struct threadpool_object *object )
@@ -1276,6 +1418,22 @@ static BOOL tp_object_release( struct threadpool_object *object )
assert( !object->num_pending_callbacks );
assert( !object->num_running_callbacks );
@ -224,112 +251,19 @@ index 08bcde0..30f1e6d 100644
/* release reference to threadpool */
tp_threadpool_release( object->pool );
@@ -380,6 +487,121 @@ static BOOL tp_object_release( struct threadpool_object *object )
return TRUE;
@@ -1328,6 +1486,8 @@ static void CALLBACK threadpool_worker_proc( void *param )
RtlEnterCriticalSection( &pool->cs );
pool->num_busy_workers--;
object->num_running_callbacks--;
+ if (!object->num_pending_callbacks && !object->num_running_callbacks)
+ RtlWakeAllConditionVariable( &object->finished_event );
tp_object_release( object );
}
@@ -1348,6 +1508,20 @@ static void CALLBACK threadpool_worker_proc( void *param )
tp_threadpool_release( pool );
}
+/* allocates a new cleanup group */
+static NTSTATUS tp_group_alloc( struct threadpool_group **out )
+{
+ struct threadpool_group *group;
+
+ group = RtlAllocateHeap( GetProcessHeap(), 0, sizeof(*group) );
+ if (!group)
+ return STATUS_NO_MEMORY;
+
+ group->refcount = 1;
+ group->shutdown = FALSE;
+
+ RtlInitializeCriticalSection( &group->cs );
+ group->cs.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": threadpool_group.cs");
+
+ list_init( &group->members );
+
+ TRACE("allocated group %p\n", group);
+
+ *out = group;
+ return STATUS_SUCCESS;
+}
+
+/* marks a cleanup group for shutdown */
+static void tp_group_shutdown( struct threadpool_group *group )
+{
+ group->shutdown = TRUE;
+}
+
+/* releases a reference to a cleanup group */
+static BOOL tp_group_release( struct threadpool_group *group )
+{
+ if (interlocked_dec( &group->refcount ))
+ return FALSE;
+
+ TRACE("destroying group %p\n", group);
+
+ assert( group->shutdown );
+ assert( list_empty( &group->members ) );
+
+ group->cs.DebugInfo->Spare[0] = 0;
+ RtlDeleteCriticalSection( &group->cs );
+
+ RtlFreeHeap( GetProcessHeap(), 0, group );
+ return TRUE;
+}
+
+/* releases all group members of a cleanup group */
+static void tp_group_release_members( struct threadpool_group *group, BOOL cancel_pending, PVOID userdata )
+{
+ struct threadpool_object *object, *next;
+ struct list members;
+
+ RtlEnterCriticalSection( &group->cs );
+
+ /* Unset group, increase references, and mark objects for shutdown */
+ LIST_FOR_EACH_ENTRY_SAFE( object, next, &group->members, struct threadpool_object, group_entry )
+ {
+ assert( object->group == group );
+ assert( object->is_group_member );
+
+ /* Simple callbacks are very special. The user doesn't hold any reference, so
+ * they would be released too early. Add one additional temporary reference. */
+ if (object->type == TP_OBJECT_TYPE_SIMPLE)
+ {
+ if (interlocked_inc( &object->refcount ) == 1)
+ {
+ /* Object is basically already destroyed, but group reference
+ * was not deleted yet. We can safely ignore this object. */
+ interlocked_dec( &object->refcount );
+ list_remove( &object->group_entry );
+ object->is_group_member = FALSE;
+ continue;
+ }
+ }
+
+ object->is_group_member = FALSE;
+ tp_object_shutdown( object );
+ }
+
+ /* Move members to a local list */
+ list_init( &members );
+ list_move_tail( &members, &group->members );
+
+ RtlLeaveCriticalSection( &group->cs );
+
+ /* Cancel pending callbacks if requested */
+ if (cancel_pending)
+ {
+ LIST_FOR_EACH_ENTRY( object, &members, struct threadpool_object, group_entry )
+ {
+ tp_object_cancel( object );
+ }
+ }
+
+ /* Wait for remaining callbacks to finish */
+ LIST_FOR_EACH_ENTRY_SAFE( object, next, &members, struct threadpool_object, group_entry )
+ {
+ tp_object_wait( object );
+ tp_object_release( object );
+ }
+}
+
+/***********************************************************************
+ * TpAllocCleanupGroup (NTDLL.@)
@ -343,10 +277,11 @@ index 08bcde0..30f1e6d 100644
+
+ return tp_group_alloc( (struct threadpool_group **)out );
+}
+
/***********************************************************************
* TpAllocPool (NTDLL.@)
@@ -398,6 +620,35 @@ NTSTATUS WINAPI TpAllocPool( TP_POOL **out, PVOID reserved )
*/
@@ -1365,6 +1539,85 @@ NTSTATUS WINAPI TpAllocPool( TP_POOL **out, PVOID reserved )
}
/***********************************************************************
@ -370,11 +305,61 @@ index 08bcde0..30f1e6d 100644
+VOID WINAPI TpReleaseCleanupGroupMembers( TP_CLEANUP_GROUP *group, BOOL cancel_pending, PVOID userdata )
+{
+ struct threadpool_group *this = impl_from_TP_CLEANUP_GROUP( group );
+ struct threadpool_object *object, *next;
+ struct list members;
+
+ TRACE("%p %d %p\n", group, cancel_pending, userdata);
+
+ if (this)
+ if (!this)
+ return;
+
+ RtlEnterCriticalSection( &this->cs );
+
+ /* Unset group, increase references, and mark objects for shutdown */
+ LIST_FOR_EACH_ENTRY_SAFE( object, next, &this->members, struct threadpool_object, group_entry )
+ {
+ tp_group_release_members( this, cancel_pending, userdata );
+ assert( object->group == this );
+ assert( object->is_group_member );
+
+ /* Simple callbacks are very special. The user doesn't hold any reference, so
+ * they would be released too early. Add one additional temporary reference. */
+ if (object->type == TP_OBJECT_TYPE_SIMPLE)
+ {
+ if (interlocked_inc( &object->refcount ) == 1)
+ {
+ /* Object is basically already destroyed, but group reference
+ * was not deleted yet. We can safely ignore this object. */
+ interlocked_dec( &object->refcount );
+ list_remove( &object->group_entry );
+ object->is_group_member = FALSE;
+ continue;
+ }
+ }
+
+ object->is_group_member = FALSE;
+ tp_object_shutdown( object );
+ }
+
+ /* Move members to a local list */
+ list_init( &members );
+ list_move_tail( &members, &this->members );
+
+ RtlLeaveCriticalSection( &this->cs );
+
+ /* Cancel pending callbacks if requested */
+ if (cancel_pending)
+ {
+ LIST_FOR_EACH_ENTRY( object, &members, struct threadpool_object, group_entry )
+ {
+ tp_object_cancel( object );
+ }
+ }
+
+ /* Wait for remaining callbacks to finish */
+ LIST_FOR_EACH_ENTRY_SAFE( object, next, &members, struct threadpool_object, group_entry )
+ {
+ tp_object_wait( object );
+ tp_object_release( object );
+ }
+}
+
@ -382,6 +367,16 @@ index 08bcde0..30f1e6d 100644
* TpReleasePool (NTDLL.@)
*/
VOID WINAPI TpReleasePool( TP_POOL *pool )
@@ -1441,9 +1694,5 @@ NTSTATUS WINAPI TpSimpleTryPost( PTP_SIMPLE_CALLBACK callback, PVOID userdata,
object->u.simple.callback = callback;
tp_object_initialize( object, pool, userdata, environment );
- tp_object_submit( object );
-
- tp_object_shutdown( object );
- tp_object_release( object );
return STATUS_SUCCESS;
}
--
2.3.0
2.3.3

View File

@ -1,4 +1,4 @@
From 8517209b838b33e7ff69d70285c4e53d5b5a4258 Mon Sep 17 00:00:00 2001
From f8532f86e968848db4b8e4f87d3556dfcaa753e8 Mon Sep 17 00:00:00 2001
From: Sebastian Lackner <sebastian@fds-team.de>
Date: Wed, 4 Mar 2015 01:19:41 +0100
Subject: ntdll/tests: Add tests for TpAllocCleanupGroup and related functions.
@ -98,5 +98,5 @@ index 6f164e9..effa7fc 100644
CloseHandle(semaphore);
}
--
2.3.0
2.3.3

View File

@ -1,18 +1,18 @@
From 5e0c3a3b77b95434e19f273da7dcadc7cd224cea Mon Sep 17 00:00:00 2001
From d4b4fc976cad98a6e483584da8de8f011f029c20 Mon Sep 17 00:00:00 2001
From: Sebastian Lackner <sebastian@fds-team.de>
Date: Wed, 4 Mar 2015 01:30:57 +0100
Subject: ntdll: Implement threadpool work item functions.
---
dlls/ntdll/ntdll.spec | 4 ++
dlls/ntdll/threadpool2.c | 108 ++++++++++++++++++++++++++++++++++++++++++++++-
2 files changed, 111 insertions(+), 1 deletion(-)
dlls/ntdll/ntdll.spec | 4 ++
dlls/ntdll/threadpool.c | 101 +++++++++++++++++++++++++++++++++++++++++++++++-
2 files changed, 104 insertions(+), 1 deletion(-)
diff --git a/dlls/ntdll/ntdll.spec b/dlls/ntdll/ntdll.spec
index 6dad2bb..1c768c9 100644
index 853ca09..96edd67 100644
--- a/dlls/ntdll/ntdll.spec
+++ b/dlls/ntdll/ntdll.spec
@@ -969,12 +969,16 @@
@@ -970,12 +970,16 @@
@ stdcall RtlxUnicodeStringToOemSize(ptr) RtlUnicodeStringToOemSize
@ stdcall TpAllocCleanupGroup(ptr)
@ stdcall TpAllocPool(ptr ptr)
@ -29,11 +29,11 @@ index 6dad2bb..1c768c9 100644
@ stdcall -ret64 VerSetConditionMask(int64 long long)
@ stdcall ZwAcceptConnectPort(ptr long ptr long long ptr) NtAcceptConnectPort
@ stdcall ZwAccessCheck(ptr long long ptr ptr ptr ptr ptr) NtAccessCheck
diff --git a/dlls/ntdll/threadpool2.c b/dlls/ntdll/threadpool2.c
index 30f1e6d..31b5e2e 100644
--- a/dlls/ntdll/threadpool2.c
+++ b/dlls/ntdll/threadpool2.c
@@ -67,7 +67,8 @@ struct threadpool
diff --git a/dlls/ntdll/threadpool.c b/dlls/ntdll/threadpool.c
index 092fa6f..1989d56 100644
--- a/dlls/ntdll/threadpool.c
+++ b/dlls/ntdll/threadpool.c
@@ -156,7 +156,8 @@ struct threadpool
enum threadpool_objtype
{
@ -43,7 +43,7 @@ index 30f1e6d..31b5e2e 100644
};
/* internal threadpool object representation */
@@ -95,6 +96,10 @@ struct threadpool_object
@@ -184,6 +185,10 @@ struct threadpool_object
{
PTP_SIMPLE_CALLBACK callback;
} simple;
@ -54,7 +54,7 @@ index 30f1e6d..31b5e2e 100644
} u;
};
@@ -113,6 +118,13 @@ static inline struct threadpool *impl_from_TP_POOL( TP_POOL *pool )
@@ -202,6 +207,13 @@ static inline struct threadpool *impl_from_TP_POOL( TP_POOL *pool )
return (struct threadpool *)pool;
}
@ -68,7 +68,7 @@ index 30f1e6d..31b5e2e 100644
static inline struct threadpool_group *impl_from_TP_CLEANUP_GROUP( TP_CLEANUP_GROUP *group )
{
return (struct threadpool_group *)group;
@@ -254,6 +266,15 @@ static void CALLBACK threadpool_worker_proc( void *param )
@@ -1478,6 +1490,15 @@ static void CALLBACK threadpool_worker_proc( void *param )
break;
}
@ -84,16 +84,20 @@ index 30f1e6d..31b5e2e 100644
default:
assert(0);
break;
@@ -372,6 +393,34 @@ static NTSTATUS tp_object_submit_simple( PTP_SIMPLE_CALLBACK callback, PVOID use
return STATUS_SUCCESS;
@@ -1539,6 +1560,53 @@ NTSTATUS WINAPI TpAllocPool( TP_POOL **out, PVOID reserved )
}
+static NTSTATUS tp_object_alloc_work( struct threadpool_object **out, PTP_WORK_CALLBACK callback,
+ PVOID userdata, TP_CALLBACK_ENVIRON *environment )
/***********************************************************************
+ * TpAllocWork (NTDLL.@)
+ */
+NTSTATUS WINAPI TpAllocWork( TP_WORK **out, PTP_WORK_CALLBACK callback, PVOID userdata,
+ TP_CALLBACK_ENVIRON *environment )
+{
+ struct threadpool_object *object;
+ struct threadpool *pool = NULL;
+
+ TRACE("%p %p %p %p\n", out, callback, userdata, environment);
+
+ if (environment)
+ pool = (struct threadpool *)environment->Pool;
+
@ -112,27 +116,9 @@ index 30f1e6d..31b5e2e 100644
+ object->u.work.callback = callback;
+ tp_object_initialize( object, pool, userdata, environment );
+
+ *out = object;
+ *out = (TP_WORK *)object;
+ return STATUS_SUCCESS;
+}
+
/* submits an object to a threadpool */
static void tp_object_submit( struct threadpool_object *object )
{
@@ -620,6 +669,32 @@ NTSTATUS WINAPI TpAllocPool( TP_POOL **out, PVOID reserved )
}
/***********************************************************************
+ * TpAllocWork (NTDLL.@)
+ */
+NTSTATUS WINAPI TpAllocWork( TP_WORK **out, PTP_WORK_CALLBACK callback, PVOID userdata,
+ TP_CALLBACK_ENVIRON *environment )
+{
+ TRACE("%p %p %p %p\n", out, callback, userdata, environment);
+
+ return tp_object_alloc_work( (struct threadpool_object **)out, callback,
+ userdata, environment );
+}
+
+/***********************************************************************
+ * TpPostWork (NTDLL.@)
@ -152,7 +138,7 @@ index 30f1e6d..31b5e2e 100644
* TpReleaseCleanupGroup (NTDLL.@)
*/
VOID WINAPI TpReleaseCleanupGroup( TP_CLEANUP_GROUP *group )
@@ -664,6 +739,21 @@ VOID WINAPI TpReleasePool( TP_POOL *pool )
@@ -1633,6 +1701,21 @@ VOID WINAPI TpReleasePool( TP_POOL *pool )
}
/***********************************************************************
@ -174,9 +160,9 @@ index 30f1e6d..31b5e2e 100644
* TpSetPoolMaxThreads (NTDLL.@)
*/
VOID WINAPI TpSetPoolMaxThreads( TP_POOL *pool, DWORD maximum )
@@ -706,3 +796,19 @@ NTSTATUS WINAPI TpSimpleTryPost( PTP_SIMPLE_CALLBACK callback, PVOID userdata,
@@ -1696,3 +1779,19 @@ NTSTATUS WINAPI TpSimpleTryPost( PTP_SIMPLE_CALLBACK callback, PVOID userdata,
return tp_object_submit_simple( callback, userdata, environment );
return STATUS_SUCCESS;
}
+
+/***********************************************************************
@ -195,5 +181,5 @@ index 30f1e6d..31b5e2e 100644
+ }
+}
--
2.3.0
2.3.3

View File

@ -1,4 +1,4 @@
From 688ef1722a39b3b51797cd179181012b0863cd1e Mon Sep 17 00:00:00 2001
From a0ad4f0f9186dbce96da918255f2c0cd5f4aae7f Mon Sep 17 00:00:00 2001
From: Sebastian Lackner <sebastian@fds-team.de>
Date: Wed, 4 Mar 2015 01:38:23 +0100
Subject: ntdll/tests: Add basic tests for threadpool work items.
@ -104,5 +104,5 @@ index effa7fc..420979c 100644
+ test_tp_work();
}
--
2.3.0
2.3.3

View File

@ -1,4 +1,4 @@
From d796254c2e3c5188d893fb8d1de4978bb864357e Mon Sep 17 00:00:00 2001
From 792ceb3a01f63e523811d42d7a28f6e31a70e2f7 Mon Sep 17 00:00:00 2001
From: Sebastian Lackner <sebastian@fds-team.de>
Date: Wed, 4 Mar 2015 01:45:11 +0100
Subject: ntdll/tests: Add threadpool scheduler tests for work items.
@ -128,5 +128,5 @@ index 420979c..1cfd67b 100644
+ test_tp_work_scheduler();
}
--
2.3.0
2.3.3

View File

@ -1,17 +1,17 @@
From af02399ac80682e6ca5c093150460dca20c7323b Mon Sep 17 00:00:00 2001
From 624d6ab353109a57dfe0d80053795ef64b6adc3e Mon Sep 17 00:00:00 2001
From: Sebastian Lackner <sebastian@fds-team.de>
Date: Wed, 4 Mar 2015 06:57:53 +0100
Subject: ntdll: Add support for threadpool group cancel callback.
---
dlls/ntdll/threadpool2.c | 17 ++++++++++++++---
dlls/ntdll/threadpool.c | 17 ++++++++++++++---
1 file changed, 14 insertions(+), 3 deletions(-)
diff --git a/dlls/ntdll/threadpool2.c b/dlls/ntdll/threadpool2.c
index 31b5e2e..5233271 100644
--- a/dlls/ntdll/threadpool2.c
+++ b/dlls/ntdll/threadpool2.c
@@ -81,6 +81,7 @@ struct threadpool_object
diff --git a/dlls/ntdll/threadpool.c b/dlls/ntdll/threadpool.c
index 1989d56..e30d45c 100644
--- a/dlls/ntdll/threadpool.c
+++ b/dlls/ntdll/threadpool.c
@@ -170,6 +170,7 @@ struct threadpool_object
struct threadpool *pool;
struct threadpool_group *group;
PVOID userdata;
@ -19,7 +19,7 @@ index 31b5e2e..5233271 100644
/* information about the group, locked via .group->cs */
struct list group_entry;
BOOL is_group_member;
@@ -317,6 +318,7 @@ static void tp_object_initialize( struct threadpool_object *object, struct threa
@@ -1290,6 +1291,7 @@ static void tp_object_initialize( struct threadpool_object *object, struct threa
object->pool = pool;
object->group = NULL;
object->userdata = userdata;
@ -27,7 +27,7 @@ index 31b5e2e..5233271 100644
memset( &object->group_entry, 0, sizeof(object->group_entry) );
object->is_group_member = FALSE;
@@ -332,6 +334,7 @@ static void tp_object_initialize( struct threadpool_object *object, struct threa
@@ -1305,6 +1307,7 @@ static void tp_object_initialize( struct threadpool_object *object, struct threa
FIXME("unsupported environment version %u\n", environment->Version);
object->group = impl_from_TP_CLEANUP_GROUP( environment->CleanupGroup );
@ -35,7 +35,7 @@ index 31b5e2e..5233271 100644
WARN("environment not fully implemented yet\n");
}
@@ -460,7 +463,7 @@ out:
@@ -1377,7 +1380,7 @@ out:
RtlLeaveCriticalSection( &pool->cs );
}
@ -44,7 +44,7 @@ index 31b5e2e..5233271 100644
{
struct threadpool *pool = object->pool;
LONG pending_callbacks = 0;
@@ -477,6 +480,14 @@ static void tp_object_cancel( struct threadpool_object *object )
@@ -1394,6 +1397,14 @@ static void tp_object_cancel( struct threadpool_object *object )
RtlLeaveCriticalSection( &pool->cs );
@ -59,7 +59,7 @@ index 31b5e2e..5233271 100644
/* Release references */
while (pending_callbacks--)
tp_object_release( object );
@@ -627,7 +638,7 @@ static void tp_group_release_members( struct threadpool_group *group, BOOL cance
@@ -1673,7 +1684,7 @@ VOID WINAPI TpReleaseCleanupGroupMembers( TP_CLEANUP_GROUP *group, BOOL cancel_p
{
LIST_FOR_EACH_ENTRY( object, &members, struct threadpool_object, group_entry )
{
@ -68,7 +68,7 @@ index 31b5e2e..5233271 100644
}
}
@@ -808,7 +819,7 @@ VOID WINAPI TpWaitForWork( TP_WORK *work, BOOL cancel_pending )
@@ -1791,7 +1802,7 @@ VOID WINAPI TpWaitForWork( TP_WORK *work, BOOL cancel_pending )
if (this)
{
if (cancel_pending)
@ -78,5 +78,5 @@ index 31b5e2e..5233271 100644
}
}
--
2.3.0
2.3.3

View File

@ -1,17 +1,17 @@
From 7fb1d9cfd7dbae474fa0965a143be2408240eeb2 Mon Sep 17 00:00:00 2001
From d92b2f79160613f6d2f258cbf98624fee30844a8 Mon Sep 17 00:00:00 2001
From: Sebastian Lackner <sebastian@fds-team.de>
Date: Wed, 4 Mar 2015 07:03:15 +0100
Subject: ntdll: Add support for threadpool finalization callback.
---
dlls/ntdll/threadpool2.c | 12 ++++++++++++
dlls/ntdll/threadpool.c | 12 ++++++++++++
1 file changed, 12 insertions(+)
diff --git a/dlls/ntdll/threadpool2.c b/dlls/ntdll/threadpool2.c
index 5233271..d9e08ac 100644
--- a/dlls/ntdll/threadpool2.c
+++ b/dlls/ntdll/threadpool2.c
@@ -82,6 +82,7 @@ struct threadpool_object
diff --git a/dlls/ntdll/threadpool.c b/dlls/ntdll/threadpool.c
index e30d45c..927d31c 100644
--- a/dlls/ntdll/threadpool.c
+++ b/dlls/ntdll/threadpool.c
@@ -171,6 +171,7 @@ struct threadpool_object
struct threadpool_group *group;
PVOID userdata;
PTP_CLEANUP_GROUP_CANCEL_CALLBACK group_cancel_callback;
@ -19,7 +19,23 @@ index 5233271..d9e08ac 100644
/* information about the group, locked via .group->cs */
struct list group_entry;
BOOL is_group_member;
@@ -281,6 +282,15 @@ static void CALLBACK threadpool_worker_proc( void *param )
@@ -1292,6 +1293,7 @@ static void tp_object_initialize( struct threadpool_object *object, struct threa
object->group = NULL;
object->userdata = userdata;
object->group_cancel_callback = NULL;
+ object->finalization_callback = NULL;
memset( &object->group_entry, 0, sizeof(object->group_entry) );
object->is_group_member = FALSE;
@@ -1308,6 +1310,7 @@ static void tp_object_initialize( struct threadpool_object *object, struct threa
object->group = impl_from_TP_CLEANUP_GROUP( environment->CleanupGroup );
object->group_cancel_callback = environment->CleanupGroupCancelCallback;
+ object->finalization_callback = environment->FinalizationCallback;
WARN("environment not fully implemented yet\n");
}
@@ -1515,6 +1518,15 @@ static void CALLBACK threadpool_worker_proc( void *param )
break;
}
@ -35,22 +51,6 @@ index 5233271..d9e08ac 100644
RtlEnterCriticalSection( &pool->cs );
pool->num_busy_workers--;
object->num_running_callbacks--;
@@ -319,6 +329,7 @@ static void tp_object_initialize( struct threadpool_object *object, struct threa
object->group = NULL;
object->userdata = userdata;
object->group_cancel_callback = NULL;
+ object->finalization_callback = NULL;
memset( &object->group_entry, 0, sizeof(object->group_entry) );
object->is_group_member = FALSE;
@@ -335,6 +346,7 @@ static void tp_object_initialize( struct threadpool_object *object, struct threa
object->group = impl_from_TP_CLEANUP_GROUP( environment->CleanupGroup );
object->group_cancel_callback = environment->CleanupGroupCancelCallback;
+ object->finalization_callback = environment->FinalizationCallback;
WARN("environment not fully implemented yet\n");
}
--
2.3.0
2.3.3

View File

@ -1,17 +1,17 @@
From 3080d2d1a5526d61c02efee05d8804611f860976 Mon Sep 17 00:00:00 2001
From a2fdd577db91938092d4c38d16a469ddf46189fb Mon Sep 17 00:00:00 2001
From: Sebastian Lackner <sebastian@fds-team.de>
Date: Wed, 4 Mar 2015 07:07:07 +0100
Subject: ntdll: Implement threadpool RaceDll environment variable.
---
dlls/ntdll/threadpool2.c | 11 +++++++++++
dlls/ntdll/threadpool.c | 11 +++++++++++
1 file changed, 11 insertions(+)
diff --git a/dlls/ntdll/threadpool2.c b/dlls/ntdll/threadpool2.c
index d9e08ac..a5203f0 100644
--- a/dlls/ntdll/threadpool2.c
+++ b/dlls/ntdll/threadpool2.c
@@ -83,6 +83,7 @@ struct threadpool_object
diff --git a/dlls/ntdll/threadpool.c b/dlls/ntdll/threadpool.c
index 927d31c..47f6f6f 100644
--- a/dlls/ntdll/threadpool.c
+++ b/dlls/ntdll/threadpool.c
@@ -172,6 +172,7 @@ struct threadpool_object
PVOID userdata;
PTP_CLEANUP_GROUP_CANCEL_CALLBACK group_cancel_callback;
PTP_SIMPLE_CALLBACK finalization_callback;
@ -19,7 +19,7 @@ index d9e08ac..a5203f0 100644
/* information about the group, locked via .group->cs */
struct list group_entry;
BOOL is_group_member;
@@ -330,6 +331,7 @@ static void tp_object_initialize( struct threadpool_object *object, struct threa
@@ -1294,6 +1295,7 @@ static void tp_object_initialize( struct threadpool_object *object, struct threa
object->userdata = userdata;
object->group_cancel_callback = NULL;
object->finalization_callback = NULL;
@ -27,7 +27,7 @@ index d9e08ac..a5203f0 100644
memset( &object->group_entry, 0, sizeof(object->group_entry) );
object->is_group_member = FALSE;
@@ -347,10 +349,15 @@ static void tp_object_initialize( struct threadpool_object *object, struct threa
@@ -1311,10 +1313,15 @@ static void tp_object_initialize( struct threadpool_object *object, struct threa
object->group = impl_from_TP_CLEANUP_GROUP( environment->CleanupGroup );
object->group_cancel_callback = environment->CleanupGroupCancelCallback;
object->finalization_callback = environment->FinalizationCallback;
@ -43,7 +43,7 @@ index d9e08ac..a5203f0 100644
/* Increase reference-count on the pool */
interlocked_inc( &pool->refcount );
@@ -555,6 +562,10 @@ static BOOL tp_object_release( struct threadpool_object *object )
@@ -1463,6 +1470,10 @@ static BOOL tp_object_release( struct threadpool_object *object )
/* release reference to threadpool */
tp_threadpool_release( object->pool );
@ -55,5 +55,5 @@ index d9e08ac..a5203f0 100644
return TRUE;
}
--
2.3.0
2.3.3

View File

@ -1,18 +1,18 @@
From 750a6fed12e8b667325b93919a05daf6cbc648b4 Mon Sep 17 00:00:00 2001
From 11233cc79c1790974d7cb401e64f9f8dcc94e1f3 Mon Sep 17 00:00:00 2001
From: Sebastian Lackner <sebastian@fds-team.de>
Date: Wed, 4 Mar 2015 07:25:35 +0100
Subject: ntdll: Implement TpCallbackMayRunLong and instance structure.
---
dlls/ntdll/ntdll.spec | 1 +
dlls/ntdll/threadpool2.c | 104 ++++++++++++++++++++++++++++++++++++++++++-----
2 files changed, 95 insertions(+), 10 deletions(-)
dlls/ntdll/ntdll.spec | 1 +
dlls/ntdll/threadpool.c | 103 +++++++++++++++++++++++++++++++++++++++++++-----
2 files changed, 94 insertions(+), 10 deletions(-)
diff --git a/dlls/ntdll/ntdll.spec b/dlls/ntdll/ntdll.spec
index 1c768c9..38e6fe8 100644
index 96edd67..b7f1555 100644
--- a/dlls/ntdll/ntdll.spec
+++ b/dlls/ntdll/ntdll.spec
@@ -970,6 +970,7 @@
@@ -971,6 +971,7 @@
@ stdcall TpAllocCleanupGroup(ptr)
@ stdcall TpAllocPool(ptr ptr)
@ stdcall TpAllocWork(ptr ptr ptr ptr)
@ -20,11 +20,11 @@ index 1c768c9..38e6fe8 100644
@ stdcall TpPostWork(ptr)
@ stdcall TpReleaseCleanupGroup(ptr)
@ stdcall TpReleaseCleanupGroupMembers(ptr long ptr)
diff --git a/dlls/ntdll/threadpool2.c b/dlls/ntdll/threadpool2.c
index a5203f0..90f2ab7 100644
--- a/dlls/ntdll/threadpool2.c
+++ b/dlls/ntdll/threadpool2.c
@@ -83,6 +83,7 @@ struct threadpool_object
diff --git a/dlls/ntdll/threadpool.c b/dlls/ntdll/threadpool.c
index 47f6f6f..d1733c8 100644
--- a/dlls/ntdll/threadpool.c
+++ b/dlls/ntdll/threadpool.c
@@ -172,6 +172,7 @@ struct threadpool_object
PVOID userdata;
PTP_CLEANUP_GROUP_CANCEL_CALLBACK group_cancel_callback;
PTP_SIMPLE_CALLBACK finalization_callback;
@ -32,7 +32,7 @@ index a5203f0..90f2ab7 100644
HMODULE race_dll;
/* information about the group, locked via .group->cs */
struct list group_entry;
@@ -106,6 +107,14 @@ struct threadpool_object
@@ -195,6 +196,14 @@ struct threadpool_object
} u;
};
@ -47,7 +47,7 @@ index a5203f0..90f2ab7 100644
/* internal threadpool group representation */
struct threadpool_group
{
@@ -133,6 +142,11 @@ static inline struct threadpool_group *impl_from_TP_CLEANUP_GROUP( TP_CLEANUP_GR
@@ -222,6 +231,11 @@ static inline struct threadpool_group *impl_from_TP_CLEANUP_GROUP( TP_CLEANUP_GR
return (struct threadpool_group *)group;
}
@ -57,70 +57,9 @@ index a5203f0..90f2ab7 100644
+}
+
static void CALLBACK threadpool_worker_proc( void *param );
static NTSTATUS tp_threadpool_alloc( struct threadpool **out );
static void tp_threadpool_shutdown( struct threadpool *pool );
@@ -140,6 +154,7 @@ static BOOL tp_threadpool_release( struct threadpool *pool );
static void tp_object_submit( struct threadpool_object *object );
static void tp_object_shutdown( struct threadpool_object *object );
static BOOL tp_object_release( struct threadpool_object *object );
+static void tp_instance_initialize( struct threadpool_instance *instance, struct threadpool_object *object );
static BOOL tp_group_release( struct threadpool_group *group );
static struct threadpool *default_threadpool = NULL;
@@ -235,6 +250,8 @@ static BOOL tp_threadpool_release( struct threadpool *pool )
/* threadpool worker function */
static void CALLBACK threadpool_worker_proc( void *param )
{
+ struct threadpool_instance instance;
+ TP_CALLBACK_INSTANCE *cb_instance = (TP_CALLBACK_INSTANCE *)&instance;
struct threadpool *pool = param;
LARGE_INTEGER timeout;
struct list *ptr;
@@ -257,23 +274,24 @@ static void CALLBACK threadpool_worker_proc( void *param )
object->num_running_callbacks++;
pool->num_busy_workers++;
RtlLeaveCriticalSection( &pool->cs );
+ tp_instance_initialize( &instance, object );
switch (object->type)
{
case TP_OBJECT_TYPE_SIMPLE:
{
- TRACE( "executing simple callback %p(NULL, %p)\n",
- object->u.simple.callback, object->userdata );
- object->u.simple.callback( NULL, object->userdata );
+ TRACE( "executing simple callback %p(%p, %p)\n",
+ object->u.simple.callback, cb_instance, object->userdata );
+ object->u.simple.callback( cb_instance, object->userdata );
TRACE( "callback %p returned\n", object->u.simple.callback );
break;
}
case TP_OBJECT_TYPE_WORK:
{
- TRACE( "executing work callback %p(NULL, %p, %p)\n",
- object->u.work.callback, object->userdata, object );
- object->u.work.callback( NULL, object->userdata, (TP_WORK *)object );
+ TRACE( "executing work callback %p(%p, %p, %p)\n",
+ object->u.work.callback, cb_instance, object->userdata, object );
+ object->u.work.callback( cb_instance, object->userdata, (TP_WORK *)object );
TRACE( "callback %p returned\n", object->u.work.callback );
break;
}
@@ -286,9 +304,9 @@ static void CALLBACK threadpool_worker_proc( void *param )
/* Execute finalization callback */
if (object->finalization_callback)
{
- TRACE( "executing finalization callback %p(NULL, %p)\n",
- object->finalization_callback, object->userdata );
- object->finalization_callback( NULL, object->userdata );
+ TRACE( "executing finalization callback %p(%p, %p)\n",
+ object->finalization_callback, cb_instance, object->userdata );
+ object->finalization_callback( cb_instance, object->userdata );
TRACE( "callback %p returned\n", object->finalization_callback );
}
@@ -331,6 +349,7 @@ static void tp_object_initialize( struct threadpool_object *object, struct threa
@@ -1295,6 +1309,7 @@ static void tp_object_initialize( struct threadpool_object *object, struct threa
object->userdata = userdata;
object->group_cancel_callback = NULL;
object->finalization_callback = NULL;
@ -128,7 +67,7 @@ index a5203f0..90f2ab7 100644
object->race_dll = NULL;
memset( &object->group_entry, 0, sizeof(object->group_entry) );
@@ -349,9 +368,14 @@ static void tp_object_initialize( struct threadpool_object *object, struct threa
@@ -1313,9 +1328,14 @@ static void tp_object_initialize( struct threadpool_object *object, struct threa
object->group = impl_from_TP_CLEANUP_GROUP( environment->CleanupGroup );
object->group_cancel_callback = environment->CleanupGroupCancelCallback;
object->finalization_callback = environment->FinalizationCallback;
@ -144,7 +83,7 @@ index a5203f0..90f2ab7 100644
}
/* Increase dll refcount */
@@ -570,6 +594,52 @@ static BOOL tp_object_release( struct threadpool_object *object )
@@ -1478,9 +1498,57 @@ static BOOL tp_object_release( struct threadpool_object *object )
return TRUE;
}
@ -194,10 +133,59 @@ index a5203f0..90f2ab7 100644
+ return !status;
+}
+
/* allocates a new cleanup group */
static NTSTATUS tp_group_alloc( struct threadpool_group **out )
/* threadpool worker function */
static void CALLBACK threadpool_worker_proc( void *param )
{
@@ -715,6 +785,20 @@ NTSTATUS WINAPI TpAllocWork( TP_WORK **out, PTP_WORK_CALLBACK callback, PVOID us
+ struct threadpool_instance instance;
+ TP_CALLBACK_INSTANCE *cb_instance = (TP_CALLBACK_INSTANCE *)&instance;
struct threadpool *pool = param;
LARGE_INTEGER timeout;
struct list *ptr;
@@ -1503,23 +1571,24 @@ static void CALLBACK threadpool_worker_proc( void *param )
object->num_running_callbacks++;
pool->num_busy_workers++;
RtlLeaveCriticalSection( &pool->cs );
+ tp_instance_initialize( &instance, object );
switch (object->type)
{
case TP_OBJECT_TYPE_SIMPLE:
{
- TRACE( "executing simple callback %p(NULL, %p)\n",
- object->u.simple.callback, object->userdata );
- object->u.simple.callback( NULL, object->userdata );
+ TRACE( "executing simple callback %p(%p, %p)\n",
+ object->u.simple.callback, cb_instance, object->userdata );
+ object->u.simple.callback( cb_instance, object->userdata );
TRACE( "callback %p returned\n", object->u.simple.callback );
break;
}
case TP_OBJECT_TYPE_WORK:
{
- TRACE( "executing work callback %p(NULL, %p, %p)\n",
- object->u.work.callback, object->userdata, object );
- object->u.work.callback( NULL, object->userdata, (TP_WORK *)object );
+ TRACE( "executing work callback %p(%p, %p, %p)\n",
+ object->u.work.callback, cb_instance, object->userdata, object );
+ object->u.work.callback( cb_instance, object->userdata, (TP_WORK *)object );
TRACE( "callback %p returned\n", object->u.work.callback );
break;
}
@@ -1532,9 +1601,9 @@ static void CALLBACK threadpool_worker_proc( void *param )
/* Execute finalization callback */
if (object->finalization_callback)
{
- TRACE( "executing finalization callback %p(NULL, %p)\n",
- object->finalization_callback, object->userdata );
- object->finalization_callback( NULL, object->userdata );
+ TRACE( "executing finalization callback %p(%p, %p)\n",
+ object->finalization_callback, cb_instance, object->userdata );
+ object->finalization_callback( cb_instance, object->userdata );
TRACE( "callback %p returned\n", object->finalization_callback );
}
@@ -1627,6 +1696,20 @@ NTSTATUS WINAPI TpAllocWork( TP_WORK **out, PTP_WORK_CALLBACK callback, PVOID us
}
/***********************************************************************
@ -219,5 +207,5 @@ index a5203f0..90f2ab7 100644
*/
VOID WINAPI TpPostWork( TP_WORK *work )
--
2.3.0
2.3.3

View File

@ -1,18 +1,18 @@
From c3f8e7288538d526ece6b07ff69790e6ff7b1d9d Mon Sep 17 00:00:00 2001
From 472f35764b63622fd5887ac16194e8b5089f0fc6 Mon Sep 17 00:00:00 2001
From: Sebastian Lackner <sebastian@fds-team.de>
Date: Wed, 4 Mar 2015 07:31:27 +0100
Subject: ntdll: Implement TpDisassociateCallback.
---
dlls/ntdll/ntdll.spec | 1 +
dlls/ntdll/threadpool2.c | 52 +++++++++++++++++++++++++++++++++++++++++++++---
dlls/ntdll/ntdll.spec | 1 +
dlls/ntdll/threadpool.c | 52 ++++++++++++++++++++++++++++++++++++++++++++++---
2 files changed, 50 insertions(+), 3 deletions(-)
diff --git a/dlls/ntdll/ntdll.spec b/dlls/ntdll/ntdll.spec
index 38e6fe8..aaf1c64 100644
index b7f1555..63426c5 100644
--- a/dlls/ntdll/ntdll.spec
+++ b/dlls/ntdll/ntdll.spec
@@ -971,6 +971,7 @@
@@ -972,6 +972,7 @@
@ stdcall TpAllocPool(ptr ptr)
@ stdcall TpAllocWork(ptr ptr ptr ptr)
@ stdcall TpCallbackMayRunLong(ptr)
@ -20,11 +20,11 @@ index 38e6fe8..aaf1c64 100644
@ stdcall TpPostWork(ptr)
@ stdcall TpReleaseCleanupGroup(ptr)
@ stdcall TpReleaseCleanupGroupMembers(ptr long ptr)
diff --git a/dlls/ntdll/threadpool2.c b/dlls/ntdll/threadpool2.c
index 90f2ab7..c40c06a 100644
--- a/dlls/ntdll/threadpool2.c
+++ b/dlls/ntdll/threadpool2.c
@@ -112,6 +112,7 @@ struct threadpool_instance
diff --git a/dlls/ntdll/threadpool.c b/dlls/ntdll/threadpool.c
index d1733c8..4861ba6 100644
--- a/dlls/ntdll/threadpool.c
+++ b/dlls/ntdll/threadpool.c
@@ -201,6 +201,7 @@ struct threadpool_instance
{
struct threadpool_object *object;
DWORD threadid;
@ -32,23 +32,7 @@ index 90f2ab7..c40c06a 100644
BOOL may_run_long;
};
@@ -312,9 +313,12 @@ static void CALLBACK threadpool_worker_proc( void *param )
RtlEnterCriticalSection( &pool->cs );
pool->num_busy_workers--;
- object->num_running_callbacks--;
- if (!object->num_pending_callbacks && !object->num_running_callbacks)
- RtlWakeAllConditionVariable( &object->finished_event );
+ if (!instance.disassociated)
+ {
+ object->num_running_callbacks--;
+ if (!object->num_pending_callbacks && !object->num_running_callbacks)
+ RtlWakeAllConditionVariable( &object->finished_event );
+ }
tp_object_release( object );
}
@@ -599,9 +603,37 @@ static void tp_instance_initialize( struct threadpool_instance *instance, struct
@@ -1503,9 +1504,37 @@ static void tp_instance_initialize( struct threadpool_instance *instance, struct
{
instance->object = object;
instance->threadid = GetCurrentThreadId();
@ -86,7 +70,23 @@ index 90f2ab7..c40c06a 100644
/* hint for the threadpool that the execution might take long, spawn additional workers */
static BOOL tp_instance_may_run_long( struct threadpool_instance *instance )
{
@@ -799,6 +831,20 @@ NTSTATUS WINAPI TpCallbackMayRunLong( TP_CALLBACK_INSTANCE *instance )
@@ -1609,9 +1638,12 @@ static void CALLBACK threadpool_worker_proc( void *param )
RtlEnterCriticalSection( &pool->cs );
pool->num_busy_workers--;
- object->num_running_callbacks--;
- if (!object->num_pending_callbacks && !object->num_running_callbacks)
- RtlWakeAllConditionVariable( &object->finished_event );
+ if (!instance.disassociated)
+ {
+ object->num_running_callbacks--;
+ if (!object->num_pending_callbacks && !object->num_running_callbacks)
+ RtlWakeAllConditionVariable( &object->finished_event );
+ }
tp_object_release( object );
}
@@ -1710,6 +1742,20 @@ NTSTATUS WINAPI TpCallbackMayRunLong( TP_CALLBACK_INSTANCE *instance )
}
/***********************************************************************
@ -108,5 +108,5 @@ index 90f2ab7..c40c06a 100644
*/
VOID WINAPI TpPostWork( TP_WORK *work )
--
2.3.0
2.3.3

View File

@ -1,18 +1,18 @@
From 6229d9139d7b30f00e78c6f1f8410c1c99712295 Mon Sep 17 00:00:00 2001
From 16d0eb264d85a90fa7faf1b429dec1f4efe385a2 Mon Sep 17 00:00:00 2001
From: Sebastian Lackner <sebastian@fds-team.de>
Date: Wed, 4 Mar 2015 07:40:02 +0100
Subject: ntdll: Implement various TpCallback*OnCompletion functions.
---
dlls/ntdll/ntdll.spec | 5 ++
dlls/ntdll/threadpool2.c | 154 +++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 159 insertions(+)
dlls/ntdll/ntdll.spec | 5 ++
dlls/ntdll/threadpool.c | 153 ++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 158 insertions(+)
diff --git a/dlls/ntdll/ntdll.spec b/dlls/ntdll/ntdll.spec
index aaf1c64..0c5ad39 100644
index 63426c5..6100a7e 100644
--- a/dlls/ntdll/ntdll.spec
+++ b/dlls/ntdll/ntdll.spec
@@ -970,7 +970,12 @@
@@ -971,7 +971,12 @@
@ stdcall TpAllocCleanupGroup(ptr)
@ stdcall TpAllocPool(ptr ptr)
@ stdcall TpAllocWork(ptr ptr ptr ptr)
@ -25,11 +25,11 @@ index aaf1c64..0c5ad39 100644
@ stdcall TpDisassociateCallback(ptr)
@ stdcall TpPostWork(ptr)
@ stdcall TpReleaseCleanupGroup(ptr)
diff --git a/dlls/ntdll/threadpool2.c b/dlls/ntdll/threadpool2.c
index c40c06a..ebf8b94 100644
--- a/dlls/ntdll/threadpool2.c
+++ b/dlls/ntdll/threadpool2.c
@@ -114,6 +114,15 @@ struct threadpool_instance
diff --git a/dlls/ntdll/threadpool.c b/dlls/ntdll/threadpool.c
index 4861ba6..aa2d8e9 100644
--- a/dlls/ntdll/threadpool.c
+++ b/dlls/ntdll/threadpool.c
@@ -203,6 +203,15 @@ struct threadpool_instance
DWORD threadid;
BOOL disassociated;
BOOL may_run_long;
@ -45,23 +45,7 @@ index c40c06a..ebf8b94 100644
};
/* internal threadpool group representation */
@@ -156,6 +165,7 @@ static void tp_object_submit( struct threadpool_object *object );
static void tp_object_shutdown( struct threadpool_object *object );
static BOOL tp_object_release( struct threadpool_object *object );
static void tp_instance_initialize( struct threadpool_instance *instance, struct threadpool_object *object );
+static NTSTATUS tp_instance_cleanup( struct threadpool_instance *instance );
static BOOL tp_group_release( struct threadpool_group *group );
static struct threadpool *default_threadpool = NULL;
@@ -311,6 +321,7 @@ static void CALLBACK threadpool_worker_proc( void *param )
TRACE( "callback %p returned\n", object->finalization_callback );
}
+ tp_instance_cleanup( &instance );
RtlEnterCriticalSection( &pool->cs );
pool->num_busy_workers--;
if (!instance.disassociated)
@@ -605,6 +616,48 @@ static void tp_instance_initialize( struct threadpool_instance *instance, struct
@@ -1506,8 +1515,50 @@ static void tp_instance_initialize( struct threadpool_instance *instance, struct
instance->threadid = GetCurrentThreadId();
instance->disassociated = FALSE;
instance->may_run_long = object->may_run_long;
@ -71,8 +55,8 @@ index c40c06a..ebf8b94 100644
+ instance->cleanup.semaphore_count = 0;
+ instance->cleanup.event = NULL;
+ instance->cleanup.library = NULL;
+}
+
}
+static NTSTATUS tp_instance_cleanup( struct threadpool_instance *instance )
+{
+ NTSTATUS status;
@ -107,10 +91,20 @@ index c40c06a..ebf8b94 100644
+ }
+
+ return STATUS_SUCCESS;
}
+ }
+
/* disassociates the current thread from the threadpool object */
@@ -817,6 +870,26 @@ NTSTATUS WINAPI TpAllocWork( TP_WORK **out, PTP_WORK_CALLBACK callback, PVOID us
static void tp_instance_disassociate_thread( struct threadpool_instance *instance )
{
@@ -1636,6 +1687,7 @@ static void CALLBACK threadpool_worker_proc( void *param )
TRACE( "callback %p returned\n", object->finalization_callback );
}
+ tp_instance_cleanup( &instance );
RtlEnterCriticalSection( &pool->cs );
pool->num_busy_workers--;
if (!instance.disassociated)
@@ -1728,6 +1780,26 @@ NTSTATUS WINAPI TpAllocWork( TP_WORK **out, PTP_WORK_CALLBACK callback, PVOID us
}
/***********************************************************************
@ -137,7 +131,7 @@ index c40c06a..ebf8b94 100644
* TpCallbackMayRunLong (NTDLL.@)
*/
NTSTATUS WINAPI TpCallbackMayRunLong( TP_CALLBACK_INSTANCE *instance )
@@ -831,6 +904,87 @@ NTSTATUS WINAPI TpCallbackMayRunLong( TP_CALLBACK_INSTANCE *instance )
@@ -1742,6 +1814,87 @@ NTSTATUS WINAPI TpCallbackMayRunLong( TP_CALLBACK_INSTANCE *instance )
}
/***********************************************************************
@ -226,5 +220,5 @@ index c40c06a..ebf8b94 100644
*/
VOID WINAPI TpDisassociateCallback( TP_CALLBACK_INSTANCE *instance )
--
2.3.0
2.3.3

View File

@ -1,4 +1,4 @@
From 0fbfe7ef91e7c0614cf45b75211ab70b500029db Mon Sep 17 00:00:00 2001
From ac6e2e281ba4f0b6cb9643ed288aaf05fd2710f7 Mon Sep 17 00:00:00 2001
From: Sebastian Lackner <sebastian@fds-team.de>
Date: Wed, 4 Mar 2015 08:01:00 +0100
Subject: ntdll: Add remaining threadpool functions to specfile.
@ -8,10 +8,10 @@ Subject: ntdll: Add remaining threadpool functions to specfile.
1 file changed, 43 insertions(+)
diff --git a/dlls/ntdll/ntdll.spec b/dlls/ntdll/ntdll.spec
index 0c5ad39..970bdeb 100644
index 6100a7e..19e63a5 100644
--- a/dlls/ntdll/ntdll.spec
+++ b/dlls/ntdll/ntdll.spec
@@ -967,24 +967,67 @@
@@ -968,24 +968,67 @@
@ stdcall RtlxOemStringToUnicodeSize(ptr) RtlOemStringToUnicodeSize
@ stdcall RtlxUnicodeStringToAnsiSize(ptr) RtlUnicodeStringToAnsiSize
@ stdcall RtlxUnicodeStringToOemSize(ptr) RtlUnicodeStringToOemSize
@ -80,5 +80,5 @@ index 0c5ad39..970bdeb 100644
@ stdcall -ret64 VerSetConditionMask(int64 long long)
@ stdcall ZwAcceptConnectPort(ptr long ptr long long ptr) NtAcceptConnectPort
--
2.3.0
2.3.3

View File

@ -1,18 +1,18 @@
From badc2951cd6764ce4115097874dadcdfa084354e Mon Sep 17 00:00:00 2001
From fa631b5349a02927f1fec95235a40e7b9a75e7b6 Mon Sep 17 00:00:00 2001
From: Sebastian Lackner <sebastian@fds-team.de>
Date: Wed, 4 Mar 2015 08:19:47 +0100
Subject: ntdll: Implement threadpool timer functions. (rev 2)
---
dlls/ntdll/ntdll.spec | 10 +-
dlls/ntdll/threadpool2.c | 390 ++++++++++++++++++++++++++++++++++++++++++++++-
2 files changed, 394 insertions(+), 6 deletions(-)
dlls/ntdll/ntdll.spec | 10 +-
dlls/ntdll/threadpool.c | 383 +++++++++++++++++++++++++++++++++++++++++++++++-
2 files changed, 387 insertions(+), 6 deletions(-)
diff --git a/dlls/ntdll/ntdll.spec b/dlls/ntdll/ntdll.spec
index 970bdeb..24b4c30 100644
index 19e63a5..7aa8bda 100644
--- a/dlls/ntdll/ntdll.spec
+++ b/dlls/ntdll/ntdll.spec
@@ -973,7 +973,7 @@
@@ -974,7 +974,7 @@
# @ stub TpAllocIoCompletion
# @ stub TpAllocJobNotification
@ stdcall TpAllocPool(ptr ptr)
@ -21,7 +21,7 @@ index 970bdeb..24b4c30 100644
# @ stub TpAllocWait
@ stdcall TpAllocWork(ptr ptr ptr ptr)
# @ stub TpAlpcRegisterCompletionList
@@ -995,7 +995,7 @@
@@ -996,7 +996,7 @@
# @ stub TpDbgSetLogRoutine
# @ stub TpDisablePoolCallbackChecks
@ stdcall TpDisassociateCallback(ptr)
@ -30,7 +30,7 @@ index 970bdeb..24b4c30 100644
@ stdcall TpPostWork(ptr)
# @ stub TpQueryPoolStackInformation
# @ stub TpReleaseAlpcCompletion
@@ -1004,7 +1004,7 @@
@@ -1005,7 +1005,7 @@
# @ stub TpReleaseIoCompletion
# @ stub TpReleaseJobNotification
@ stdcall TpReleasePool(ptr)
@ -39,7 +39,7 @@ index 970bdeb..24b4c30 100644
# @ stub TpReleaseWait
@ stdcall TpReleaseWork(ptr)
# @ stub TpSetDefaultPoolMaxThreads
@@ -1015,7 +1015,7 @@
@@ -1016,7 +1016,7 @@
# @ stub TpSetPoolStackInformation
# @ stub TpSetPoolThreadBasePriority
# @ stub TpSetPoolWorkerThreadIdleTimeout
@ -48,7 +48,7 @@ index 970bdeb..24b4c30 100644
# @ stub TpSetTimerEx
# @ stub TpSetWait
# @ stub TpSetWaitEx
@@ -1026,7 +1026,7 @@
@@ -1027,7 +1027,7 @@
# @ stub TpWaitForAlpcCompletion
# @ stub TpWaitForIoCompletion
# @ stub TpWaitForJobNotification
@ -57,11 +57,11 @@ index 970bdeb..24b4c30 100644
# @ stub TpWaitForWait
@ stdcall TpWaitForWork(ptr long)
@ stdcall -ret64 VerSetConditionMask(int64 long long)
diff --git a/dlls/ntdll/threadpool2.c b/dlls/ntdll/threadpool2.c
index ebf8b94..a1089a4 100644
--- a/dlls/ntdll/threadpool2.c
+++ b/dlls/ntdll/threadpool2.c
@@ -68,7 +68,8 @@ struct threadpool
diff --git a/dlls/ntdll/threadpool.c b/dlls/ntdll/threadpool.c
index aa2d8e9..afb35aa 100644
--- a/dlls/ntdll/threadpool.c
+++ b/dlls/ntdll/threadpool.c
@@ -157,7 +157,8 @@ struct threadpool
enum threadpool_objtype
{
TP_OBJECT_TYPE_SIMPLE,
@ -71,7 +71,7 @@ index ebf8b94..a1089a4 100644
};
/* internal threadpool object representation */
@@ -104,6 +105,18 @@ struct threadpool_object
@@ -193,6 +194,18 @@ struct threadpool_object
{
PTP_WORK_CALLBACK callback;
} work;
@ -90,7 +90,7 @@ index ebf8b94..a1089a4 100644
} u;
};
@@ -135,6 +148,33 @@ struct threadpool_group
@@ -224,6 +237,33 @@ struct threadpool_group
struct list members;
};
@ -124,7 +124,7 @@ index ebf8b94..a1089a4 100644
static inline struct threadpool *impl_from_TP_POOL( TP_POOL *pool )
{
return (struct threadpool *)pool;
@@ -147,6 +187,13 @@ static inline struct threadpool_object *impl_from_TP_WORK( TP_WORK *work )
@@ -236,6 +276,13 @@ static inline struct threadpool_object *impl_from_TP_WORK( TP_WORK *work )
return object;
}
@ -138,17 +138,17 @@ index ebf8b94..a1089a4 100644
static inline struct threadpool_group *impl_from_TP_CLEANUP_GROUP( TP_CLEANUP_GROUP *group )
{
return (struct threadpool_group *)group;
@@ -158,6 +205,7 @@ static inline struct threadpool_instance *impl_from_TP_CALLBACK_INSTANCE( TP_CAL
@@ -247,6 +294,7 @@ static inline struct threadpool_instance *impl_from_TP_CALLBACK_INSTANCE( TP_CAL
}
static void CALLBACK threadpool_worker_proc( void *param );
+static void CALLBACK timerqueue_thread_proc( void *param );
static NTSTATUS tp_threadpool_alloc( struct threadpool **out );
static void tp_threadpool_shutdown( struct threadpool *pool );
static BOOL tp_threadpool_release( struct threadpool *pool );
@@ -168,6 +216,230 @@ static void tp_instance_initialize( struct threadpool_instance *instance, struct
static NTSTATUS tp_instance_cleanup( struct threadpool_instance *instance );
static BOOL tp_group_release( struct threadpool_group *group );
static void tp_object_submit( struct threadpool_object *object );
static void tp_object_shutdown( struct threadpool_object *object );
static BOOL tp_object_release( struct threadpool_object *object );
@@ -1170,6 +1218,230 @@ NTSTATUS WINAPI RtlDeleteTimer(HANDLE TimerQueue, HANDLE Timer,
return status;
}
+static NTSTATUS tp_timerqueue_acquire( struct threadpool_object *timer )
+{
@ -374,10 +374,20 @@ index ebf8b94..a1089a4 100644
+ RtlLeaveCriticalSection( &timerqueue.cs );
+}
+
static struct threadpool *default_threadpool = NULL;
/* allocate a new threadpool (with at least one worker thread) */
static NTSTATUS tp_threadpool_alloc( struct threadpool **out )
{
@@ -1466,6 +1738,9 @@ static void tp_object_wait( struct threadpool_object *object )
/* mark an object as 'shutdown', submitting is no longer possible */
static void tp_object_shutdown( struct threadpool_object *object )
{
+ if (object->type == TP_OBJECT_TYPE_TIMER)
+ tp_timerqueue_release( object );
+
object->shutdown = TRUE;
}
/* allocates or returns the default threadpool */
@@ -307,6 +579,15 @@ static void CALLBACK threadpool_worker_proc( void *param )
@@ -1673,6 +1948,15 @@ static void CALLBACK threadpool_worker_proc( void *param )
break;
}
@ -393,17 +403,21 @@ index ebf8b94..a1089a4 100644
default:
assert(0);
break;
@@ -482,6 +763,43 @@ static NTSTATUS tp_object_alloc_work( struct threadpool_object **out, PTP_WORK_C
return STATUS_SUCCESS;
@@ -1747,6 +2031,48 @@ NTSTATUS WINAPI TpAllocPool( TP_POOL **out, PVOID reserved )
}
+static NTSTATUS tp_object_alloc_timer( struct threadpool_object **out, PTP_TIMER_CALLBACK callback,
+ PVOID userdata, TP_CALLBACK_ENVIRON *environment )
/***********************************************************************
+ * TpAllocTimer (NTDLL.@)
+ */
+NTSTATUS WINAPI TpAllocTimer( TP_TIMER **out, PTP_TIMER_CALLBACK callback, PVOID userdata,
+ TP_CALLBACK_ENVIRON *environment )
+{
+ struct threadpool_object *object;
+ struct threadpool *pool = NULL;
+ NTSTATUS status;
+
+ TRACE("%p %p %p %p\n", out, callback, userdata, environment);
+
+ if (environment)
+ pool = (struct threadpool *)environment->Pool;
+
@ -430,43 +444,15 @@ index ebf8b94..a1089a4 100644
+
+ tp_object_initialize( object, pool, userdata, environment );
+
+ *out = object;
+ *out = (TP_TIMER *)object;
+ return STATUS_SUCCESS;
+}
+
/* submits an object to a threadpool */
static void tp_object_submit( struct threadpool_object *object )
{
@@ -567,6 +885,9 @@ static void tp_object_wait( struct threadpool_object *object )
/* mark an object as 'shutdown', submitting is no longer possible */
static void tp_object_shutdown( struct threadpool_object *object )
{
+ if (object->type == TP_OBJECT_TYPE_TIMER)
+ tp_timerqueue_release( object );
+
object->shutdown = TRUE;
}
@@ -858,6 +1179,18 @@ NTSTATUS WINAPI TpAllocPool( TP_POOL **out, PVOID reserved )
}
/***********************************************************************
+ * TpAllocTimer (NTDLL.@)
+ */
+NTSTATUS WINAPI TpAllocTimer( TP_TIMER **out, PTP_TIMER_CALLBACK callback, PVOID userdata,
+ TP_CALLBACK_ENVIRON *environment )
+{
+ TRACE("%p %p %p %p\n", out, callback, userdata, environment);
+
+ return tp_object_alloc_timer( (struct threadpool_object **)out, callback,
+ userdata, environment );
+}
+
+/***********************************************************************
* TpAllocWork (NTDLL.@)
*/
NTSTATUS WINAPI TpAllocWork( TP_WORK **out, PTP_WORK_CALLBACK callback, PVOID userdata,
@@ -999,6 +1332,17 @@ VOID WINAPI TpDisassociateCallback( TP_CALLBACK_INSTANCE *instance )
@@ -1909,6 +2235,17 @@ VOID WINAPI TpDisassociateCallback( TP_CALLBACK_INSTANCE *instance )
}
/***********************************************************************
@ -484,7 +470,7 @@ index ebf8b94..a1089a4 100644
* TpPostWork (NTDLL.@)
*/
VOID WINAPI TpPostWork( TP_WORK *work )
@@ -1057,6 +1401,21 @@ VOID WINAPI TpReleasePool( TP_POOL *pool )
@@ -2017,6 +2354,21 @@ VOID WINAPI TpReleasePool( TP_POOL *pool )
}
/***********************************************************************
@ -506,7 +492,7 @@ index ebf8b94..a1089a4 100644
* TpReleaseWork (NTDLL.@)
*/
VOID WINAPI TpReleaseWork( TP_WORK *work )
@@ -1105,6 +1464,20 @@ BOOL WINAPI TpSetPoolMinThreads( TP_POOL *pool, DWORD minimum )
@@ -2065,6 +2417,20 @@ BOOL WINAPI TpSetPoolMinThreads( TP_POOL *pool, DWORD minimum )
}
/***********************************************************************
@ -527,7 +513,7 @@ index ebf8b94..a1089a4 100644
* TpSimpleTryPost (NTDLL.@)
*/
NTSTATUS WINAPI TpSimpleTryPost( PTP_SIMPLE_CALLBACK callback, PVOID userdata,
@@ -1116,6 +1489,21 @@ NTSTATUS WINAPI TpSimpleTryPost( PTP_SIMPLE_CALLBACK callback, PVOID userdata,
@@ -2097,6 +2463,21 @@ NTSTATUS WINAPI TpSimpleTryPost( PTP_SIMPLE_CALLBACK callback, PVOID userdata,
}
/***********************************************************************
@ -550,5 +536,5 @@ index ebf8b94..a1089a4 100644
*/
VOID WINAPI TpWaitForWork( TP_WORK *work, BOOL cancel_pending )
--
2.3.0
2.3.3

View File

@ -1,4 +1,4 @@
From 63d215c8d93f67821f4defe1dcb61f7702639c1a Mon Sep 17 00:00:00 2001
From 4a3ad1401f815720b35b0ab48e6ab1cc08835f5e Mon Sep 17 00:00:00 2001
From: Sebastian Lackner <sebastian@fds-team.de>
Date: Wed, 4 Mar 2015 13:17:04 +0100
Subject: ntdll/tests: Add tests for Tp* threadpool functions.
@ -526,5 +526,5 @@ index 1cfd67b..b44b0f5 100644
+ Sleep(100);
}
--
2.3.0
2.3.3

View File

@ -1,4 +1,4 @@
From 62fdd332539cd14b48077665d6c88f12ac12b091 Mon Sep 17 00:00:00 2001
From 6a7aaa0145d32fde06229bae7f8cb879ea2ac182 Mon Sep 17 00:00:00 2001
From: Sebastian Lackner <sebastian@fds-team.de>
Date: Sun, 1 Feb 2015 19:41:13 +0100
Subject: kernel32: Forward various threadpool functions to ntdll.
@ -11,7 +11,7 @@ Subject: kernel32: Forward various threadpool functions to ntdll.
4 files changed, 155 insertions(+), 27 deletions(-)
diff --git a/dlls/kernel32/kernel32.spec b/dlls/kernel32/kernel32.spec
index c95c446..54d83da 100644
index 1179af2..f65f894 100644
--- a/dlls/kernel32/kernel32.spec
+++ b/dlls/kernel32/kernel32.spec
@@ -204,7 +204,7 @@
@ -191,10 +191,10 @@ index d3ecd2a..25801b2 100644
static void test_reserved_tls(void)
diff --git a/dlls/kernel32/thread.c b/dlls/kernel32/thread.c
index 0abfdf1..085b011 100644
index 3dabf94..945fe0b 100644
--- a/dlls/kernel32/thread.c
+++ b/dlls/kernel32/thread.c
@@ -831,3 +831,104 @@ BOOL WINAPI GetThreadPreferredUILanguages( DWORD flags, PULONG count, PCZZWSTR b
@@ -860,3 +860,104 @@ BOOL WINAPI GetThreadPreferredUILanguages( DWORD flags, PULONG count, PCZZWSTR b
*buffersize = 0;
return TRUE;
}
@ -300,10 +300,10 @@ index 0abfdf1..085b011 100644
+ TpSetTimer( timer, due_time ? &timeout : NULL, period, window_length );
+}
diff --git a/include/winternl.h b/include/winternl.h
index 3992309..7608d21 100644
index f88001f..4f16d24 100644
--- a/include/winternl.h
+++ b/include/winternl.h
@@ -2604,6 +2604,33 @@ NTSYSAPI LONGLONG WINAPI RtlLargeIntegerSubtract(LONGLONG,LONGLONG);
@@ -2596,6 +2596,33 @@ NTSYSAPI LONGLONG WINAPI RtlLargeIntegerSubtract(LONGLONG,LONGLONG);
NTSYSAPI NTSTATUS WINAPI RtlLargeIntegerToChar(const ULONGLONG *,ULONG,ULONG,PCHAR);
#endif
@ -338,5 +338,5 @@ index 3992309..7608d21 100644
NTSYSAPI NTSTATUS CDECL wine_nt_to_unix_file_name( const UNICODE_STRING *nameW, ANSI_STRING *unix_name_ret,
--
2.3.0
2.3.3

View File

@ -1,18 +1,18 @@
From 59afc4395781ac5bddc1c846605771529eb2055b Mon Sep 17 00:00:00 2001
From 56bf4aa534b59ba3a7d6175bea587b7b2aba1206 Mon Sep 17 00:00:00 2001
From: Sebastian Lackner <sebastian@fds-team.de>
Date: Wed, 4 Mar 2015 13:33:25 +0100
Subject: ntdll: Implement threadpool wait objects.
---
dlls/ntdll/ntdll.spec | 8 +-
dlls/ntdll/threadpool2.c | 486 ++++++++++++++++++++++++++++++++++++++++++++++-
2 files changed, 483 insertions(+), 11 deletions(-)
dlls/ntdll/ntdll.spec | 8 +-
dlls/ntdll/threadpool.c | 479 +++++++++++++++++++++++++++++++++++++++++++++++-
2 files changed, 476 insertions(+), 11 deletions(-)
diff --git a/dlls/ntdll/ntdll.spec b/dlls/ntdll/ntdll.spec
index 24b4c30..b4cfe69 100644
index 7aa8bda..7c15f76 100644
--- a/dlls/ntdll/ntdll.spec
+++ b/dlls/ntdll/ntdll.spec
@@ -974,7 +974,7 @@
@@ -975,7 +975,7 @@
# @ stub TpAllocJobNotification
@ stdcall TpAllocPool(ptr ptr)
@ stdcall TpAllocTimer(ptr ptr ptr)
@ -21,7 +21,7 @@ index 24b4c30..b4cfe69 100644
@ stdcall TpAllocWork(ptr ptr ptr ptr)
# @ stub TpAlpcRegisterCompletionList
# @ stub TpAlpcUnregisterCompletionList
@@ -1005,7 +1005,7 @@
@@ -1006,7 +1006,7 @@
# @ stub TpReleaseJobNotification
@ stdcall TpReleasePool(ptr)
@ stdcall TpReleaseTimer(ptr)
@ -30,7 +30,7 @@ index 24b4c30..b4cfe69 100644
@ stdcall TpReleaseWork(ptr)
# @ stub TpSetDefaultPoolMaxThreads
# @ stub TpSetDefaultPoolStackInformation
@@ -1017,7 +1017,7 @@
@@ -1018,7 +1018,7 @@
# @ stub TpSetPoolWorkerThreadIdleTimeout
@ stdcall TpSetTimer(ptr ptr long long)
# @ stub TpSetTimerEx
@ -39,7 +39,7 @@ index 24b4c30..b4cfe69 100644
# @ stub TpSetWaitEx
@ stdcall TpSimpleTryPost(ptr ptr ptr)
# @ stub TpStartAsyncIoOperation
@@ -1027,7 +1027,7 @@
@@ -1028,7 +1028,7 @@
# @ stub TpWaitForIoCompletion
# @ stub TpWaitForJobNotification
@ stdcall TpWaitForTimer(ptr long)
@ -48,19 +48,19 @@ index 24b4c30..b4cfe69 100644
@ stdcall TpWaitForWork(ptr long)
@ stdcall -ret64 VerSetConditionMask(int64 long long)
@ stdcall ZwAcceptConnectPort(ptr long ptr long long ptr) NtAcceptConnectPort
diff --git a/dlls/ntdll/threadpool2.c b/dlls/ntdll/threadpool2.c
index a1089a4..9b2a0c8 100644
--- a/dlls/ntdll/threadpool2.c
+++ b/dlls/ntdll/threadpool2.c
@@ -48,6 +48,7 @@ static inline LONG interlocked_dec( PLONG dest )
}
diff --git a/dlls/ntdll/threadpool.c b/dlls/ntdll/threadpool.c
index afb35aa..706d62b 100644
--- a/dlls/ntdll/threadpool.c
+++ b/dlls/ntdll/threadpool.c
@@ -137,6 +137,7 @@ struct timer_queue
*/
#define THREADPOOL_WORKER_TIMEOUT 5000
+#define MAXIMUM_WAITQUEUE_OBJECTS (MAXIMUM_WAIT_OBJECTS - 1)
/* internal threadpool representation */
struct threadpool
@@ -69,7 +70,8 @@ enum threadpool_objtype
@@ -158,7 +159,8 @@ enum threadpool_objtype
{
TP_OBJECT_TYPE_SIMPLE,
TP_OBJECT_TYPE_WORK,
@ -70,7 +70,7 @@ index a1089a4..9b2a0c8 100644
};
/* internal threadpool object representation */
@@ -117,6 +119,17 @@ struct threadpool_object
@@ -206,6 +208,17 @@ struct threadpool_object
LONG period;
LONG window_length;
} timer;
@ -88,7 +88,7 @@ index a1089a4..9b2a0c8 100644
} u;
};
@@ -175,6 +188,38 @@ static RTL_CRITICAL_SECTION_DEBUG timerqueue_debug =
@@ -264,6 +277,38 @@ static RTL_CRITICAL_SECTION_DEBUG timerqueue_debug =
0, 0, { (DWORD_PTR)(__FILE__ ": timerqueue.cs") }
};
@ -127,7 +127,7 @@ index a1089a4..9b2a0c8 100644
static inline struct threadpool *impl_from_TP_POOL( TP_POOL *pool )
{
return (struct threadpool *)pool;
@@ -194,6 +239,13 @@ static inline struct threadpool_object *impl_from_TP_TIMER( TP_TIMER *timer )
@@ -283,6 +328,13 @@ static inline struct threadpool_object *impl_from_TP_TIMER( TP_TIMER *timer )
return object;
}
@ -141,20 +141,17 @@ index a1089a4..9b2a0c8 100644
static inline struct threadpool_group *impl_from_TP_CLEANUP_GROUP( TP_CLEANUP_GROUP *group )
{
return (struct threadpool_group *)group;
@@ -206,10 +258,11 @@ static inline struct threadpool_instance *impl_from_TP_CALLBACK_INSTANCE( TP_CAL
@@ -295,7 +347,8 @@ static inline struct threadpool_instance *impl_from_TP_CALLBACK_INSTANCE( TP_CAL
static void CALLBACK threadpool_worker_proc( void *param );
static void CALLBACK timerqueue_thread_proc( void *param );
+static void CALLBACK waitqueue_thread_proc( void *param );
static NTSTATUS tp_threadpool_alloc( struct threadpool **out );
static void tp_threadpool_shutdown( struct threadpool *pool );
static BOOL tp_threadpool_release( struct threadpool *pool );
-static void tp_object_submit( struct threadpool_object *object );
+static void CALLBACK waitqueue_thread_proc( void *param );
+static void tp_object_submit( struct threadpool_object *object, BOOL success );
static void tp_object_shutdown( struct threadpool_object *object );
static BOOL tp_object_release( struct threadpool_object *object );
static void tp_instance_initialize( struct threadpool_instance *instance, struct threadpool_object *object );
@@ -347,7 +400,7 @@ update_timer:
static struct threadpool *default_threadpool = NULL;
@@ -1349,7 +1402,7 @@ update_timer:
RtlLeaveCriticalSection( &timerqueue.cs );
if (submit_timer)
@ -163,7 +160,7 @@ index a1089a4..9b2a0c8 100644
}
static void CALLBACK timerqueue_thread_proc( void *param )
@@ -374,7 +427,7 @@ static void CALLBACK timerqueue_thread_proc( void *param )
@@ -1376,7 +1429,7 @@ static void CALLBACK timerqueue_thread_proc( void *param )
/* Queue a new callback in one of the worker threads */
list_remove( &timer->u.timer.timer_entry );
@ -172,7 +169,7 @@ index a1089a4..9b2a0c8 100644
/* Requeue the timer, except its marked for shutdown */
if (!timer->shutdown && timer->u.timer.period)
@@ -440,6 +493,301 @@ static void CALLBACK timerqueue_thread_proc( void *param )
@@ -1442,6 +1495,301 @@ static void CALLBACK timerqueue_thread_proc( void *param )
RtlLeaveCriticalSection( &timerqueue.cs );
}
@ -471,10 +468,58 @@ index a1089a4..9b2a0c8 100644
+ RtlFreeHeap( GetProcessHeap(), 0, bucket );
+}
+
static struct threadpool *default_threadpool = NULL;
/* allocate a new threadpool (with at least one worker thread) */
static NTSTATUS tp_threadpool_alloc( struct threadpool **out )
{
@@ -1633,7 +1981,7 @@ static void tp_object_initialize( struct threadpool_object *object, struct threa
* to the cleanup group. As soon as the cleanup group members are released ->shutdown
* will be set, and tp_object_submit would fail with an assertion. */
if (simple_cb)
- tp_object_submit( object );
+ tp_object_submit( object, FALSE );
/* allocates or returns the default threadpool */
@@ -536,6 +884,7 @@ static void CALLBACK threadpool_worker_proc( void *param )
if (object->group)
{
@@ -1654,7 +2002,7 @@ static void tp_object_initialize( struct threadpool_object *object, struct threa
}
/* submits an object to a threadpool */
-static void tp_object_submit( struct threadpool_object *object )
+static void tp_object_submit( struct threadpool_object *object, BOOL success )
{
struct threadpool *pool = object->pool;
@@ -1689,6 +2037,10 @@ out:
if (!object->num_pending_callbacks++)
list_add_tail( &pool->pool, &object->pool_entry );
+ /* increment success counter by one */
+ if (object->type == TP_OBJECT_TYPE_WAIT && success)
+ object->u.wait.signaled++;
+
RtlLeaveCriticalSection( &pool->cs );
}
@@ -1707,6 +2059,9 @@ static void tp_object_cancel( struct threadpool_object *object, BOOL group_cance
list_remove( &object->pool_entry );
}
+ if (object->type == TP_OBJECT_TYPE_WAIT)
+ object->u.wait.signaled = 0;
+
RtlLeaveCriticalSection( &pool->cs );
/* Execute group cancellation callback if defined, and if this was actually a group cancel. */
@@ -1740,6 +2095,8 @@ static void tp_object_shutdown( struct threadpool_object *object )
{
if (object->type == TP_OBJECT_TYPE_TIMER)
tp_timerqueue_release( object );
+ else if (object->type == TP_OBJECT_TYPE_WAIT)
+ tp_waitqueue_release( object );
object->shutdown = TRUE;
}
@@ -1905,6 +2262,7 @@ static void CALLBACK threadpool_worker_proc( void *param )
struct threadpool_instance instance;
TP_CALLBACK_INSTANCE *cb_instance = (TP_CALLBACK_INSTANCE *)&instance;
struct threadpool *pool = param;
@ -482,7 +527,7 @@ index a1089a4..9b2a0c8 100644
LARGE_INTEGER timeout;
struct list *ptr;
@@ -553,6 +902,18 @@ static void CALLBACK threadpool_worker_proc( void *param )
@@ -1922,6 +2280,18 @@ static void CALLBACK threadpool_worker_proc( void *param )
if (--object->num_pending_callbacks)
list_add_tail( &pool->pool, &object->pool_entry );
@ -501,7 +546,7 @@ index a1089a4..9b2a0c8 100644
/* Leave critical section and do the actual callback. */
object->num_running_callbacks++;
pool->num_busy_workers++;
@@ -588,6 +949,15 @@ static void CALLBACK threadpool_worker_proc( void *param )
@@ -1957,6 +2327,15 @@ static void CALLBACK threadpool_worker_proc( void *param )
break;
}
@ -517,26 +562,21 @@ index a1089a4..9b2a0c8 100644
default:
assert(0);
break;
@@ -687,7 +1057,7 @@ static void tp_object_initialize( struct threadpool_object *object, struct threa
* to the cleanup group. As soon as the cleanup group members are released ->shutdown
* will be set, and tp_object_submit would fail with an assertion. */
if (simple_cb)
- tp_object_submit( object );
+ tp_object_submit( object, FALSE );
if (object->group)
{
@@ -800,8 +1170,45 @@ static NTSTATUS tp_object_alloc_timer( struct threadpool_object **out, PTP_TIMER
return STATUS_SUCCESS;
@@ -2073,6 +2452,48 @@ NTSTATUS WINAPI TpAllocTimer( TP_TIMER **out, PTP_TIMER_CALLBACK callback, PVOID
}
+static NTSTATUS tp_object_alloc_wait( struct threadpool_object **out, PTP_WAIT_CALLBACK callback,
+ PVOID userdata, TP_CALLBACK_ENVIRON *environment )
/***********************************************************************
+ * TpAllocWait (NTDLL.@)
+ */
+NTSTATUS WINAPI TpAllocWait( TP_WAIT **out, PTP_WAIT_CALLBACK callback, PVOID userdata,
+ TP_CALLBACK_ENVIRON *environment )
+{
+ struct threadpool_object *object;
+ struct threadpool *pool = NULL;
+ NTSTATUS status;
+
+ TRACE("%p %p %p %p\n", out, callback, userdata, environment);
+
+ if (environment)
+ pool = (struct threadpool *)environment->Pool;
+
@ -563,66 +603,15 @@ index a1089a4..9b2a0c8 100644
+
+ tp_object_initialize( object, pool, userdata, environment );
+
+ *out = object;
+ *out = (TP_WAIT *)object;
+ return STATUS_SUCCESS;
+}
+
/* submits an object to a threadpool */
-static void tp_object_submit( struct threadpool_object *object )
+static void tp_object_submit( struct threadpool_object *object, BOOL success )
{
struct threadpool *pool = object->pool;
@@ -836,6 +1243,10 @@ out:
if (!object->num_pending_callbacks++)
list_add_tail( &pool->pool, &object->pool_entry );
+ /* increment success counter by one */
+ if (object->type == TP_OBJECT_TYPE_WAIT && success)
+ object->u.wait.signaled++;
+
RtlLeaveCriticalSection( &pool->cs );
}
@@ -854,6 +1265,9 @@ static void tp_object_cancel( struct threadpool_object *object, BOOL group_cance
list_remove( &object->pool_entry );
}
+ if (object->type == TP_OBJECT_TYPE_WAIT)
+ object->u.wait.signaled = 0;
+
RtlLeaveCriticalSection( &pool->cs );
/* Execute group cancellation callback if defined, and if this was actually a group cancel. */
@@ -887,6 +1301,8 @@ static void tp_object_shutdown( struct threadpool_object *object )
{
if (object->type == TP_OBJECT_TYPE_TIMER)
tp_timerqueue_release( object );
+ else if (object->type == TP_OBJECT_TYPE_WAIT)
+ tp_waitqueue_release( object );
object->shutdown = TRUE;
}
@@ -1191,6 +1607,18 @@ NTSTATUS WINAPI TpAllocTimer( TP_TIMER **out, PTP_TIMER_CALLBACK callback, PVOID
}
/***********************************************************************
+ * TpAllocWait (NTDLL.@)
+ */
+NTSTATUS WINAPI TpAllocWait( TP_WAIT **out, PTP_WAIT_CALLBACK callback, PVOID userdata,
+ TP_CALLBACK_ENVIRON *environment )
+{
+ TRACE("%p %p %p %p\n", out, callback, userdata, environment);
+
+ return tp_object_alloc_wait( (struct threadpool_object **)out, callback,
+ userdata, environment );
+}
+
+/***********************************************************************
* TpAllocWork (NTDLL.@)
*/
NTSTATUS WINAPI TpAllocWork( TP_WORK **out, PTP_WORK_CALLBACK callback, PVOID userdata,
@@ -1352,7 +1780,7 @@ VOID WINAPI TpPostWork( TP_WORK *work )
@@ -2255,7 +2676,7 @@ VOID WINAPI TpPostWork( TP_WORK *work )
if (this)
{
@ -631,7 +620,7 @@ index a1089a4..9b2a0c8 100644
}
}
@@ -1416,6 +1844,21 @@ VOID WINAPI TpReleaseTimer( TP_TIMER *timer )
@@ -2369,6 +2790,21 @@ VOID WINAPI TpReleaseTimer( TP_TIMER *timer )
}
/***********************************************************************
@ -653,7 +642,7 @@ index a1089a4..9b2a0c8 100644
* TpReleaseWork (NTDLL.@)
*/
VOID WINAPI TpReleaseWork( TP_WORK *work )
@@ -1478,6 +1921,20 @@ VOID WINAPI TpSetTimer( TP_TIMER *timer, LARGE_INTEGER *timeout, LONG period, LO
@@ -2431,6 +2867,20 @@ VOID WINAPI TpSetTimer( TP_TIMER *timer, LARGE_INTEGER *timeout, LONG period, LO
}
/***********************************************************************
@ -674,7 +663,7 @@ index a1089a4..9b2a0c8 100644
* TpSimpleTryPost (NTDLL.@)
*/
NTSTATUS WINAPI TpSimpleTryPost( PTP_SIMPLE_CALLBACK callback, PVOID userdata,
@@ -1504,6 +1961,21 @@ VOID WINAPI TpWaitForTimer( TP_TIMER *timer, BOOL cancel_pending )
@@ -2478,6 +2928,21 @@ VOID WINAPI TpWaitForTimer( TP_TIMER *timer, BOOL cancel_pending )
}
/***********************************************************************
@ -697,5 +686,5 @@ index a1089a4..9b2a0c8 100644
*/
VOID WINAPI TpWaitForWork( TP_WORK *work, BOOL cancel_pending )
--
2.3.0
2.3.3

View File

@ -1,4 +1,4 @@
From be47a4f14f26fde351a5a2d0bd9d613bb56a1268 Mon Sep 17 00:00:00 2001
From 274f80bef1283a43868aedf0ea55f5b842ceff86 Mon Sep 17 00:00:00 2001
From: Sebastian Lackner <sebastian@fds-team.de>
Date: Fri, 6 Feb 2015 20:09:41 +0100
Subject: ntdll/tests: Add tests for threadpool wait objects.
@ -313,5 +313,5 @@ index b44b0f5..91d1b95 100644
/* FIXME: Make sure worker threads have terminated before. */
Sleep(100);
--
2.3.0
2.3.3

View File

@ -1,4 +1,4 @@
From 921fe6b2ea88ca6be056a8fd733ae099f2839eb5 Mon Sep 17 00:00:00 2001
From bd2b6f3c1602f5bd24781ae12052994cae0bad73 Mon Sep 17 00:00:00 2001
From: Sebastian Lackner <sebastian@fds-team.de>
Date: Fri, 6 Feb 2015 20:24:27 +0100
Subject: kernel32: Forward threadpool wait functions to ntdll.
@ -10,7 +10,7 @@ Subject: kernel32: Forward threadpool wait functions to ntdll.
3 files changed, 51 insertions(+), 4 deletions(-)
diff --git a/dlls/kernel32/kernel32.spec b/dlls/kernel32/kernel32.spec
index 54d83da..abee11b 100644
index f65f894..4eba956 100644
--- a/dlls/kernel32/kernel32.spec
+++ b/dlls/kernel32/kernel32.spec
@@ -233,7 +233,7 @@
@ -50,10 +50,10 @@ index 54d83da..abee11b 100644
@ stdcall WaitNamedPipeA (str long)
@ stdcall WaitNamedPipeW (wstr long)
diff --git a/dlls/kernel32/thread.c b/dlls/kernel32/thread.c
index 085b011..77037ef 100644
index 945fe0b..89b0b60 100644
--- a/dlls/kernel32/thread.c
+++ b/dlls/kernel32/thread.c
@@ -894,6 +894,27 @@ PTP_TIMER WINAPI CreateThreadpoolTimer( PTP_TIMER_CALLBACK callback, PVOID userd
@@ -923,6 +923,27 @@ PTP_TIMER WINAPI CreateThreadpoolTimer( PTP_TIMER_CALLBACK callback, PVOID userd
}
/***********************************************************************
@ -81,7 +81,7 @@ index 085b011..77037ef 100644
* CreateThreadpoolWork (KERNEL32.@)
*/
PTP_WORK WINAPI CreateThreadpoolWork( PTP_WORK_CALLBACK callback, PVOID userdata,
@@ -932,3 +953,25 @@ VOID WINAPI SetThreadpoolTimer( TP_TIMER *timer, FILETIME *due_time,
@@ -961,3 +982,25 @@ VOID WINAPI SetThreadpoolTimer( TP_TIMER *timer, FILETIME *due_time,
TpSetTimer( timer, due_time ? &timeout : NULL, period, window_length );
}
@ -108,10 +108,10 @@ index 085b011..77037ef 100644
+ TpSetWait( wait, handle, due_time ? &timeout : NULL );
+}
diff --git a/include/winternl.h b/include/winternl.h
index 7608d21..dca7f46 100644
index 4f16d24..ee38c48 100644
--- a/include/winternl.h
+++ b/include/winternl.h
@@ -2609,6 +2609,7 @@ NTSYSAPI NTSTATUS WINAPI RtlLargeIntegerToChar(const ULONGLONG *,ULONG,ULONG,PC
@@ -2601,6 +2601,7 @@ NTSYSAPI NTSTATUS WINAPI RtlLargeIntegerToChar(const ULONGLONG *,ULONG,ULONG,PC
NTSYSAPI NTSTATUS WINAPI TpAllocCleanupGroup(TP_CLEANUP_GROUP **);
NTSYSAPI NTSTATUS WINAPI TpAllocPool(TP_POOL **,PVOID);
NTSYSAPI NTSTATUS WINAPI TpAllocTimer(TP_TIMER **,PTP_TIMER_CALLBACK,PVOID,TP_CALLBACK_ENVIRON *);
@ -119,7 +119,7 @@ index 7608d21..dca7f46 100644
NTSYSAPI NTSTATUS WINAPI TpAllocWork(TP_WORK **,PTP_WORK_CALLBACK,PVOID,TP_CALLBACK_ENVIRON *);
NTSYSAPI void WINAPI TpCallbackLeaveCriticalSectionOnCompletion(TP_CALLBACK_INSTANCE *,RTL_CRITICAL_SECTION *);
NTSYSAPI NTSTATUS WINAPI TpCallbackMayRunLong(TP_CALLBACK_INSTANCE *);
@@ -2623,12 +2624,15 @@ NTSYSAPI void WINAPI TpReleaseCleanupGroup(TP_CLEANUP_GROUP *);
@@ -2615,12 +2616,15 @@ NTSYSAPI void WINAPI TpReleaseCleanupGroup(TP_CLEANUP_GROUP *);
NTSYSAPI void WINAPI TpReleaseCleanupGroupMembers(TP_CLEANUP_GROUP *,BOOL,PVOID);
NTSYSAPI void WINAPI TpReleasePool(TP_POOL *);
NTSYSAPI void WINAPI TpReleaseTimer(TP_TIMER *);
@ -136,5 +136,5 @@ index 7608d21..dca7f46 100644
/* Wine internal functions */
--
2.3.0
2.3.3

View File

@ -3197,8 +3197,8 @@ fi
# | * [#37306] Implement threadpool timers
# |
# | Modified files:
# | * dlls/kernel32/kernel32.spec, dlls/kernel32/tests/thread.c, dlls/kernel32/thread.c, dlls/ntdll/Makefile.in,
# | dlls/ntdll/ntdll.spec, dlls/ntdll/tests/threadpool.c, dlls/ntdll/threadpool2.c, include/winternl.h
# | * dlls/kernel32/kernel32.spec, dlls/kernel32/tests/thread.c, dlls/kernel32/thread.c, dlls/ntdll/ntdll.spec,
# | dlls/ntdll/tests/threadpool.c, dlls/ntdll/threadpool.c, include/winternl.h
# |
if test "$enable_ntdll_Vista_Threadpool" -eq 1; then
patch_apply ntdll-Vista_Threadpool/0001-ntdll-Implement-TpSimpleTryPost-and-basic-threadpool.patch