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/t... ============================================================================== --- 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; }