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




svn path=/trunk/; revision=22807
This commit is contained in:
Magnus Olsen 2006-07-03 20:26:58 +00:00
parent 34861fa5e2
commit ae94c696ac
2 changed files with 75 additions and 18 deletions

View file

@ -620,24 +620,6 @@ MapUserPhysicalPagesScatter(
return 0;
}
/*
* @unimplemented
*/
BOOL
STDCALL
QueueUserWorkItem(
LPTHREAD_START_ROUTINE Function,
PVOID Context,
ULONG Flags
)
{
STUB;
return 0;
}
/*
* @unimplemented
*/

View file

@ -873,4 +873,79 @@ SleepEx(DWORD dwMilliseconds,
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 */