- Refactor Io*Event APIs to call an internal worker function instead of duplicating the same code twice.

- Optimize Io*Work APIs and initialize the event on allocation, not on queue!!

svn path=/trunk/; revision=22719
This commit is contained in:
Alex Ionescu 2006-06-30 16:56:18 +00:00
parent 2e185ea41a
commit ed3df3667f
3 changed files with 129 additions and 139 deletions

View file

@ -197,6 +197,17 @@ typedef struct _IO_COMPLETION_PACKET
IO_STATUS_BLOCK IoStatus; IO_STATUS_BLOCK IoStatus;
} IO_COMPLETION_PACKET, *PIO_COMPLETION_PACKET; } IO_COMPLETION_PACKET, *PIO_COMPLETION_PACKET;
//
// I/O Wrapper around the Executive Work Item
//
typedef struct _IO_WORKITEM
{
WORK_QUEUE_ITEM Item;
PDEVICE_OBJECT DeviceObject;
PIO_WORKITEM_ROUTINE WorkerRoutine;
PVOID Context;
} IO_WORKITEM, *PIO_WORKITEM;
// //
// Dummy File Object used inside the Open Packet so that OB knows how to // Dummy File Object used inside the Open Packet so that OB knows how to
// deal with the Object Pointer even though it's not a real file. // deal with the Object Pointer even though it's not a real file.

View file

@ -1,11 +1,10 @@
/* $Id$ /*
* * PROJECT: ReactOS Kernel
* COPYRIGHT: See COPYING in the top level directory * LICENSE: GPL - See COPYING in the top level directory
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/io/event.c * FILE: ntoskrnl/io/event.c
* PURPOSE: Implements named events * PURPOSE: I/O Wrappers for the Executive Event Functions
* * PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org)
* PROGRAMMERS: David Welch (welch@mcmail.com) * Eric Kohl
*/ */
/* INCLUDES *****************************************************************/ /* INCLUDES *****************************************************************/
@ -13,92 +12,73 @@
#include <ntoskrnl.h> #include <ntoskrnl.h>
#include <internal/debug.h> #include <internal/debug.h>
/* FUNCTIONS *****************************************************************/ /* PRIVATE FUNCTIONS *********************************************************/
/* PKEVENT
* @implemented NTAPI
*/ IopCreateEvent(IN PUNICODE_STRING EventName,
PKEVENT STDCALL IN PHANDLE EventHandle,
IoCreateNotificationEvent(PUNICODE_STRING EventName, IN EVENT_TYPE Type)
PHANDLE EventHandle)
{ {
OBJECT_ATTRIBUTES ObjectAttributes; OBJECT_ATTRIBUTES ObjectAttributes;
PKEVENT Event; PKEVENT Event;
HANDLE Handle; HANDLE Handle;
NTSTATUS Status; NTSTATUS Status;
PAGED_CODE();
/* Initialize the object attributes */
InitializeObjectAttributes(&ObjectAttributes, InitializeObjectAttributes(&ObjectAttributes,
EventName, EventName,
OBJ_OPENIF, OBJ_OPENIF,
NULL, NULL,
NULL); NULL);
/* Create the event */
Status = ZwCreateEvent(&Handle, Status = ZwCreateEvent(&Handle,
EVENT_ALL_ACCESS, EVENT_ALL_ACCESS,
&ObjectAttributes, &ObjectAttributes,
NotificationEvent, Type,
TRUE); TRUE);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status)) return NULL;
{
return NULL;
}
/* Get a handle to it */
ObReferenceObjectByHandle(Handle, ObReferenceObjectByHandle(Handle,
0, 0,
ExEventObjectType, ExEventObjectType,
KernelMode, KernelMode,
(PVOID*)&Event, (PVOID*)&Event,
NULL); NULL);
/* Dereference the extra count, and return the handle */
ObDereferenceObject(Event); ObDereferenceObject(Event);
*EventHandle = Handle; *EventHandle = Handle;
return Event; return Event;
} }
/* PUBLIC FUNCTIONS **********************************************************/
/*
* @implemented
*/
PKEVENT
NTAPI
IoCreateNotificationEvent(IN PUNICODE_STRING EventName,
IN PHANDLE EventHandle)
{
/* Call the internal API */
return IopCreateEvent(EventName, EventHandle, NotificationEvent);
}
/* /*
* @implemented * @implemented
*/ */
PKEVENT STDCALL PKEVENT
IoCreateSynchronizationEvent(PUNICODE_STRING EventName, NTAPI
PHANDLE EventHandle) IoCreateSynchronizationEvent(IN PUNICODE_STRING EventName,
IN PHANDLE EventHandle)
{ {
OBJECT_ATTRIBUTES ObjectAttributes; /* Call the internal API */
KPROCESSOR_MODE PreviousMode; return IopCreateEvent(EventName, EventHandle, SynchronizationEvent);
PKEVENT Event;
HANDLE Handle;
NTSTATUS Status;
PreviousMode = ExGetPreviousMode();
InitializeObjectAttributes(&ObjectAttributes,
EventName,
OBJ_OPENIF,
NULL,
NULL);
Status = ZwCreateEvent(&Handle,
EVENT_ALL_ACCESS,
&ObjectAttributes,
SynchronizationEvent,
TRUE);
if (!NT_SUCCESS(Status))
{
return NULL;
}
ObReferenceObjectByHandle(Handle,
0,
ExEventObjectType,
KernelMode,
(PVOID*)&Event,
NULL);
ObDereferenceObject(Event);
*EventHandle = Handle;
return Event;
} }
/* EOF */ /* EOF */

