Saturday, May 18, 2013

WaitForMultipleObjects 和 KeWaitForMultipleObjects 备忘

WaitForMultipleObjects 和 KeWaitForMultipleObjects 备忘
联系起来看这两个函数才能真正搞明白,先看内核函数,再看API


NTSTATUS
  KeWaitForMultipleObjects(
    IN ULONG  Count,
    IN PVOID  Object[],
    IN WAIT_TYPE  WaitType,
    IN KWAIT_REASON  WaitReason,
    IN KPROCESSOR_MODE  WaitMode,
    IN BOOLEAN  Alertable,
    IN PLARGE_INTEGER  Timeout  OPTIONAL,
    IN PKWAIT_BLOCK  WaitBlockArray  OPTIONAL
    );
KeWaitForMultipleObjects can return one of the following:

STATUS_SUCCESS
The caller specified WaitAll for the WaitType parameter and all dispatcher objects in the Object array have been set to the signaled state.
STATUS_ALERTED
The wait was interrupted to deliver an alert to the calling thread.
STATUS_USER_APC
The wait was interrupted to deliver a user asynchronous procedure call (APC) to the calling thread.
STATUS_TIMEOUT
A time-out occurred before the specified set of wait conditions was met. This value can be returned when an explicit time-out value of zero is specified, but the specified set of wait conditions cannot be met immediately.
STATUS_WAIT_0 through STATUS_WAIT_63
The caller specified WaitAny for WaitType and one of the dispatcher objects in the Object array has been set to the signaled state. The lower six bits of the return value encode the zero-based index of the object that satisfied the wait.
STATUS_ABANDONED_WAIT_0 through STATUS_ABANDONED_WAIT_63
The caller attempted to wait for a mutex that has been abandoned. The lower six bits of the return value encode the zero-based index of the mutex in the Object array.

Note that the NT_SUCCESS macro recognizes all of these status values as "success" values.



DWORD WINAPI WaitForMultipleObjects(
  __in  DWORD nCount,   
  __in  const HANDLE* lpHandles,
  __in  BOOL bWaitAll,
  __in  DWORD dwMilliseconds
);
nCount表明想要等待的对象个数,最大值MAXIMUM_WAIT_OBJECTS(0x40)。它满足:
    0 < MAXIMUM_WAIT_OBJECTS < WAIT_ABANDONED_0
后面会介绍原因。
lpHandles表明想要等待的对象数组,可以等待的对象有事件、信号量(注意一个信号量中有很多信号灯)、互斥量、线程,Process,Console input and so on。

If the function succeeds, the return value indicates the event that caused the function to return. It can be one of the following values. (Note that WAIT_OBJECT_0 is defined as 0 and WAIT_ABANDONED_0 is defined as 0x00000080L.):
WAIT_OBJECT_0 to (WAIT_OBJECT_0 + nCount– 1) =>
If bWaitAll is TRUE, the return value indicates that the state of all specified objects is signaled.
If bWaitAll is FALSE, the return value minus WAIT_OBJECT_0 indicates the lpHandles array index of the object that satisfied the wait. If more than one object became signaled during the call, this is the array index of the signaled object with the smallest index value of all the signaled objects.

WAIT_ABANDONED_0 to (WAIT_ABANDONED_0 + nCount– 1) =>
If bWaitAll is TRUE, the return value indicates that the state of all specified objects is signaled and at least one of the objects is an abandoned mutex object(see KeWaitForMultipleObjects for detail).
If bWaitAll is FALSE, the return value minus WAIT_ABANDONED_0 indicates the lpHandles array index of an abandoned mutex object that satisfied the wait. Ownership of the mutex object is granted to the calling thread, and the mutex is set to nonsignaled.

If a mutex was protecting persistent state information, you should check it for consistency.

No comments:

Post a Comment