- Samplify SwitchToThread and QueueUserWorkItem

- Remove unneeded InternalWorkItemTrampoline function and QUEUE_USER_WORKITEM_CONTEXT structure
- Other small changes

svn path=/trunk/; revision=42012
This commit is contained in:
Dmitry Chapyshev 2009-07-17 18:42:12 +00:00
parent c0db0a0a0b
commit 3b39cbc701

View file

@ -263,13 +263,13 @@ OpenThread(DWORD dwDesiredAccess,
BOOL bInheritHandle, BOOL bInheritHandle,
DWORD dwThreadId) DWORD dwThreadId)
{ {
NTSTATUS errCode; NTSTATUS Status;
HANDLE ThreadHandle; HANDLE ThreadHandle;
OBJECT_ATTRIBUTES ObjectAttributes; OBJECT_ATTRIBUTES ObjectAttributes;
CLIENT_ID ClientId ; CLIENT_ID ClientId ;
ClientId.UniqueProcess = 0; ClientId.UniqueProcess = 0;
ClientId.UniqueThread = (HANDLE)dwThreadId; ClientId.UniqueThread = ULongToHandle(dwThreadId);
InitializeObjectAttributes(&ObjectAttributes, InitializeObjectAttributes(&ObjectAttributes,
NULL, NULL,
@ -277,13 +277,13 @@ OpenThread(DWORD dwDesiredAccess,
NULL, NULL,
NULL); NULL);
errCode = NtOpenThread(&ThreadHandle, Status = NtOpenThread(&ThreadHandle,
dwDesiredAccess, dwDesiredAccess,
&ObjectAttributes, &ObjectAttributes,
&ClientId); &ClientId);
if (!NT_SUCCESS(errCode)) if (!NT_SUCCESS(Status))
{ {
SetLastErrorByStatus (errCode); SetLastErrorByStatus(Status);
return NULL; return NULL;
} }
@ -306,9 +306,7 @@ BOOL
WINAPI WINAPI
SwitchToThread(VOID) SwitchToThread(VOID)
{ {
NTSTATUS Status; return NtYieldExecution() != STATUS_NO_YIELD_PERFORMED;
Status = NtYieldExecution();
return Status != STATUS_NO_YIELD_PERFORMED;
} }
@ -750,10 +748,10 @@ GetThreadId(HANDLE Thread)
* @unimplemented * @unimplemented
*/ */
LANGID WINAPI LANGID WINAPI
SetThreadUILanguage(WORD wReserved) SetThreadUILanguage(LANGID LangId)
{ {
DPRINT1("SetThreadUILanguage(0x%4x) unimplemented!\n", wReserved); DPRINT1("SetThreadUILanguage(0x%4x) unimplemented!\n", LangId);
return 0; return LangId;
} }
static void CALLBACK static void CALLBACK
@ -773,10 +771,13 @@ QueueUserAPC(PAPCFUNC pfnAPC, HANDLE hThread, ULONG_PTR dwData)
Status = NtQueueApcThread(hThread, IntCallUserApc, pfnAPC, Status = NtQueueApcThread(hThread, IntCallUserApc, pfnAPC,
(PVOID)dwData, NULL); (PVOID)dwData, NULL);
if (Status) if (!NT_SUCCESS(Status))
{
SetLastErrorByStatus(Status); SetLastErrorByStatus(Status);
return 0;
}
return NT_SUCCESS(Status); return 1;
} }
/* /*
@ -853,34 +854,6 @@ dowait:
} }
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 * @implemented
*/ */
@ -892,34 +865,13 @@ QueueUserWorkItem(
ULONG Flags ULONG Flags
) )
{ {
PQUEUE_USER_WORKITEM_CONTEXT WorkItemContext;
NTSTATUS Status; NTSTATUS Status;
/* Save the context for the trampoline function */ Status = RtlQueueWorkItem((WORKERCALLBACKFUNC)Function,
WorkItemContext = RtlAllocateHeap(RtlGetProcessHeap(), Context,
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); Flags);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
/* Free the allocated context in case of failure */
RtlFreeHeap(RtlGetProcessHeap(),
0,
WorkItemContext);
SetLastErrorByStatus(Status); SetLastErrorByStatus(Status);
return FALSE; return FALSE;
} }
@ -942,16 +894,16 @@ RegisterWaitForSingleObject(
ULONG dwFlags ULONG dwFlags
) )
{ {
NTSTATUS Status = RtlRegisterWait( phNewWaitObject, NTSTATUS Status = RtlRegisterWait(phNewWaitObject,
hObject, hObject,
Callback, Callback,
Context, Context,
dwMilliseconds, dwMilliseconds,
dwFlags ); dwFlags);
if (Status != STATUS_SUCCESS) if (!NT_SUCCESS(Status))
{ {
SetLastError( RtlNtStatusToDosError(Status) ); SetLastErrorByStatus(Status);
return FALSE; return FALSE;
} }
return TRUE; return TRUE;
@ -974,18 +926,19 @@ RegisterWaitForSingleObjectEx(
NTSTATUS Status; NTSTATUS Status;
HANDLE hNewWaitObject; HANDLE hNewWaitObject;
Status = RtlRegisterWait( &hNewWaitObject, Status = RtlRegisterWait(&hNewWaitObject,
hObject, hObject,
Callback, Callback,
Context, Context,
dwMilliseconds, dwMilliseconds,
dwFlags ); dwFlags);
if (Status != STATUS_SUCCESS) if (!NT_SUCCESS(Status))
{ {
SetLastError( RtlNtStatusToDosError(Status) ); SetLastErrorByStatus(Status);
return NULL; return NULL;
} }
return hNewWaitObject; return hNewWaitObject;
} }
@ -999,12 +952,14 @@ UnregisterWait(
HANDLE WaitHandle HANDLE WaitHandle
) )
{ {
NTSTATUS Status = RtlDeregisterWaitEx( WaitHandle, NULL ); NTSTATUS Status = RtlDeregisterWaitEx(WaitHandle, NULL);
if (Status != STATUS_SUCCESS)
if (!NT_SUCCESS(Status))
{ {
SetLastError( RtlNtStatusToDosError(Status) ); SetLastErrorByStatus(Status);
return FALSE; return FALSE;
} }
return TRUE; return TRUE;
} }
@ -1019,12 +974,14 @@ UnregisterWaitEx(
HANDLE CompletionEvent HANDLE CompletionEvent
) )
{ {
NTSTATUS Status = RtlDeregisterWaitEx( WaitHandle, CompletionEvent ); NTSTATUS Status = RtlDeregisterWaitEx(WaitHandle, CompletionEvent);
if (Status != STATUS_SUCCESS)
if (!NT_SUCCESS(Status))
{ {
SetLastError( RtlNtStatusToDosError(Status) ); SetLastErrorByStatus(Status);
return FALSE; return FALSE;
} }
return TRUE; return TRUE;
} }