View file

@ -1,11 +1,9 @@
/* $Id$ /*
* * PROJECT: ReactOS Kernel
* COPYRIGHT: See COPYING in the top level directory * LICENSE: GPL - See COPYING in the top level directory
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/io/iowork.c * FILE: ntoskrnl/io/iowork.c
* PURPOSE: Manage IO system work queues * PURPOSE: I/O Wrappers for the Executive Work Item Functions
* * PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org)
* PROGRAMMERS: David Welch (welch@mcmail.com)
* Robert Dickenson (odin@pnc.com.au) * Robert Dickenson (odin@pnc.com.au)
*/ */
@ -15,80 +13,81 @@
#define NDEBUG #define NDEBUG
#include <internal/debug.h> #include <internal/debug.h>
/* TYPES ********************************************************************/ /* PRIVATE FUNCTIONS *********************************************************/
typedef struct _IO_WORKITEM VOID
{ NTAPI
WORK_QUEUE_ITEM Item; IopWorkItemCallback(IN PVOID Parameter)
PDEVICE_OBJECT DeviceObject;
PIO_WORKITEM_ROUTINE WorkerRoutine;
PVOID Context;
} IO_WORKITEM;
/* FUNCTIONS ****************************************************************/
VOID STATIC STDCALL
IoWorkItemCallback(PVOID Parameter)
{ {
PIO_WORKITEM IoWorkItem = (PIO_WORKITEM)Parameter; PIO_WORKITEM IoWorkItem = (PIO_WORKITEM)Parameter;
PDEVICE_OBJECT DeviceObject = IoWorkItem->DeviceObject; PDEVICE_OBJECT DeviceObject = IoWorkItem->DeviceObject;
IoWorkItem->WorkerRoutine(IoWorkItem->DeviceObject, IoWorkItem->Context); PAGED_CODE();
/* Call the work routine */
IoWorkItem->WorkerRoutine(DeviceObject, IoWorkItem->Context);
/* Dereferenece the device object */
ObDereferenceObject(DeviceObject); ObDereferenceObject(DeviceObject);
} }
/* PUBLIC FUNCTIONS **********************************************************/
/* /*
* @implemented * @implemented
*/ */
VOID STDCALL VOID
NTAPI
IoQueueWorkItem(IN PIO_WORKITEM IoWorkItem, IoQueueWorkItem(IN PIO_WORKITEM IoWorkItem,
IN PIO_WORKITEM_ROUTINE WorkerRoutine, IN PIO_WORKITEM_ROUTINE WorkerRoutine,
IN WORK_QUEUE_TYPE QueueType, IN WORK_QUEUE_TYPE QueueType,
IN PVOID Context) IN PVOID Context)
/*
* FUNCTION: Inserts a work item in a queue for one of the system worker
* threads to process
* ARGUMENTS:
* IoWorkItem = Item to insert
* QueueType = Queue to insert it in
*/
{ {
ExInitializeWorkItem(&IoWorkItem->Item, IoWorkItemCallback, /* Make sure we're called at DISPATCH or lower */
(PVOID)IoWorkItem); ASSERT_IRQL_LESS_OR_EQUAL(DISPATCH_LEVEL);
/* Reference the device object */
ObReferenceObject(IoWorkItem->DeviceObject);
/* Setup the work item */
IoWorkItem->WorkerRoutine = WorkerRoutine; IoWorkItem->WorkerRoutine = WorkerRoutine;
IoWorkItem->Context = Context; IoWorkItem->Context = Context;
ObReferenceObjectByPointer(IoWorkItem->DeviceObject,
FILE_ALL_ACCESS, /* Queue the work item */
NULL,
KernelMode);
ExQueueWorkItem(&IoWorkItem->Item, QueueType); ExQueueWorkItem(&IoWorkItem->Item, QueueType);
} }
/* /*
* @implemented * @implemented
*/ */
VOID STDCALL VOID
IoFreeWorkItem(PIO_WORKITEM IoWorkItem) NTAPI
IoFreeWorkItem(IN PIO_WORKITEM IoWorkItem)
{ {
/* Free the work item */
ExFreePool(IoWorkItem); ExFreePool(IoWorkItem);
} }
/* /*
* @implemented * @implemented
*/ */
PIO_WORKITEM STDCALL PIO_WORKITEM
IoAllocateWorkItem(PDEVICE_OBJECT DeviceObject) NTAPI
IoAllocateWorkItem(IN PDEVICE_OBJECT DeviceObject)
{ {
PIO_WORKITEM IoWorkItem = NULL; PIO_WORKITEM IoWorkItem;
IoWorkItem = /* Allocate the work item */
ExAllocatePoolWithTag(NonPagedPool, sizeof(IO_WORKITEM), TAG_IOWI); IoWorkItem = ExAllocatePoolWithTag(NonPagedPool,
if (IoWorkItem == NULL) sizeof(IO_WORKITEM),
{ TAG_IOWI);
return(NULL); if (!IoWorkItem) return NULL;
}
RtlZeroMemory(IoWorkItem, sizeof(IO_WORKITEM)); /* Initialize it */
IoWorkItem->DeviceObject = DeviceObject; IoWorkItem->DeviceObject = DeviceObject;
return(IoWorkItem); ExInitializeWorkItem(&IoWorkItem->Item, IopWorkItemCallback, IoWorkItem);
/* Return it */
return IoWorkItem;
} }
/* EOF */ /* EOF */