Author: greatlrd Date: Tue Jul 4 00:26:58 2006 New Revision: 22807
URL: http://svn.reactos.org/svn/reactos?rev=22807&view=rev Log: 4 of 4 commit (sorry my svn clinet is crazy for moment) Commit w3seek patch from bug 1609 : file attachment (id=910) The attached patch implements QueueUserWorkItem()/RtlQueueWorkItem() (lacks optimizations!!!). WINE's latest rpcrt4 relies on it.
1. Implement QueueUserWorkItem()/RtlQueueWorkItem() : 2. A slightly optimized 3. Supports WT_TRANSFER_IMPERSONATION 4. Slightly improved handling of growing/shrinking the pool by assuming work items with WT_EXECUTELONGFUNCTION run longer 5. Fixes a hack that made a worker thread always terminate if there were at least one more thread available
Modified: trunk/reactos/dll/win32/kernel32/misc/stubs.c trunk/reactos/dll/win32/kernel32/thread/thread.c
Modified: trunk/reactos/dll/win32/kernel32/misc/stubs.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/kernel32/misc/stu... ============================================================================== --- trunk/reactos/dll/win32/kernel32/misc/stubs.c (original) +++ trunk/reactos/dll/win32/kernel32/misc/stubs.c Tue Jul 4 00:26:58 2006 @@ -625,24 +625,6 @@ */ BOOL STDCALL -QueueUserWorkItem( - LPTHREAD_START_ROUTINE Function, - PVOID Context, - ULONG Flags - ) -{ - STUB; - return 0; -} - - - - -/* - * @unimplemented - */ -BOOL -STDCALL ReadFileScatter( HANDLE hFile, FILE_SEGMENT_ELEMENT aSegmentArray[],
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 (original) +++ trunk/reactos/dll/win32/kernel32/thread/thread.c Tue Jul 4 00:26:58 2006 @@ -873,4 +873,79 @@ return 0; }
+ +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 != NULL); + + /* 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 + */ +BOOL +STDCALL +QueueUserWorkItem( + LPTHREAD_START_ROUTINE Function, + PVOID Context, + ULONG Flags + ) +{ + 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; + } + + return TRUE; +} + /* EOF */