[ros-diffs] [dchapyshev] 42122: - Revert my previous changes in QueueUserWorkItem
dchapyshev at svn.reactos.org
dchapyshev at svn.reactos.org
Tue Jul 21 18:38:50 CEST 2009
Author: dchapyshev
Date: Tue Jul 21 18:38:50 2009
New Revision: 42122
URL: http://svn.reactos.org/svn/reactos?rev=42122&view=rev
Log:
- Revert my previous changes in QueueUserWorkItem
Modified:
trunk/reactos/dll/win32/kernel32/thread/thread.c
Modified: trunk/reactos/dll/win32/kernel32/thread/thread.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/kernel32/thread/thread.c?rev=42122&r1=42121&r2=42122&view=diff
==============================================================================
--- trunk/reactos/dll/win32/kernel32/thread/thread.c [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/kernel32/thread/thread.c [iso-8859-1] Tue Jul 21 18:38:50 2009
@@ -854,6 +854,34 @@
}
+typedef struct _QUEUE_USER_WORKITEM_CONTEXT
+{
+ LPTHREAD_START_ROUTINE Function;
+ PVOID Context;
+} QUEUE_USER_WORKITEM_CONTEXT, *PQUEUE_USER_WORKITEM_CONTEXT;
+
+static VOID
+NTAPI
+InternalWorkItemTrampoline(PVOID Context)
+{
+ QUEUE_USER_WORKITEM_CONTEXT Info;
+
+ ASSERT(Context);
+
+ /* Save the context to the stack */
+ Info = *(volatile QUEUE_USER_WORKITEM_CONTEXT *)Context;
+
+ /* Free the context before calling the callback. This avoids
+ a memory leak in case the thread dies... */
+ RtlFreeHeap(RtlGetProcessHeap(),
+ 0,
+ Context);
+
+ /* Call the real callback */
+ Info.Function(Info.Context);
+}
+
+
/*
* @implemented
*/
@@ -865,13 +893,34 @@
ULONG Flags
)
{
- NTSTATUS Status;
-
- Status = RtlQueueWorkItem((WORKERCALLBACKFUNC)Function,
- Context,
+ PQUEUE_USER_WORKITEM_CONTEXT WorkItemContext;
+ NTSTATUS Status;
+
+ /* Save the context for the trampoline function */
+ WorkItemContext = RtlAllocateHeap(RtlGetProcessHeap(),
+ 0,
+ sizeof(*WorkItemContext));
+ if (WorkItemContext == NULL)
+ {
+ SetLastError(ERROR_NOT_ENOUGH_MEMORY);
+ return FALSE;
+ }
+
+ WorkItemContext->Function = Function;
+ WorkItemContext->Context = Context;
+
+ /* NOTE: Don't use Function directly since the callback signature
+ differs. This might cause problems on certain platforms... */
+ Status = RtlQueueWorkItem(InternalWorkItemTrampoline,
+ WorkItemContext,
Flags);
if (!NT_SUCCESS(Status))
{
+ /* Free the allocated context in case of failure */
+ RtlFreeHeap(RtlGetProcessHeap(),
+ 0,
+ WorkItemContext);
+
SetLastErrorByStatus(Status);
return FALSE;
}
More information about the Ros-diffs
mailing list