- 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
NTAPI
IopCreateEvent(IN PUNICODE_STRING EventName,
IN PHANDLE EventHandle,
IN EVENT_TYPE Type)
{
OBJECT_ATTRIBUTES ObjectAttributes;
PKEVENT Event;
HANDLE Handle;
NTSTATUS Status;
PAGED_CODE();
/* Initialize the object attributes */
InitializeObjectAttributes(&ObjectAttributes,
EventName,
OBJ_OPENIF,
NULL,
NULL);
/* Create the event */
Status = ZwCreateEvent(&Handle,
EVENT_ALL_ACCESS,
&ObjectAttributes,
Type,
TRUE);
if (!NT_SUCCESS(Status)) return NULL;
/* Get a handle to it */
ObReferenceObjectByHandle(Handle,
0,
ExEventObjectType,
KernelMode,
(PVOID*)&Event,
NULL);
/* Dereference the extra count, and return the handle */
ObDereferenceObject(Event);
*EventHandle = Handle;
return Event;
}
/* PUBLIC FUNCTIONS **********************************************************/
/* /*
* @implemented * @implemented
*/ */
PKEVENT STDCALL PKEVENT
IoCreateNotificationEvent(PUNICODE_STRING EventName, NTAPI
PHANDLE EventHandle) IoCreateNotificationEvent(IN PUNICODE_STRING EventName,
IN PHANDLE EventHandle)
{ {
OBJECT_ATTRIBUTES ObjectAttributes; /* Call the internal API */
PKEVENT Event; return IopCreateEvent(EventName, EventHandle, NotificationEvent);
HANDLE Handle;
NTSTATUS Status;
InitializeObjectAttributes(&ObjectAttributes,
EventName,
OBJ_OPENIF,
NULL,
NULL);
Status = ZwCreateEvent(&Handle,
EVENT_ALL_ACCESS,
&ObjectAttributes,
NotificationEvent,
TRUE);
if (!NT_SUCCESS(Status))
{
return NULL;
}
ObReferenceObjectByHandle(Handle,
0,
ExEventObjectType,
KernelMode,
(PVOID*)&Event,
NULL);
ObDereferenceObject(Event);
*EventHandle = Handle;
return Event;
} }
/* /*
* @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
IopWorkItemCallback(IN PVOID Parameter)
{ {
WORK_QUEUE_ITEM Item; PIO_WORKITEM IoWorkItem = (PIO_WORKITEM)Parameter;
PDEVICE_OBJECT DeviceObject; PDEVICE_OBJECT DeviceObject = IoWorkItem->DeviceObject;
PIO_WORKITEM_ROUTINE WorkerRoutine; PAGED_CODE();
PVOID Context;
} IO_WORKITEM;
/* FUNCTIONS ****************************************************************/ /* Call the work routine */
IoWorkItem->WorkerRoutine(DeviceObject, IoWorkItem->Context);
VOID STATIC STDCALL /* Dereferenece the device object */
IoWorkItemCallback(PVOID Parameter) ObDereferenceObject(DeviceObject);
{
PIO_WORKITEM IoWorkItem = (PIO_WORKITEM)Parameter;
PDEVICE_OBJECT DeviceObject = IoWorkItem->DeviceObject;
IoWorkItem->WorkerRoutine(IoWorkItem->DeviceObject, IoWorkItem->Context);
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);
IoWorkItem->WorkerRoutine = WorkerRoutine;
IoWorkItem->Context = Context; /* Reference the device object */
ObReferenceObjectByPointer(IoWorkItem->DeviceObject, ObReferenceObject(IoWorkItem->DeviceObject);
FILE_ALL_ACCESS,
NULL, /* Setup the work item */
KernelMode); IoWorkItem->WorkerRoutine = WorkerRoutine;
ExQueueWorkItem(&IoWorkItem->Item, QueueType); IoWorkItem->Context = Context;
/* Queue the work item */
ExQueueWorkItem(&IoWorkItem->Item, QueueType);
} }
/* /*
* @implemented * @implemented
*/ */
VOID STDCALL VOID
IoFreeWorkItem(PIO_WORKITEM IoWorkItem) NTAPI
IoFreeWorkItem(IN PIO_WORKITEM IoWorkItem)
{ {
ExFreePool(IoWorkItem); /* Free the work item */
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 */