Author: ion Date: Sat Jul 8 21:07:24 2006 New Revision: 22926
URL: http://svn.reactos.org/svn/reactos?rev=22926&view=rev Log: - Massively improve File I/O by using deferred I/O completion for MJ_(MAILSLOT/FILE/NAMEDPIPE)CREATE and manually completing the IRP.
Modified: trunk/reactos/ntoskrnl/io/iomgr/file.c
Modified: trunk/reactos/ntoskrnl/io/iomgr/file.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/io/iomgr/file.c?re... ============================================================================== --- trunk/reactos/ntoskrnl/io/iomgr/file.c (original) +++ trunk/reactos/ntoskrnl/io/iomgr/file.c Sat Jul 8 21:07:24 2006 @@ -41,6 +41,7 @@ BOOLEAN DirectOpen = FALSE; OBJECT_ATTRIBUTES ObjectAttributes; BOOLEAN OpenCancelled; + KIRQL OldIrql; DPRINT("IopParseDevice:\n" "DeviceObject : %p\n" "RelatedFileObject : %p\n" @@ -232,8 +233,8 @@ Irp->Tail.Overlay.OriginalFileObject = FileObject; Irp->RequestorMode = AccessMode; Irp->Flags = IRP_CREATE_OPERATION | - IRP_SYNCHRONOUS_API;// | - //IRP_DEFER_IO_COMPLETION; + IRP_SYNCHRONOUS_API | + IRP_DEFER_IO_COMPLETION; Irp->Tail.Overlay.Thread = PsGetCurrentThread(); Irp->UserEvent = &FileObject->Event; Irp->UserIosb = &IoStatusBlock; @@ -341,26 +342,41 @@ KernelMode, FALSE, NULL); + + /* Get the new status */ Status = IoStatusBlock.Status; } -#if 0 else { - KIRQL OldIrql; - PKNORMAL_ROUTINE NormalRoutine; - PVOID NormalContext; - /* We'll have to complete it ourselves */ ASSERT(!Irp->PendingReturned); + + /* Completion happens at APC_LEVEL */ KeRaiseIrql(APC_LEVEL, &OldIrql); - IopCompleteRequest(&Irp->Tail.Apc, - &NormalRoutine, - &NormalContext, - (PVOID*)&FileObject, - &NormalContext); + + /* Get the new I/O Status block ourselves */ + IoStatusBlock = Irp->IoStatus; + Status = IoStatusBlock.Status; + + /* Manually signal the even, we can't have any waiters */ + FileObject->Event.Header.SignalState = 1; + + /* Now that we've signaled the events, de-associate the IRP */ + RemoveEntryList(&Irp->ThreadListEntry); + InitializeListHead(&Irp->ThreadListEntry); + + /* Check if the IRP had an input buffer */ + if ((Irp->Flags & IRP_BUFFERED_IO) && + (Irp->Flags & IRP_DEALLOCATE_BUFFER)) + { + /* Free it. A driver might've tacked one on */ + ExFreePool(Irp->AssociatedIrp.SystemBuffer); + } + + /* Free the IRP and bring the IRQL back down */ + IoFreeIrp(Irp); KeLowerIrql(OldIrql); } -#endif
/* Copy the I/O Status */ OpenPacket->Information = IoStatusBlock.Information;