mirror of
https://github.com/reactos/reactos.git
synced 2024-12-28 01:55:19 +00:00
Implemented Nt/KeWaitForMultipleObjects (still buggy).
svn path=/trunk/; revision=651
This commit is contained in:
parent
09d88da5e9
commit
1fc6701c79
1 changed files with 117 additions and 73 deletions
|
@ -73,7 +73,9 @@ static BOOLEAN KeDispatcherObjectWakeAll(DISPATCHER_HEADER* hdr)
|
||||||
{
|
{
|
||||||
PKWAIT_BLOCK current;
|
PKWAIT_BLOCK current;
|
||||||
PLIST_ENTRY current_entry;
|
PLIST_ENTRY current_entry;
|
||||||
|
|
||||||
|
DPRINT("KeDispatcherObjectWakeAll(hdr %x)\n",hdr);
|
||||||
|
|
||||||
if (IsListEmpty(&hdr->WaitListHead))
|
if (IsListEmpty(&hdr->WaitListHead))
|
||||||
{
|
{
|
||||||
return(FALSE);
|
return(FALSE);
|
||||||
|
@ -84,7 +86,13 @@ static BOOLEAN KeDispatcherObjectWakeAll(DISPATCHER_HEADER* hdr)
|
||||||
current_entry = RemoveHeadList(&hdr->WaitListHead);
|
current_entry = RemoveHeadList(&hdr->WaitListHead);
|
||||||
current = CONTAINING_RECORD(current_entry,KWAIT_BLOCK,
|
current = CONTAINING_RECORD(current_entry,KWAIT_BLOCK,
|
||||||
WaitListEntry);
|
WaitListEntry);
|
||||||
DPRINT("Waking %x\n",current->Thread);
|
DPRINT("Waking %x\n",current->Thread);
|
||||||
|
|
||||||
|
if (current->NextWaitBlock != NULL)
|
||||||
|
{
|
||||||
|
DbgPrint("DANGLING POINTERS!!! We're in trouble!\n");
|
||||||
|
}
|
||||||
|
|
||||||
PsResumeThread(CONTAINING_RECORD(current->Thread,ETHREAD,Tcb));
|
PsResumeThread(CONTAINING_RECORD(current->Thread,ETHREAD,Tcb));
|
||||||
};
|
};
|
||||||
return(TRUE);
|
return(TRUE);
|
||||||
|
@ -94,7 +102,7 @@ static BOOLEAN KeDispatcherObjectWakeOne(DISPATCHER_HEADER* hdr)
|
||||||
{
|
{
|
||||||
PKWAIT_BLOCK current;
|
PKWAIT_BLOCK current;
|
||||||
PLIST_ENTRY current_entry;
|
PLIST_ENTRY current_entry;
|
||||||
|
|
||||||
DPRINT("KeDispatcherObjectWakeOn(hdr %x)\n",hdr);
|
DPRINT("KeDispatcherObjectWakeOn(hdr %x)\n",hdr);
|
||||||
DPRINT("hdr->WaitListHead.Flink %x hdr->WaitListHead.Blink %x\n",
|
DPRINT("hdr->WaitListHead.Flink %x hdr->WaitListHead.Blink %x\n",
|
||||||
hdr->WaitListHead.Flink,hdr->WaitListHead.Blink);
|
hdr->WaitListHead.Flink,hdr->WaitListHead.Blink);
|
||||||
|
@ -120,7 +128,7 @@ BOOLEAN KeDispatcherObjectWake(DISPATCHER_HEADER* hdr)
|
||||||
*/
|
*/
|
||||||
{
|
{
|
||||||
BOOL Ret;
|
BOOL Ret;
|
||||||
|
|
||||||
DPRINT("Entering KeDispatcherObjectWake(hdr %x)\n",hdr);
|
DPRINT("Entering KeDispatcherObjectWake(hdr %x)\n",hdr);
|
||||||
// DPRINT("hdr->WaitListHead %x hdr->WaitListHead.Flink %x\n",
|
// DPRINT("hdr->WaitListHead %x hdr->WaitListHead.Flink %x\n",
|
||||||
// &hdr->WaitListHead,hdr->WaitListHead.Flink);
|
// &hdr->WaitListHead,hdr->WaitListHead.Flink);
|
||||||
|
@ -129,7 +137,7 @@ BOOLEAN KeDispatcherObjectWake(DISPATCHER_HEADER* hdr)
|
||||||
{
|
{
|
||||||
case NotificationEvent:
|
case NotificationEvent:
|
||||||
return(KeDispatcherObjectWakeAll(hdr));
|
return(KeDispatcherObjectWakeAll(hdr));
|
||||||
|
|
||||||
case SynchronizationEvent:
|
case SynchronizationEvent:
|
||||||
Ret = KeDispatcherObjectWakeOne(hdr);
|
Ret = KeDispatcherObjectWakeOne(hdr);
|
||||||
if (Ret)
|
if (Ret)
|
||||||
|
@ -137,7 +145,7 @@ BOOLEAN KeDispatcherObjectWake(DISPATCHER_HEADER* hdr)
|
||||||
hdr->SignalState = FALSE;
|
hdr->SignalState = FALSE;
|
||||||
}
|
}
|
||||||
return(Ret);
|
return(Ret);
|
||||||
|
|
||||||
case SemaphoreType:
|
case SemaphoreType:
|
||||||
if(hdr->SignalState>0)
|
if(hdr->SignalState>0)
|
||||||
{
|
{
|
||||||
|
@ -159,8 +167,8 @@ BOOLEAN KeDispatcherObjectWake(DISPATCHER_HEADER* hdr)
|
||||||
KeBugCheck(0);
|
KeBugCheck(0);
|
||||||
return(FALSE);
|
return(FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
NTSTATUS KeWaitForSingleObject(PVOID Object,
|
NTSTATUS KeWaitForSingleObject(PVOID Object,
|
||||||
KWAIT_REASON WaitReason,
|
KWAIT_REASON WaitReason,
|
||||||
KPROCESSOR_MODE WaitMode,
|
KPROCESSOR_MODE WaitMode,
|
||||||
|
@ -182,14 +190,14 @@ NTSTATUS KeWaitForSingleObject(PVOID Object,
|
||||||
{
|
{
|
||||||
DISPATCHER_HEADER* hdr = (DISPATCHER_HEADER *)Object;
|
DISPATCHER_HEADER* hdr = (DISPATCHER_HEADER *)Object;
|
||||||
KWAIT_BLOCK blk;
|
KWAIT_BLOCK blk;
|
||||||
|
|
||||||
DPRINT("Entering KeWaitForSingleObject(Object %x) "
|
DPRINT("Entering KeWaitForSingleObject(Object %x) "
|
||||||
"PsGetCurrentThread() %x\n",Object,PsGetCurrentThread());
|
"PsGetCurrentThread() %x\n",Object,PsGetCurrentThread());
|
||||||
|
|
||||||
KeAcquireDispatcherDatabaseLock(FALSE);
|
KeAcquireDispatcherDatabaseLock(FALSE);
|
||||||
|
|
||||||
DPRINT("hdr->SignalState %d\n", hdr->SignalState);
|
DPRINT("hdr->SignalState %d\n", hdr->SignalState);
|
||||||
|
|
||||||
if (hdr->SignalState > 0)
|
if (hdr->SignalState > 0)
|
||||||
{
|
{
|
||||||
switch (hdr->Type)
|
switch (hdr->Type)
|
||||||
|
@ -204,7 +212,7 @@ NTSTATUS KeWaitForSingleObject(PVOID Object,
|
||||||
case ID_PROCESS_OBJECT:
|
case ID_PROCESS_OBJECT:
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ID_THREAD_OBJECT:
|
case ID_THREAD_OBJECT:
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case NotificationEvent:
|
case NotificationEvent:
|
||||||
|
@ -224,10 +232,10 @@ NTSTATUS KeWaitForSingleObject(PVOID Object,
|
||||||
{
|
{
|
||||||
KeAddThreadTimeout(KeGetCurrentThread(),Timeout);
|
KeAddThreadTimeout(KeGetCurrentThread(),Timeout);
|
||||||
}
|
}
|
||||||
|
|
||||||
blk.Object=Object;
|
blk.Object=Object;
|
||||||
blk.Thread=KeGetCurrentThread();
|
blk.Thread=KeGetCurrentThread();
|
||||||
blk.WaitKey = WaitReason; // Assumed
|
blk.WaitKey = 0;
|
||||||
blk.WaitType = WaitAll;
|
blk.WaitType = WaitAll;
|
||||||
blk.NextWaitBlock = NULL;
|
blk.NextWaitBlock = NULL;
|
||||||
InsertTailList(&(hdr->WaitListHead),&(blk.WaitListEntry));
|
InsertTailList(&(hdr->WaitListHead),&(blk.WaitListEntry));
|
||||||
|
@ -255,91 +263,126 @@ NTSTATUS KeWaitForMultipleObjects(ULONG Count,
|
||||||
PLARGE_INTEGER Timeout,
|
PLARGE_INTEGER Timeout,
|
||||||
PKWAIT_BLOCK WaitBlockArray)
|
PKWAIT_BLOCK WaitBlockArray)
|
||||||
{
|
{
|
||||||
#if 0
|
DISPATCHER_HEADER* hdr;
|
||||||
DISPATCHER_HEADER* hdr;
|
PKWAIT_BLOCK blk;
|
||||||
PKWAIT_BLOCK blk;
|
ULONG CountSignaled;
|
||||||
ULONG Counter;
|
ULONG i;
|
||||||
|
|
||||||
DPRINT("Entering KeWaitForSingleObject(Object %x) "
|
DbgPrint("Entering KeWaitForMultipleObjects(Count %lu Object[] %p) "
|
||||||
"PsGetCurrentThread() %x\n",Object,PsGetCurrentThread());
|
"PsGetCurrentThread() %x\n",Count,Object,PsGetCurrentThread());
|
||||||
|
|
||||||
KeAcquireDispatcherDatabaseLock(FALSE);
|
CountSignaled = 0;
|
||||||
|
|
||||||
for (Counter = 0; Counter < Count; Counter++)
|
if (WaitBlockArray == NULL)
|
||||||
{
|
{
|
||||||
hdr = (DISPATCHER_HEADER *)Object[Counter];
|
DbgPrint("FIXME: Use internal wait blocks!\n");
|
||||||
|
return STATUS_UNSUCCESSFUL;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (Count > 64)
|
||||||
|
{
|
||||||
|
DbgPrint("Too many objects!\n");
|
||||||
|
return STATUS_UNSUCCESSFUL;
|
||||||
|
}
|
||||||
|
blk = WaitBlockArray;
|
||||||
|
}
|
||||||
|
|
||||||
DPRINT("hdr->SignalState %d\n", hdr->SignalState);
|
KeAcquireDispatcherDatabaseLock(FALSE);
|
||||||
|
|
||||||
|
for (i = 0; i < Count; i++)
|
||||||
|
{
|
||||||
|
hdr = (DISPATCHER_HEADER *)Object[i];
|
||||||
|
|
||||||
|
// DbgPrint("hdr->SignalState %d\n", hdr->SignalState);
|
||||||
|
|
||||||
if (hdr->SignalState > 0)
|
if (hdr->SignalState > 0)
|
||||||
{
|
{
|
||||||
switch (hdr->Type)
|
CountSignaled++;
|
||||||
{
|
|
||||||
case SynchronizationEvent:
|
switch (hdr->Type)
|
||||||
|
{
|
||||||
|
case SynchronizationEvent:
|
||||||
hdr->SignalState = FALSE;
|
hdr->SignalState = FALSE;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SemaphoreType:
|
case SemaphoreType:
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ID_PROCESS_OBJECT:
|
case ID_PROCESS_OBJECT:
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ID_THREAD_OBJECT:
|
case ID_THREAD_OBJECT:
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case NotificationEvent:
|
case NotificationEvent:
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
DbgPrint("(%s:%d) Dispatcher object %x has unknown type\n",
|
DbgPrint("(%s:%d) Dispatcher object %x has unknown type\n",
|
||||||
__FILE__,__LINE__,hdr);
|
__FILE__,__LINE__,hdr);
|
||||||
KeBugCheck(0);
|
KeBugCheck(0);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
if (WaitType == WaitAny)
|
||||||
KeReleaseDispatcherDatabaseLock(FALSE);
|
{
|
||||||
return(STATUS_SUCCESS);
|
KeReleaseDispatcherDatabaseLock(FALSE);
|
||||||
}
|
DbgPrint("One object is already signaled!\n");
|
||||||
}
|
return(STATUS_SUCCESS);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (Timeout != NULL)
|
if ((WaitType == WaitAll) && (CountSignaled == Count))
|
||||||
{
|
{
|
||||||
|
KeReleaseDispatcherDatabaseLock(FALSE);
|
||||||
|
DbgPrint("All objects are already signaled!\n");
|
||||||
|
return(STATUS_SUCCESS);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Timeout != NULL)
|
||||||
|
{
|
||||||
KeAddThreadTimeout(KeGetCurrentThread(),Timeout);
|
KeAddThreadTimeout(KeGetCurrentThread(),Timeout);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (Counter = 0; Counter < Count; Counter++)
|
for (i = 0; i < Count; i++)
|
||||||
{
|
{
|
||||||
hdr = (DISPATCHER_HEADER *)Object[Counter];
|
hdr = (DISPATCHER_HEADER *)Object[i];
|
||||||
|
|
||||||
blk = &WaitBlockArray[Counter];
|
DbgPrint("hdr->SignalState %d\n", hdr->SignalState);
|
||||||
|
|
||||||
blk->Object=Object[Counter];
|
blk->Object=Object[i];
|
||||||
blk->Thread=KeGetCurrentThread();
|
blk->Thread=KeGetCurrentThread();
|
||||||
blk->WaitKey = WaitReason; // Assumed
|
blk->WaitKey = i;
|
||||||
blk->WaitType = WaitType;
|
blk->WaitType = WaitType;
|
||||||
blk->NextWaitBlock = NULL;
|
if (i == Count - 1)
|
||||||
InsertTailList(&(hdr->WaitListHead),&(blk.WaitListEntry));
|
blk->NextWaitBlock = NULL;
|
||||||
|
else
|
||||||
|
blk->NextWaitBlock = (PVOID)((ULONG)blk+sizeof(KWAIT_BLOCK));
|
||||||
|
DbgPrint("blk %p blk->NextWaitBlock %p\n",
|
||||||
|
blk, blk->NextWaitBlock);
|
||||||
|
|
||||||
|
InsertTailList(&(hdr->WaitListHead),&(blk->WaitListEntry));
|
||||||
// DPRINT("hdr->WaitListHead.Flink %x hdr->WaitListHead.Blink %x\n",
|
// DPRINT("hdr->WaitListHead.Flink %x hdr->WaitListHead.Blink %x\n",
|
||||||
// hdr->WaitListHead.Flink,hdr->WaitListHead.Blink);
|
// hdr->WaitListHead.Flink,hdr->WaitListHead.Blink);
|
||||||
}
|
|
||||||
|
|
||||||
KeReleaseDispatcherDatabaseLock(FALSE);
|
blk = blk->NextWaitBlock;
|
||||||
|
}
|
||||||
|
|
||||||
DPRINT("Waiting at %s:%d with irql %d\n", __FILE__, __LINE__,
|
KeReleaseDispatcherDatabaseLock(FALSE);
|
||||||
KeGetCurrentIrql());
|
|
||||||
|
|
||||||
PsSuspendThread(PsGetCurrentThread());
|
DbgPrint("Waiting at %s:%d with irql %d\n", __FILE__, __LINE__,
|
||||||
|
KeGetCurrentIrql());
|
||||||
if (Timeout != NULL)
|
PsSuspendThread(PsGetCurrentThread());
|
||||||
{
|
|
||||||
|
if (Timeout != NULL)
|
||||||
|
{
|
||||||
KeCancelTimer(&KeGetCurrentThread()->Timer);
|
KeCancelTimer(&KeGetCurrentThread()->Timer);
|
||||||
}
|
}
|
||||||
DPRINT("Returning from KeWaitForMultipleObject()\n");
|
|
||||||
|
|
||||||
return(STATUS_SUCCESS);
|
DbgPrint("Returning from KeWaitForMultipleObjects()\n");
|
||||||
#else
|
|
||||||
UNIMPLEMENTED;
|
return STATUS_SUCCESS;
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
VOID KeInitializeDispatcher(VOID)
|
VOID KeInitializeDispatcher(VOID)
|
||||||
|
@ -347,6 +390,7 @@ VOID KeInitializeDispatcher(VOID)
|
||||||
KeInitializeSpinLock(&DispatcherDatabaseLock);
|
KeInitializeSpinLock(&DispatcherDatabaseLock);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
STDCALL
|
STDCALL
|
||||||
NtWaitForMultipleObjects (
|
NtWaitForMultipleObjects (
|
||||||
|
@ -357,9 +401,10 @@ NtWaitForMultipleObjects (
|
||||||
IN PLARGE_INTEGER Time
|
IN PLARGE_INTEGER Time
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
#if 0
|
KWAIT_BLOCK WaitBlockArray[64];
|
||||||
KWAIT_BLOCK WaitBlockArray[MAXIMUM_WAIT_OBJECTS];
|
PVOID ObjectPtrArray[64];
|
||||||
PVOID ObjectPtrArray[MAXIMUM_WAIT_OBJECTS];
|
// KWAIT_BLOCK WaitBlockArray[MAXIMUM_WAIT_OBJECTS];
|
||||||
|
// PVOID ObjectPtrArray[MAXIMUM_WAIT_OBJECTS];
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
ULONG i, j;
|
ULONG i, j;
|
||||||
|
|
||||||
|
@ -367,8 +412,10 @@ NtWaitForMultipleObjects (
|
||||||
DPRINT("NtWaitForMultipleObjects(Count %lu Object[] %x, Alertable %d, Time %x)\n",
|
DPRINT("NtWaitForMultipleObjects(Count %lu Object[] %x, Alertable %d, Time %x)\n",
|
||||||
Count,Object,Alertable,Time);
|
Count,Object,Alertable,Time);
|
||||||
|
|
||||||
if (Count > MAXIMUM_WAIT_OBJECTS)
|
if (Count > 64)
|
||||||
return ...; /* WAIT_FAIL */
|
// if (Count > MAXIMUM_WAIT_OBJECTS)
|
||||||
|
return STATUS_UNSUCCESSFUL;
|
||||||
|
// return WAIT_FAIL; /* this must be returned by WaitForMultipleObjects */
|
||||||
|
|
||||||
/* reference all objects */
|
/* reference all objects */
|
||||||
for (i = 0; i < Count; i++)
|
for (i = 0; i < Count; i++)
|
||||||
|
@ -394,7 +441,7 @@ NtWaitForMultipleObjects (
|
||||||
Status = KeWaitForMultipleObjects(Count,
|
Status = KeWaitForMultipleObjects(Count,
|
||||||
ObjectPtrArray,
|
ObjectPtrArray,
|
||||||
WaitType,
|
WaitType,
|
||||||
UserMode,
|
UserRequest,
|
||||||
UserMode,
|
UserMode,
|
||||||
Alertable,
|
Alertable,
|
||||||
Time,
|
Time,
|
||||||
|
@ -407,9 +454,6 @@ NtWaitForMultipleObjects (
|
||||||
}
|
}
|
||||||
|
|
||||||
return(Status);
|
return(Status);
|
||||||
#else
|
|
||||||
UNIMPLEMENTED;
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue