- 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_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
// deal with the Object Pointer even though it's not a real file.

View file

@ -1,11 +1,10 @@
/* $Id$
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
/*
* PROJECT: ReactOS Kernel
* LICENSE: GPL - See COPYING in the top level directory
* FILE: ntoskrnl/io/event.c
* PURPOSE: Implements named events
*
* PROGRAMMERS: David Welch (welch@mcmail.com)
* PURPOSE: I/O Wrappers for the Executive Event Functions
* PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org)
* Eric Kohl
*/
/* INCLUDES *****************************************************************/
@ -13,92 +12,73 @@
#include <ntoskrnl.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
*/
PKEVENT STDCALL
IoCreateNotificationEvent(PUNICODE_STRING EventName,
PHANDLE EventHandle)
PKEVENT
NTAPI
IoCreateNotificationEvent(IN PUNICODE_STRING EventName,
IN PHANDLE EventHandle)
{
OBJECT_ATTRIBUTES ObjectAttributes;
PKEVENT Event;
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;
/* Call the internal API */
return IopCreateEvent(EventName, EventHandle, NotificationEvent);
}
/*
* @implemented
*/
PKEVENT STDCALL
IoCreateSynchronizationEvent(PUNICODE_STRING EventName,
PHANDLE EventHandle)
PKEVENT
NTAPI
IoCreateSynchronizationEvent(IN PUNICODE_STRING EventName,
IN PHANDLE EventHandle)
{
OBJECT_ATTRIBUTES ObjectAttributes;
KPROCESSOR_MODE PreviousMode;
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;
/* Call the internal API */
return IopCreateEvent(EventName, EventHandle, SynchronizationEvent);
}
/* EOF */

View file

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