singrdk/base/Kernel/Singularity/Eventing/EventQuery.cs

430 lines
13 KiB
C#
Raw Permalink Normal View History

2008-11-17 18:29:00 -05:00
////////////////////////////////////////////////////////////////////////////////
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// File: EventQuery.cs
//
//
//
using System;
using System.Threading;
using System.Runtime.CompilerServices;
using Microsoft.Singularity;
using Microsoft.Singularity.V1.Services;
using Microsoft.Singularity.Eventing;
using System.Collections;
namespace Microsoft.Singularity.Eventing
{
// Delegates for the session and entry queries
public class EnumerationContext
{
public EnumerationContext(){}
}
[CLSCompliant(false)]
public delegate bool QuerySourceDelegate(UIntPtr sourceHandle,
UIntPtr storageHandle,
UIntPtr eventType,
UInt16 count,
string bufferName,
EventDescriptor Descriptor,
ref EnumerationContext context);
[CLSCompliant(false)]
public delegate bool ActiveSourceEntryDelegate(UIntPtr sourceHandle,
int index,
EventDescriptor descriptor,
QueryBuffer entryBuffer,
ref EnumerationContext context);
[CLSCompliant(false)]
public delegate bool QueryEntryDelegate(EventDescriptor currentEntry,
QueryBuffer buffer,
ref EnumerationContext context);
[CLSCompliant(false)]
public delegate bool QueryFieldDelegate(FieldDescriptor fieldDescriptor,
object value,
ref EnumerationContext context);
[CLSCompliant(false)]
public class FieldDescriptor
{
public UInt16 Offset;
public UInt16 Type;
public string Name;
public FieldDescriptor(UInt16 offset, UInt16 type, string name)
{
Offset = offset;
Type = type;
Name = name;
}
public object GetObject(QueryBuffer buffer)
{
unsafe {
switch (Type) {
case DataType.__int8:
case DataType.__uint8:
fixed(byte * ptrInt = &(buffer.GetBuffer()[buffer.UserOffset + Offset])) {
return *(byte *)ptrInt;
}
case DataType.__int16:
case DataType.__uint16:
fixed(byte * ptrInt = &(buffer.GetBuffer()[buffer.UserOffset + Offset])) {
return *(ushort *)ptrInt;
}
case DataType.__int32:
case DataType.__uint32:
fixed(byte * ptrInt = &(buffer.GetBuffer()[buffer.UserOffset + Offset])) {
return *(Int32 *)ptrInt;
}
case DataType.__UIntPtr:
fixed(byte * ptrInt = &(buffer.GetBuffer()[buffer.UserOffset + Offset])) {
return *(UIntPtr *)ptrInt;
}
case DataType.__IntPtr:
fixed(byte * ptrInt = &(buffer.GetBuffer()[buffer.UserOffset + Offset])) {
return *(IntPtr *)ptrInt;
}
default:
DebugStub.WriteLine("Unknown field type");
break;
}
}
return null;
}
public string GetTypeName()
{
switch (Type) {
case DataType.__int8: return "int8";
case DataType.__int16: return "int16";
case DataType.__int32: return "int32";
case DataType.__int64: return "int64";
case DataType.__uint8: return "uint8";
case DataType.__uint16: return "uint16";
case DataType.__uint32: return "uint32";
case DataType.__uint64: return "uint64";
case DataType.__IntPtr: return "IntPtr";
case DataType.__UIntPtr: return "UIntPtr";
case DataType.__arrayType:return "ArrayType";
default:
return "unknown";
}
}
}
[CLSCompliant(false)]
[AccessedByRuntime("output to header : defined in EventController.cpp")]
public class EventDescriptor
{
internal UIntPtr EventHandle;
internal string EventName;
public ArrayList Fields;
internal Hashtable LookupTable;
internal Controller ControllerObject;
public EventDescriptor(Controller controller, UIntPtr eventHandle)
{
EventHandle = eventHandle;
ControllerObject = controller;
}
public string GetName()
{
return EventName;
}
public int GetFieldsCount()
{
return Fields.Count;
}
public bool Initialize()
{
UIntPtr fieldHandle = 0;
UInt16 offset = 0;
UInt16 type = 0;
string fieldName = "";
Fields = new ArrayList();
LookupTable = new Hashtable();
do {
fieldHandle = ControllerObject.WalkEventDescriptor(EventHandle,
fieldHandle,
ref offset,
ref type,
ref fieldName);
if (fieldHandle != 0) {
if (type == 0) {
// This entry describes the event metadata. Fetch the name here
EventName = fieldName;
} else {
// This is an actual field. Addit to our table
FieldDescriptor fieldDescriptor = new FieldDescriptor(offset,
type,
fieldName);
if (fieldDescriptor == null) {
return false;
}
Fields.Add(fieldDescriptor);
LookupTable[fieldName] = fieldDescriptor;
}
}
} while (fieldHandle != 0);
Fields.Reverse();
return true;
}
public void EnumerateFields(QueryFieldDelegate fieldDelegate,
QueryBuffer buffer,
ref EnumerationContext context)
{
for (int i = 0; i < Fields.Count; i++) {
FieldDescriptor fieldDescriptor = Fields[i] as FieldDescriptor;
if (buffer != null) {
if (!fieldDelegate(fieldDescriptor, fieldDescriptor.GetObject(buffer), ref context)) {
break;
}
} else {
if (!fieldDelegate(fieldDescriptor, null, ref context)) {
break;
}
}
}
}
public object GetProperty(QueryBuffer buffer, string propertyName)
{
FieldDescriptor fieldDescriptor = LookupTable[propertyName] as FieldDescriptor;
if (fieldDescriptor == null) {
return null;
}
return fieldDescriptor.GetObject(buffer);
}
}
[CLSCompliant(false)]
public class QueryBuffer
{
private byte [] Buffer = null;
private UInt16 BufferSize;
// offset of user-specific data in the buffer
public UInt32 UserOffset;
public UIntPtr Type;
public UIntPtr EntryHandle;
public QueryBuffer(UInt16 size)
{
BufferSize = size;
Buffer = new byte[BufferSize];
}
[NoHeapAllocation]
public byte[] GetBuffer()
{
return Buffer;
}
[NoHeapAllocation]
public UInt16 GetBufferSize()
{
return BufferSize;
}
}
[CLSCompliant(false)]
[AccessedByRuntime("output to header : defined in EventController.cpp")]
public class QuerySession
{
// Implementation details
private QueryBuffer EntryBuffer;
private EventingStorage QueryStorage = null;
private UIntPtr QueryHandle = 0;
public bool Initialize(EventingStorage storage,
bool forward)
{
if (EntryBuffer == null) {
EntryBuffer = new QueryBuffer(256);
if ((EntryBuffer == null) || (EntryBuffer.GetBuffer() == null)) {
return false;
}
}
// Cleanup for the previous states.
if (QueryHandle != 0) {
QueryStorage.DeleteQueryView(QueryHandle);
QueryHandle = 0;
QueryStorage = null;
}
// Initialize the new query states
QueryStorage = storage;
if (QueryStorage == null) {
return false;
}
QueryHandle = QueryStorage.CreateQueryView(forward);
if (QueryHandle == 0) {
QueryStorage = null;
return false;
}
return true;
}
public void EnumerateEntries(QueryEntryDelegate entryDelegate,
ref EnumerationContext context)
{
if ((QueryHandle != 0) && (entryDelegate!= null)) {
UIntPtr entryHandle;
do {
entryHandle = QueryStorage.GetNextEntry(QueryHandle ,
ref EntryBuffer);
if (entryHandle != 0) {
if (!entryDelegate(GetEventDescriptor(QueryStorage.GetController(),
EntryBuffer.Type),
EntryBuffer,
ref context)) {
break;
}
}
} while (entryHandle != 0);
}
}
// General methods for event schema registration and lookup
internal static Hashtable DescriptorTable = null;
internal static Mutex Lock = null;
internal static EventDescriptor EventMetadata = null;
public static bool InitializeQuerySystem()
{
if (DescriptorTable != null) {
return false;
}
DescriptorTable = new Hashtable();
Lock = new Mutex();
if ((Lock == null) || (DescriptorTable == null) ) {
return false;
}
return true;
}
public static void FlushCaches()
{
Lock.AcquireMutex();
DescriptorTable.Clear();
Lock.ReleaseMutex();
}
public static EventDescriptor GetEventDescriptor(Controller controller, UIntPtr typeHandle)
{
Lock.AcquireMutex();
EventDescriptor descriptor = DescriptorTable[typeHandle] as EventDescriptor;
if (descriptor != null) {
Lock.ReleaseMutex();
return descriptor;
}
descriptor = new EventDescriptor(controller, typeHandle);
if ((descriptor != null) && descriptor.Initialize()) {
DescriptorTable[typeHandle] = descriptor;
if (typeHandle == 0) {
EventMetadata = descriptor;
}
} else {
descriptor = null;
}
Lock.ReleaseMutex();
return descriptor;
}
}
}