diff --git a/reactos/ntoskrnl/ke/wait.c b/reactos/ntoskrnl/ke/wait.c index baf06d8faad..59a89a8cfe3 100644 --- a/reactos/ntoskrnl/ke/wait.c +++ b/reactos/ntoskrnl/ke/wait.c @@ -73,7 +73,9 @@ static BOOLEAN KeDispatcherObjectWakeAll(DISPATCHER_HEADER* hdr) { PKWAIT_BLOCK current; PLIST_ENTRY current_entry; - + + DPRINT("KeDispatcherObjectWakeAll(hdr %x)\n",hdr); + if (IsListEmpty(&hdr->WaitListHead)) { return(FALSE); @@ -84,7 +86,13 @@ static BOOLEAN KeDispatcherObjectWakeAll(DISPATCHER_HEADER* hdr) current_entry = RemoveHeadList(&hdr->WaitListHead); current = CONTAINING_RECORD(current_entry,KWAIT_BLOCK, 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)); }; return(TRUE); @@ -94,7 +102,7 @@ static BOOLEAN KeDispatcherObjectWakeOne(DISPATCHER_HEADER* hdr) { PKWAIT_BLOCK current; PLIST_ENTRY current_entry; - + DPRINT("KeDispatcherObjectWakeOn(hdr %x)\n",hdr); DPRINT("hdr->WaitListHead.Flink %x hdr->WaitListHead.Blink %x\n", hdr->WaitListHead.Flink,hdr->WaitListHead.Blink); @@ -120,7 +128,7 @@ BOOLEAN KeDispatcherObjectWake(DISPATCHER_HEADER* hdr) */ { BOOL Ret; - + DPRINT("Entering KeDispatcherObjectWake(hdr %x)\n",hdr); // DPRINT("hdr->WaitListHead %x hdr->WaitListHead.Flink %x\n", // &hdr->WaitListHead,hdr->WaitListHead.Flink); @@ -129,7 +137,7 @@ BOOLEAN KeDispatcherObjectWake(DISPATCHER_HEADER* hdr) { case NotificationEvent: return(KeDispatcherObjectWakeAll(hdr)); - + case SynchronizationEvent: Ret = KeDispatcherObjectWakeOne(hdr); if (Ret) @@ -137,7 +145,7 @@ BOOLEAN KeDispatcherObjectWake(DISPATCHER_HEADER* hdr) hdr->SignalState = FALSE; } return(Ret); - + case SemaphoreType: if(hdr->SignalState>0) { @@ -159,8 +167,8 @@ BOOLEAN KeDispatcherObjectWake(DISPATCHER_HEADER* hdr) KeBugCheck(0); return(FALSE); } - - + + NTSTATUS KeWaitForSingleObject(PVOID Object, KWAIT_REASON WaitReason, KPROCESSOR_MODE WaitMode, @@ -182,14 +190,14 @@ NTSTATUS KeWaitForSingleObject(PVOID Object, { DISPATCHER_HEADER* hdr = (DISPATCHER_HEADER *)Object; KWAIT_BLOCK blk; - + DPRINT("Entering KeWaitForSingleObject(Object %x) " "PsGetCurrentThread() %x\n",Object,PsGetCurrentThread()); KeAcquireDispatcherDatabaseLock(FALSE); - + DPRINT("hdr->SignalState %d\n", hdr->SignalState); - + if (hdr->SignalState > 0) { switch (hdr->Type) @@ -204,7 +212,7 @@ NTSTATUS KeWaitForSingleObject(PVOID Object, case ID_PROCESS_OBJECT: break; - case ID_THREAD_OBJECT: + case ID_THREAD_OBJECT: break; case NotificationEvent: @@ -224,10 +232,10 @@ NTSTATUS KeWaitForSingleObject(PVOID Object, { KeAddThreadTimeout(KeGetCurrentThread(),Timeout); } - + blk.Object=Object; blk.Thread=KeGetCurrentThread(); - blk.WaitKey = WaitReason; // Assumed + blk.WaitKey = 0; blk.WaitType = WaitAll; blk.NextWaitBlock = NULL; InsertTailList(&(hdr->WaitListHead),&(blk.WaitListEntry)); @@ -255,91 +263,126 @@ NTSTATUS KeWaitForMultipleObjects(ULONG Count, PLARGE_INTEGER Timeout, PKWAIT_BLOCK WaitBlockArray) { -#if 0 - DISPATCHER_HEADER* hdr; - PKWAIT_BLOCK blk; - ULONG Counter; + DISPATCHER_HEADER* hdr; + PKWAIT_BLOCK blk; + ULONG CountSignaled; + ULONG i; - DPRINT("Entering KeWaitForSingleObject(Object %x) " - "PsGetCurrentThread() %x\n",Object,PsGetCurrentThread()); + DbgPrint("Entering KeWaitForMultipleObjects(Count %lu Object[] %p) " + "PsGetCurrentThread() %x\n",Count,Object,PsGetCurrentThread()); - KeAcquireDispatcherDatabaseLock(FALSE); + CountSignaled = 0; - for (Counter = 0; Counter < Count; Counter++) - { - hdr = (DISPATCHER_HEADER *)Object[Counter]; + if (WaitBlockArray == NULL) + { + 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) - { - switch (hdr->Type) - { - case SynchronizationEvent: + { + CountSignaled++; + + switch (hdr->Type) + { + case SynchronizationEvent: hdr->SignalState = FALSE; break; - case SemaphoreType: + case SemaphoreType: break; - case ID_PROCESS_OBJECT: + case ID_PROCESS_OBJECT: break; - case ID_THREAD_OBJECT: + case ID_THREAD_OBJECT: break; - case NotificationEvent: + case NotificationEvent: break; - default: + default: DbgPrint("(%s:%d) Dispatcher object %x has unknown type\n", __FILE__,__LINE__,hdr); KeBugCheck(0); + } - } - KeReleaseDispatcherDatabaseLock(FALSE); - return(STATUS_SUCCESS); - } - } + if (WaitType == WaitAny) + { + 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); - } + } - for (Counter = 0; Counter < Count; Counter++) - { - hdr = (DISPATCHER_HEADER *)Object[Counter]; + for (i = 0; i < Count; i++) + { + 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->WaitKey = WaitReason; // Assumed + blk->WaitKey = i; blk->WaitType = WaitType; - blk->NextWaitBlock = NULL; - InsertTailList(&(hdr->WaitListHead),&(blk.WaitListEntry)); + if (i == Count - 1) + 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", // hdr->WaitListHead.Flink,hdr->WaitListHead.Blink); - } - KeReleaseDispatcherDatabaseLock(FALSE); + blk = blk->NextWaitBlock; + } - DPRINT("Waiting at %s:%d with irql %d\n", __FILE__, __LINE__, - KeGetCurrentIrql()); + KeReleaseDispatcherDatabaseLock(FALSE); - PsSuspendThread(PsGetCurrentThread()); - - if (Timeout != NULL) - { + DbgPrint("Waiting at %s:%d with irql %d\n", __FILE__, __LINE__, + KeGetCurrentIrql()); + PsSuspendThread(PsGetCurrentThread()); + + if (Timeout != NULL) + { KeCancelTimer(&KeGetCurrentThread()->Timer); - } - DPRINT("Returning from KeWaitForMultipleObject()\n"); + } - return(STATUS_SUCCESS); -#else - UNIMPLEMENTED; -#endif + DbgPrint("Returning from KeWaitForMultipleObjects()\n"); + + return STATUS_SUCCESS; } VOID KeInitializeDispatcher(VOID) @@ -347,6 +390,7 @@ VOID KeInitializeDispatcher(VOID) KeInitializeSpinLock(&DispatcherDatabaseLock); } + NTSTATUS STDCALL NtWaitForMultipleObjects ( @@ -357,9 +401,10 @@ NtWaitForMultipleObjects ( IN PLARGE_INTEGER Time ) { -#if 0 - KWAIT_BLOCK WaitBlockArray[MAXIMUM_WAIT_OBJECTS]; - PVOID ObjectPtrArray[MAXIMUM_WAIT_OBJECTS]; + KWAIT_BLOCK WaitBlockArray[64]; + PVOID ObjectPtrArray[64]; +// KWAIT_BLOCK WaitBlockArray[MAXIMUM_WAIT_OBJECTS]; +// PVOID ObjectPtrArray[MAXIMUM_WAIT_OBJECTS]; NTSTATUS Status; ULONG i, j; @@ -367,8 +412,10 @@ NtWaitForMultipleObjects ( DPRINT("NtWaitForMultipleObjects(Count %lu Object[] %x, Alertable %d, Time %x)\n", Count,Object,Alertable,Time); - if (Count > MAXIMUM_WAIT_OBJECTS) - return ...; /* WAIT_FAIL */ + if (Count > 64) +// if (Count > MAXIMUM_WAIT_OBJECTS) + return STATUS_UNSUCCESSFUL; +// return WAIT_FAIL; /* this must be returned by WaitForMultipleObjects */ /* reference all objects */ for (i = 0; i < Count; i++) @@ -394,7 +441,7 @@ NtWaitForMultipleObjects ( Status = KeWaitForMultipleObjects(Count, ObjectPtrArray, WaitType, - UserMode, + UserRequest, UserMode, Alertable, Time, @@ -407,9 +454,6 @@ NtWaitForMultipleObjects ( } return(Status); -#else - UNIMPLEMENTED; -#endif }