mirror of
https://github.com/reactos/reactos.git
synced 2025-01-03 21:09:19 +00:00
- 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:
parent
2e185ea41a
commit
ed3df3667f
3 changed files with 129 additions and 139 deletions
|
@ -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.
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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 */
|
||||
|
|
Loading…
Reference in a new issue