示例#1
0
        public IInstanceEntry CreateNewInstance()
        {
            var newInstance = new InstanceEntry();

            base.Create(newInstance);
            return(newInstance);
        }
 public ObjectInfo(
     bool weighted,
     GeometryEntry g,
     Matrix bindMatrix,
     SkinEntry skin,
     SceneEntry scene,
     InstanceEntry inst,
     ResourceNode parent,
     NodeEntry node)
 {
     _weighted   = weighted;
     _g          = g;
     _bindMatrix = bindMatrix;
     _skin       = skin;
     _scene      = scene;
     _parent     = parent;
     _node       = node;
     _inst       = inst;
 }
示例#3
0
        public Snapshot GetSnapshot()
        {
            var dropletEntries = new List <DropletEntry>();

            lock (droplets)
            {
                if (false == this.IsEmpty)
                {
                    foreach (var droplet in droplets)
                    {
                        var instanceEntries = new List <InstanceEntry>();

                        foreach (var instance in droplet.Value)
                        {
                            var instanceEntry = new InstanceEntry
                            {
                                InstanceID = instance.Key,
                                Instance   = instance.Value
                            };
                            instanceEntries.Add(instanceEntry);
                        }

                        var d = new DropletEntry
                        {
                            DropletID = droplet.Key,
                            Instances = instanceEntries.ToArray()
                        };

                        dropletEntries.Add(d);
                    }
                }
            }

            return(new Snapshot()
            {
                Entries = dropletEntries.ToArrayOrNull()
            });
        }
        private unsafe void ClearCounterValues(InstanceEntry* instancePointer) {
            //Clear counter instance values
            CounterEntry* currentCounterPointer = null;
            
            if (instancePointer->FirstCounterOffset != 0)
                currentCounterPointer = (CounterEntry*)(ResolveOffset(instancePointer->FirstCounterOffset, CounterEntrySize));

            while(currentCounterPointer != null) {
                SetValue(currentCounterPointer, 0);
                    
                if (currentCounterPointer->NextCounterOffset != 0)
                    currentCounterPointer = (CounterEntry*)(ResolveOffset(currentCounterPointer->NextCounterOffset, CounterEntrySize));
                else
                    currentCounterPointer = null;
            }

        }
        private unsafe bool FindCounter(int counterNameHashCode, string counterName, InstanceEntry* instancePointer, CounterEntry** returnCounterPointerReference) {
            CounterEntry* currentCounterPointer = (CounterEntry*)(ResolveOffset(instancePointer->FirstCounterOffset, CounterEntrySize));
            CounterEntry* previousCounterPointer = currentCounterPointer;
            for(;;) {
                if (currentCounterPointer->CounterNameHashCode == counterNameHashCode) {
                    if (StringEquals(counterName, currentCounterPointer->CounterNameOffset)) {
                        *returnCounterPointerReference = currentCounterPointer;
                        return true;
                    }
                }

                previousCounterPointer = currentCounterPointer;
                if (currentCounterPointer->NextCounterOffset != 0)
                    currentCounterPointer = (CounterEntry*)(ResolveOffset(currentCounterPointer->NextCounterOffset, CounterEntrySize));
                else {
                    *returnCounterPointerReference = previousCounterPointer;
                    return false;
                }
            }
        }
        private unsafe void VerifyLifetime(InstanceEntry* currentInstancePointer) {
            Debug.Assert(currentInstancePointer->RefCount != 0, "RefCount must be 1 for instances passed to VerifyLifetime");

            CounterEntry* counter = (CounterEntry*) ResolveOffset(currentInstancePointer->FirstCounterOffset, CounterEntrySize);
            if (counter->LifetimeOffset != 0) {
                ProcessLifetimeEntry* lifetime = (ProcessLifetimeEntry*) ResolveOffset(counter->LifetimeOffset, ProcessLifetimeEntrySize);
                if (lifetime->LifetimeType == (int) PerformanceCounterInstanceLifetime.Process) {
                    int pid = lifetime->ProcessId;
                    long startTime = lifetime->StartupTime;

                    if (pid != 0) {

                        // Optimize for this process
                        if (pid == ProcessData.ProcessId) {
                            if ((ProcessData.StartupTime != -1) && (startTime != -1) && (ProcessData.StartupTime != startTime)) {
                                // Process id got recycled.  Reclaim this instance. 
                                currentInstancePointer->RefCount = 0;
                                return;
                            }
                        }
                        else {
                            long processStartTime;
                            using (SafeProcessHandle procHandle = SafeProcessHandle.OpenProcess(NativeMethods.PROCESS_QUERY_INFORMATION, false, pid)) {
                                int error = Marshal.GetLastWin32Error();
                                if ((error == NativeMethods.ERROR_INVALID_PARAMETER) && procHandle.IsInvalid) {
                                    // The process is dead.  Reclaim this instance.  Note that we only clear the refcount here.  
                                    // If we tried to clear the pid and startup time as well, we would have a ---- where
                                    // we could clear the pid/startup time but not the refcount. 
                                    currentInstancePointer->RefCount = 0;
                                    return;
                                }

                                // Defer cleaning the instance when we had previously encountered errors in 
                                // recording process start time (i.e, when startTime == -1) until after the 
                                // process id is not valid (which will be caught in the if check above)
                                if (!procHandle.IsInvalid && startTime != -1) {
                                    long temp;
                                    if (NativeMethods.GetProcessTimes(procHandle, out processStartTime, out temp, out temp, out temp)) {
                                        if (processStartTime != startTime) {
                                            // The process is dead but a new one is using the same pid.  Reclaim this instance. 
                                            currentInstancePointer->RefCount = 0;
                                            return;
                                        }
                                    }
                                }
                            }

                            // Check to see if the process handle has been signaled by the kernel.  If this is the case then it's safe
                            // to reclaim the instance as the process is in the process of exiting.
                            using (SafeProcessHandle procHandle = SafeProcessHandle.OpenProcess(NativeMethods.SYNCHRONIZE, false, pid)) {
                                if (!procHandle.IsInvalid) {
                                    using (ProcessWaitHandle wh = new ProcessWaitHandle(procHandle)) {
                                        if (wh.WaitOne(0, false)) {
                                            // Process has exited
                                            currentInstancePointer->RefCount = 0;
                                            return;
                                        }
                                    }
                                }
                            }
                        }
                    }
                    
                }
            }
        }
        private unsafe void RemoveOneInstance(InstanceEntry* instancePointer, bool clearValue) {
            bool sectionEntered = false;

            RuntimeHelpers.PrepareConstrainedRegions();
            try {
                if (!categoryData.UseUniqueSharedMemory) {
                    while (!sectionEntered) {
                        WaitAndEnterCriticalSection(&(instancePointer->SpinLock), out sectionEntered);
                    }
                }
            
                instancePointer->RefCount = 0;

                if (clearValue)
                    ClearCounterValues(instancePointer);
            }
            finally {
                if (sectionEntered)
                    ExitCriticalSection(&(instancePointer->SpinLock));
            }
        }
        private unsafe bool TryReuseInstance(int instanceNameHashCode, string instanceName, 
                                               CategoryEntry* categoryPointer, InstanceEntry** returnInstancePointerReference, 
                                               PerformanceCounterInstanceLifetime lifetime,
                                               InstanceEntry* lockInstancePointer) {
            //
            // 2nd pass find a free instance slot
            // 
            InstanceEntry* currentInstancePointer = (InstanceEntry*)(ResolveOffset(categoryPointer->FirstInstanceOffset, InstanceEntrySize));
            InstanceEntry* previousInstancePointer = currentInstancePointer;
            for (;;) {
                if (currentInstancePointer->RefCount == 0) {

                    bool hasFit;
                    long instanceNamePtr;       // we need cache this to avoid race conditions. 
                    
                    if (categoryData.UseUniqueSharedMemory) {
                        instanceNamePtr = ResolveOffset(currentInstancePointer->InstanceNameOffset, InstanceNameSlotSize);
                        // In the separate shared memory case we should always have enough space for instances.  The
                        // name slot size is fixed. 
                        Debug.Assert(((instanceName.Length + 1) * 2) <= InstanceNameSlotSize, "The instance name length should always fit in our slot size");
                        hasFit = true;
                    }
                    else {
                        // we don't know the string length yet. 
                        instanceNamePtr = ResolveOffset(currentInstancePointer->InstanceNameOffset, 0);

                        // In the global shared memory, we require names to be exactly the same length in order
                        // to reuse them.  This way we don't end up leaking any space and we don't need to 
                        // depend on the layout of the memory to calculate the space we have. 
                        int length = GetStringLength((char*) instanceNamePtr);
                        hasFit = (length == instanceName.Length);
                    }

                    bool noSpinLock = (lockInstancePointer == currentInstancePointer) || categoryData.UseUniqueSharedMemory;
                    // Instance name fit
                    if (hasFit) {
                        // don't bother locking again if we're using a separate shared memory.  
                        bool sectionEntered;
                        if (noSpinLock)
                            sectionEntered = true;
                        else
                            WaitAndEnterCriticalSection(&(currentInstancePointer->SpinLock), out sectionEntered);

                        if (sectionEntered) {
                            try {
                                // Make copy with zero-term
                                SafeMarshalCopy(instanceName, (IntPtr)instanceNamePtr);
                                currentInstancePointer->InstanceNameHashCode = instanceNameHashCode;

                                // return
                                *returnInstancePointerReference = currentInstancePointer;
                                // clear the counter values. 
                                ClearCounterValues(*returnInstancePointerReference);

                                if (categoryData.UseUniqueSharedMemory) {
                                    CounterEntry* counterPointer = (CounterEntry*)ResolveOffset(currentInstancePointer->FirstCounterOffset, CounterEntrySize);
                                    ProcessLifetimeEntry* lifetimeEntry = (ProcessLifetimeEntry*) ResolveOffset(counterPointer->LifetimeOffset, ProcessLifetimeEntrySize);
                                    PopulateLifetimeEntry(lifetimeEntry, lifetime);
                                }
                                
                                (*returnInstancePointerReference)->RefCount = 1;
                                return true;
                            }
                            finally {
                                if (!noSpinLock)
                                    ExitCriticalSection(&(currentInstancePointer->SpinLock));
                            }
                        }
                    }
                 }
            
                previousInstancePointer = currentInstancePointer;
                if (currentInstancePointer->NextInstanceOffset != 0)
                    currentInstancePointer = (InstanceEntry*)(ResolveOffset(currentInstancePointer->NextInstanceOffset, InstanceEntrySize));
                else
                {
                    *returnInstancePointerReference = previousInstancePointer;
                    return false;
                }
            }
        }
        private unsafe void VerifyInstance(InstanceEntry* currentInstancePointer) {
            int freeOffset = *((int*)baseAddress);
            ResolveOffset(freeOffset, 0);        // verify next free offset

            if (currentInstancePointer->NextInstanceOffset > freeOffset)
                currentInstancePointer->NextInstanceOffset = 0;
            else if (currentInstancePointer->NextInstanceOffset != 0)
                VerifyInstance((InstanceEntry*) ResolveOffset(currentInstancePointer->NextInstanceOffset, InstanceEntrySize));
        }
示例#10
0
        private static void CreateMDL0Object(
            InstanceEntry inst,
            NodeEntry node,
            ResourceNode parent,
            PrimitiveManager manager,
            MDL0Node model,
            DecoderShell shell)
        {
            if (manager != null)
            {
                Error = "There was a problem creating a new object for " + (node._name != null ? node._name : node._id);

                MDL0ObjectNode poly = new MDL0ObjectNode()
                {
                    _manager   = manager,
                    _name      = node._name != null ? node._name : node._id,
                    _drawCalls = new BindingList <DrawCall>()
                };

                //Attach material
                if (inst._material != null)
                {
                    foreach (MaterialEntry mat in shell._materials)
                    {
                        if (mat._id == inst._material._target)
                        {
                            poly._drawCalls.Add(new DrawCall(poly)
                            {
                                MaterialNode = mat._node as MDL0MaterialNode
                            });
                        }
                    }
                }

                model._numTriangles  += poly._numFaces = manager._faceCount = manager._pointCount / 3;
                model._numFacepoints += poly._numFacepoints = manager._pointCount;

                poly._parent = model._objGroup;
                model._objList.Add(poly);

                model.ResetToBindState();

                //Attach single-bind
                if (parent != null && parent is MDL0BoneNode)
                {
                    MDL0BoneNode bone = (MDL0BoneNode)parent;
                    poly.DeferUpdateAssets();
                    poly.MatrixNode = bone;

                    foreach (DrawCall c in poly._drawCalls)
                    {
                        c.VisibilityBoneNode = bone;
                    }
                }
                else if (model._boneList.Count == 0)
                {
                    Error = String.Format("There was a problem rigging {0} to a single bone.", poly._name);

                    Box          box  = poly.GetBox();
                    MDL0BoneNode bone = new MDL0BoneNode()
                    {
                        Scale       = Vector3.One,
                        Translation = (box.Max + box.Min) / 2.0f,
                        _name       = "TransN_" + poly.Name,
                        Parent      = TempRootBone,
                    };

                    poly.DeferUpdateAssets();
                    poly.MatrixNode = bone;
                    ((MDL0BoneNode)TempRootBone).RecalcBindState(true, false, false);

                    foreach (DrawCall c in poly._drawCalls)
                    {
                        c.VisibilityBoneNode = bone;
                    }
                }
                else
                {
                    Error = String.Format("There was a problem checking if {0} is rigged to a single bone.", poly._name);

                    foreach (DrawCall c in poly._drawCalls)
                    {
                        c.VisibilityBoneNode = model._boneList[0] as MDL0BoneNode;
                    }

                    IMatrixNode mtxNode    = null;
                    bool        singlebind = true;

                    foreach (Vertex3 v in poly._manager._vertices)
                    {
                        if (v.MatrixNode != null)
                        {
                            if (mtxNode == null)
                            {
                                mtxNode = v.MatrixNode;
                            }

                            if (v.MatrixNode != mtxNode)
                            {
                                singlebind = false;
                                break;
                            }
                        }
                    }

                    if (singlebind && poly._matrixNode == null)
                    {
                        //Reassign reference entries
                        if (poly._manager._vertices[0].MatrixNode != null)
                        {
                            poly._manager._vertices[0].MatrixNode.Users.Add(poly);
                        }

                        foreach (Vertex3 v in poly._manager._vertices)
                        {
                            if (v.MatrixNode != null)
                            {
                                v.MatrixNode.Users.Remove(v);
                            }
                        }

                        poly._nodeId = -2; //Continued on polygon rebuild
                    }
                }
            }
        }
        private void CreateObject(InstanceEntry inst, NodeEntry node, ResourceNode parent, PrimitiveManager manager, MDL0Node model, DecoderShell shell)
        {
            if (manager != null)
            {
                Error = "There was a problem creating a new object for " + (node._name != null ? node._name : node._id);
                int i = 0;
                foreach (Vertex3 v in manager._vertices)
                    v._index = i++;

                MDL0ObjectNode poly = new MDL0ObjectNode() { _manager = manager };
                poly._manager._polygon = poly;
                poly._name = node._name != null ? node._name : node._id;

                //Attach single-bind
                if (parent != null && parent is MDL0BoneNode)
                    poly.MatrixNode = (MDL0BoneNode)parent;

                //Attach material
                if (inst._material != null)
                    foreach (MaterialEntry mat in shell._materials)
                        if (mat._id == inst._material._target)
                        {
                            (poly._opaMaterial = (mat._node as MDL0MaterialNode))._objects.Add(poly);
                            break;
                        }

                model._numFaces += poly._numFaces = manager._faceCount = manager._pointCount / 3;
                model._numFacepoints += poly._numFacepoints = manager._pointCount;

                poly._parent = model._objGroup;
                model._objList.Add(poly);
            }
        }
 private unsafe void VerifyInstance(InstanceEntry* currentInstancePointer)
 {
     int offset = *((int*) this.baseAddress);
     this.ResolveOffset(offset, 0);
     if (currentInstancePointer.NextInstanceOffset > offset)
     {
         currentInstancePointer.NextInstanceOffset = 0;
     }
     else if (currentInstancePointer.NextInstanceOffset != 0)
     {
         this.VerifyInstance((InstanceEntry*) this.ResolveOffset(currentInstancePointer.NextInstanceOffset, InstanceEntrySize));
     }
 }
 private unsafe void VerifyLifetime(InstanceEntry* currentInstancePointer)
 {
     CounterEntry* entryPtr = (CounterEntry*) this.ResolveOffset(currentInstancePointer.FirstCounterOffset, CounterEntrySize);
     if (entryPtr->LifetimeOffset != 0)
     {
         ProcessLifetimeEntry* entryPtr2 = (ProcessLifetimeEntry*) this.ResolveOffset(entryPtr->LifetimeOffset, ProcessLifetimeEntrySize);
         if (entryPtr2->LifetimeType == 1)
         {
             int processId = entryPtr2->ProcessId;
             long startupTime = entryPtr2->StartupTime;
             if (processId != 0)
             {
                 if (processId == ProcessData.ProcessId)
                 {
                     if (((ProcessData.StartupTime != -1L) && (startupTime != -1L)) && (ProcessData.StartupTime != startupTime))
                     {
                         currentInstancePointer.RefCount = 0;
                     }
                 }
                 else
                 {
                     using (Microsoft.Win32.SafeHandles.SafeProcessHandle handle = Microsoft.Win32.SafeHandles.SafeProcessHandle.OpenProcess(0x400, false, processId))
                     {
                         long num3;
                         long num5;
                         if ((Marshal.GetLastWin32Error() == 0x57) && handle.IsInvalid)
                         {
                             currentInstancePointer.RefCount = 0;
                             return;
                         }
                         if ((!handle.IsInvalid && (startupTime != -1L)) && (Microsoft.Win32.NativeMethods.GetProcessTimes(handle, out num3, out num5, out num5, out num5) && (num3 != startupTime)))
                         {
                             currentInstancePointer.RefCount = 0;
                             return;
                         }
                     }
                     using (Microsoft.Win32.SafeHandles.SafeProcessHandle handle2 = Microsoft.Win32.SafeHandles.SafeProcessHandle.OpenProcess(0x100000, false, processId))
                     {
                         if (!handle2.IsInvalid)
                         {
                             using (ProcessWaitHandle handle3 = new ProcessWaitHandle(handle2))
                             {
                                 if (handle3.WaitOne(0, false))
                                 {
                                     currentInstancePointer.RefCount = 0;
                                 }
                             }
                         }
                     }
                 }
             }
         }
     }
 }
 private unsafe void ClearCounterValues(InstanceEntry* instancePointer)
 {
     CounterEntry* counterEntry = null;
     if (instancePointer.FirstCounterOffset != 0)
     {
         counterEntry = (CounterEntry*) this.ResolveOffset(instancePointer.FirstCounterOffset, CounterEntrySize);
     }
     while (counterEntry != null)
     {
         SetValue(counterEntry, 0L);
         if (counterEntry->NextCounterOffset != 0)
         {
             counterEntry = (CounterEntry*) this.ResolveOffset(counterEntry->NextCounterOffset, CounterEntrySize);
         }
         else
         {
             counterEntry = null;
         }
     }
 }
 private unsafe bool TryReuseInstance(int instanceNameHashCode, string instanceName, CategoryEntry* categoryPointer, InstanceEntry** returnInstancePointerReference, PerformanceCounterInstanceLifetime lifetime, InstanceEntry* lockInstancePointer)
 {
     InstanceEntry* entryPtr = (InstanceEntry*) this.ResolveOffset(categoryPointer.FirstInstanceOffset, InstanceEntrySize);
     InstanceEntry* entryPtr2 = entryPtr;
 Label_0015:
     if (entryPtr->RefCount == 0)
     {
         bool flag;
         long num;
         if (this.categoryData.UseUniqueSharedMemory)
         {
             num = this.ResolveOffset(entryPtr->InstanceNameOffset, 0x100);
             flag = true;
         }
         else
         {
             num = this.ResolveOffset(entryPtr->InstanceNameOffset, 0);
             flag = this.GetStringLength((char*) num) == instanceName.Length;
         }
         bool flag2 = (lockInstancePointer == entryPtr) || this.categoryData.UseUniqueSharedMemory;
         if (flag)
         {
             bool flag3;
             if (flag2)
             {
                 flag3 = true;
             }
             else
             {
                 WaitAndEnterCriticalSection(&entryPtr->SpinLock, out flag3);
             }
             if (flag3)
             {
                 try
                 {
                     SafeMarshalCopy(instanceName, (IntPtr) num);
                     entryPtr->InstanceNameHashCode = instanceNameHashCode;
                     *((IntPtr*) returnInstancePointerReference) = entryPtr;
                     this.ClearCounterValues(returnInstancePointerReference[0]);
                     if (this.categoryData.UseUniqueSharedMemory)
                     {
                         CounterEntry* entryPtr3 = (CounterEntry*) this.ResolveOffset(entryPtr->FirstCounterOffset, CounterEntrySize);
                         ProcessLifetimeEntry* lifetimeEntry = (ProcessLifetimeEntry*) this.ResolveOffset(entryPtr3->LifetimeOffset, ProcessLifetimeEntrySize);
                         PopulateLifetimeEntry(lifetimeEntry, lifetime);
                     }
                     *(((IntPtr*) returnInstancePointerReference)).RefCount = 1;
                     return true;
                 }
                 finally
                 {
                     if (!flag2)
                     {
                         ExitCriticalSection(&entryPtr->SpinLock);
                     }
                 }
             }
         }
     }
     entryPtr2 = entryPtr;
     if (entryPtr->NextInstanceOffset != 0)
     {
         entryPtr = (InstanceEntry*) this.ResolveOffset(entryPtr->NextInstanceOffset, InstanceEntrySize);
         goto Label_0015;
     }
     *((IntPtr*) returnInstancePointerReference) = entryPtr2;
     return false;
 }
 private unsafe void RemoveOneInstance(InstanceEntry* instancePointer, bool clearValue)
 {
     bool taken = false;
     RuntimeHelpers.PrepareConstrainedRegions();
     try
     {
         if (!this.categoryData.UseUniqueSharedMemory)
         {
             while (!taken)
             {
                 WaitAndEnterCriticalSection(&instancePointer.SpinLock, out taken);
             }
         }
         instancePointer.RefCount = 0;
         if (clearValue)
         {
             this.ClearCounterValues(instancePointer);
         }
     }
     finally
     {
         if (taken)
         {
             ExitCriticalSection(&instancePointer.SpinLock);
         }
     }
 }
        private unsafe bool FindInstance(int instanceNameHashCode, string instanceName, 
                                           CategoryEntry* categoryPointer, InstanceEntry** returnInstancePointerReference, 
                                           bool activateUnusedInstances, PerformanceCounterInstanceLifetime lifetime, 
                                           out bool foundFreeInstance) {

            InstanceEntry* currentInstancePointer = (InstanceEntry*)(ResolveOffset(categoryPointer->FirstInstanceOffset, InstanceEntrySize));
            InstanceEntry* previousInstancePointer = currentInstancePointer;
            foundFreeInstance = false;
            // Look at the first instance to determine if this is single or multi instance. 
            if (currentInstancePointer->InstanceNameHashCode == SingleInstanceHashCode) {
                if (StringEquals(SingleInstanceName, currentInstancePointer->InstanceNameOffset)){
                    if (instanceName != SingleInstanceName)
                        throw new InvalidOperationException(SR.GetString(SR.SingleInstanceOnly, categoryName));
                }
                else {
                    if (instanceName == SingleInstanceName)
                        throw new InvalidOperationException(SR.GetString(SR.MultiInstanceOnly, categoryName));
                }
            }
            else {
                if (instanceName == SingleInstanceName)
                    throw new InvalidOperationException(SR.GetString(SR.MultiInstanceOnly, categoryName));
            }

            //
            // 1st pass find exact matching!
            // 
            // We don't need to aggressively claim unused instances. For performance, we would proactively 
            // verify lifetime of instances if activateUnusedInstances is specified and certain time 
            // has elapsed since last sweep or we are running out of shared memory.  
            bool verifyLifeTime = activateUnusedInstances;
            if (activateUnusedInstances) {
                
                int totalSize = InstanceEntrySize + ProcessLifetimeEntrySize + InstanceNameSlotSize +  (CounterEntrySize * categoryData.CounterNames.Count);
                int freeMemoryOffset = *((int *) baseAddress);
                int alignmentAdjustment;
                int newOffset = CalculateMemoryNoBoundsCheck(freeMemoryOffset, totalSize, out alignmentAdjustment);

                if (!(newOffset > FileView.FileMappingSize || newOffset < 0)) {
                    long tickDelta = (DateTime.Now.Ticks - Volatile.Read(ref LastInstanceLifetimeSweepTick));  
                    if (tickDelta < InstanceLifetimeSweepWindow) 
                        verifyLifeTime = false;    
                }
            }

            new SecurityPermission(SecurityPermissionFlag.UnmanagedCode).Assert();
            try {
                for(;;) {
                    bool verifiedLifetimeOfThisInstance = false;
                    if (verifyLifeTime && (currentInstancePointer->RefCount != 0)) {
                        verifiedLifetimeOfThisInstance = true;
                        VerifyLifetime(currentInstancePointer);
                    }
                    
                    if (currentInstancePointer->InstanceNameHashCode == instanceNameHashCode) {
                        if (StringEquals(instanceName, currentInstancePointer->InstanceNameOffset)){
                            // we found a matching instance. 
                            *returnInstancePointerReference = currentInstancePointer;
    
                            CounterEntry* firstCounter = (CounterEntry*) ResolveOffset(currentInstancePointer->FirstCounterOffset, CounterEntrySize);
                            ProcessLifetimeEntry* lifetimeEntry;
                            if (categoryData.UseUniqueSharedMemory) 
                                lifetimeEntry = (ProcessLifetimeEntry*) ResolveOffset(firstCounter->LifetimeOffset, ProcessLifetimeEntrySize);
                            else
                                lifetimeEntry = null;
                            
                            // ensure that we have verified the lifetime of the matched instance
                            if (!verifiedLifetimeOfThisInstance && currentInstancePointer->RefCount != 0) 
                                VerifyLifetime(currentInstancePointer);
                                
                            if (currentInstancePointer->RefCount != 0) {
                                if (lifetimeEntry != null && lifetimeEntry->ProcessId != 0) {
                                    if (lifetime != PerformanceCounterInstanceLifetime.Process)
                                        throw new InvalidOperationException(SR.GetString(SR.CantConvertProcessToGlobal));
                                        
                                    // make sure only one process is using this instance. 
                                    if (ProcessData.ProcessId != lifetimeEntry->ProcessId)
                                        throw new InvalidOperationException(SR.GetString(SR.InstanceAlreadyExists, instanceName));

                                   // compare start time of the process, account for ACL issues in querying process information
                                    if ((lifetimeEntry->StartupTime != -1) && (ProcessData.StartupTime != -1)) { 
                                        if (ProcessData.StartupTime != lifetimeEntry->StartupTime)
                                            throw new InvalidOperationException(SR.GetString(SR.InstanceAlreadyExists, instanceName));
                                    }
                                }
                                else {
                                    if (lifetime == PerformanceCounterInstanceLifetime.Process)
                                        throw new InvalidOperationException(SR.GetString(SR.CantConvertGlobalToProcess));
                                }
                                return true;
                            }
                            
                            if (activateUnusedInstances) {
                                Mutex mutex = null;
                                RuntimeHelpers.PrepareConstrainedRegions();
                                try {
                                    SharedUtils.EnterMutexWithoutGlobal(categoryData.MutexName, ref mutex);
                                    ClearCounterValues(currentInstancePointer);
                                    if (lifetimeEntry != null)
                                        PopulateLifetimeEntry(lifetimeEntry, lifetime);
                                    
                                    currentInstancePointer->RefCount = 1;
                                    return true;
                                }
                                finally {
                                    if (mutex != null) {
                                        mutex.ReleaseMutex();
                                        mutex.Close();
                                    }
                                }
                            }
                            else
                                return false;
                        }
                    }
    
                    if (currentInstancePointer->RefCount == 0) {
                        foundFreeInstance = true;
                    }
    
                    previousInstancePointer = currentInstancePointer;
                    if (currentInstancePointer->NextInstanceOffset != 0)
                        currentInstancePointer =  (InstanceEntry*)(ResolveOffset(currentInstancePointer->NextInstanceOffset, InstanceEntrySize));
                    else {
                        *returnInstancePointerReference = previousInstancePointer;
                        return false;
                    }
                }
            }
            finally  {
                SecurityPermission.RevertAssert();
                
                if (verifyLifeTime) 
                    Volatile.Write(ref LastInstanceLifetimeSweepTick, DateTime.Now.Ticks);
            }
        }
示例#18
0
        private void WriteToCache(InstanceEntry entry, string serviceName, Guid serviceId)
        {
            var instance = entry.ToInstance();

            _instanceCache.AddOrUpdate(serviceName, serviceId, instance);
        }
 private unsafe bool FindCounter(int counterNameHashCode, string counterName, InstanceEntry* instancePointer, CounterEntry** returnCounterPointerReference)
 {
     CounterEntry* entryPtr = (CounterEntry*) this.ResolveOffset(instancePointer.FirstCounterOffset, CounterEntrySize);
     CounterEntry* entryPtr2 = entryPtr;
 Label_0015:
     if ((entryPtr->CounterNameHashCode == counterNameHashCode) && this.StringEquals(counterName, entryPtr->CounterNameOffset))
     {
         *((IntPtr*) returnCounterPointerReference) = entryPtr;
         return true;
     }
     entryPtr2 = entryPtr;
     if (entryPtr->NextCounterOffset != 0)
     {
         entryPtr = (CounterEntry*) this.ResolveOffset(entryPtr->NextCounterOffset, CounterEntrySize);
         goto Label_0015;
     }
     *((IntPtr*) returnCounterPointerReference) = entryPtr2;
     return false;
 }
            private InstanceEntry ParseInstance(InstanceType type)
            {
                InstanceEntry c = new InstanceEntry();
                c._type = type;

                while (_reader.ReadAttribute())
                    if (_reader.Name.Equals("url", true))
                        c._url = _reader.Value[0] == '#' ? (string)(_reader.Value + 1) : (string)_reader.Value;

                while (_reader.BeginElement())
                {
                    if (_reader.Name.Equals("skeleton", true))
                        c.skeletons.Add(_reader.Value[0] == '#' ? (string)(_reader.Value + 1) : (string)_reader.Value);

                    if (_reader.Name.Equals("bind_material", true))
                        while (_reader.BeginElement())
                        {
                            if (_reader.Name.Equals("technique_common", true))
                                while (_reader.BeginElement())
                                {
                                    if (_reader.Name.Equals("instance_material", true))
                                        c._material = ParseMatInstance();
                                    _reader.EndElement();
                                }
                            _reader.EndElement();
                        }

                    _reader.EndElement();
                }

                return c;
            }
 private unsafe bool FindInstance(int instanceNameHashCode, string instanceName, CategoryEntry* categoryPointer, InstanceEntry** returnInstancePointerReference, bool activateUnusedInstances, PerformanceCounterInstanceLifetime lifetime, out bool foundFreeInstance)
 {
     bool flag3;
     InstanceEntry* currentInstancePointer = (InstanceEntry*) this.ResolveOffset(categoryPointer.FirstInstanceOffset, InstanceEntrySize);
     InstanceEntry* entryPtr2 = currentInstancePointer;
     foundFreeInstance = false;
     if (currentInstancePointer->InstanceNameHashCode == SingleInstanceHashCode)
     {
         if (!this.StringEquals("systemdiagnosticssharedsingleinstance", currentInstancePointer->InstanceNameOffset))
         {
             if (instanceName == "systemdiagnosticssharedsingleinstance")
             {
                 throw new InvalidOperationException(SR.GetString("MultiInstanceOnly", new object[] { this.categoryName }));
             }
         }
         else if (instanceName != "systemdiagnosticssharedsingleinstance")
         {
             throw new InvalidOperationException(SR.GetString("SingleInstanceOnly", new object[] { this.categoryName }));
         }
     }
     else if (instanceName == "systemdiagnosticssharedsingleinstance")
     {
         throw new InvalidOperationException(SR.GetString("MultiInstanceOnly", new object[] { this.categoryName }));
     }
     bool flag = activateUnusedInstances;
     if (activateUnusedInstances)
     {
         int num3;
         int totalSize = ((InstanceEntrySize + ProcessLifetimeEntrySize) + 0x100) + (CounterEntrySize * this.categoryData.CounterNames.Count);
         int oldOffset = *((int*) this.baseAddress);
         int num4 = this.CalculateMemoryNoBoundsCheck(oldOffset, totalSize, out num3);
         if ((num4 <= this.FileView.FileMappingSize) && (num4 >= 0))
         {
             long num5 = DateTime.Now.Ticks - LastInstanceLifetimeSweepTick;
             if (num5 < InstanceLifetimeSweepWindow)
             {
                 flag = false;
             }
         }
     }
     new SecurityPermission(SecurityPermissionFlag.UnmanagedCode).Assert();
     try
     {
         bool flag2;
     Label_0156:
         flag2 = false;
         if (flag && (currentInstancePointer->RefCount != 0))
         {
             flag2 = true;
             this.VerifyLifetime(currentInstancePointer);
         }
         if ((currentInstancePointer->InstanceNameHashCode == instanceNameHashCode) && this.StringEquals(instanceName, currentInstancePointer->InstanceNameOffset))
         {
             ProcessLifetimeEntry* entryPtr4;
             *((IntPtr*) returnInstancePointerReference) = currentInstancePointer;
             CounterEntry* entryPtr3 = (CounterEntry*) this.ResolveOffset(currentInstancePointer->FirstCounterOffset, CounterEntrySize);
             if (this.categoryData.UseUniqueSharedMemory)
             {
                 entryPtr4 = (ProcessLifetimeEntry*) this.ResolveOffset(entryPtr3->LifetimeOffset, ProcessLifetimeEntrySize);
             }
             else
             {
                 entryPtr4 = null;
             }
             if (!flag2 && (currentInstancePointer->RefCount != 0))
             {
                 this.VerifyLifetime(currentInstancePointer);
             }
             if (currentInstancePointer->RefCount != 0)
             {
                 if ((entryPtr4 != null) && (entryPtr4->ProcessId != 0))
                 {
                     if (lifetime != PerformanceCounterInstanceLifetime.Process)
                     {
                         throw new InvalidOperationException(SR.GetString("CantConvertProcessToGlobal"));
                     }
                     if (ProcessData.ProcessId != entryPtr4->ProcessId)
                     {
                         throw new InvalidOperationException(SR.GetString("InstanceAlreadyExists", new object[] { instanceName }));
                     }
                     if (((entryPtr4->StartupTime != -1L) && (ProcessData.StartupTime != -1L)) && (ProcessData.StartupTime != entryPtr4->StartupTime))
                     {
                         throw new InvalidOperationException(SR.GetString("InstanceAlreadyExists", new object[] { instanceName }));
                     }
                 }
                 else if (lifetime == PerformanceCounterInstanceLifetime.Process)
                 {
                     throw new InvalidOperationException(SR.GetString("CantConvertGlobalToProcess"));
                 }
                 return true;
             }
             if (activateUnusedInstances)
             {
                 Mutex mutex = null;
                 RuntimeHelpers.PrepareConstrainedRegions();
                 try
                 {
                     SharedUtils.EnterMutexWithoutGlobal(this.categoryData.MutexName, ref mutex);
                     this.ClearCounterValues(currentInstancePointer);
                     if (entryPtr4 != null)
                     {
                         PopulateLifetimeEntry(entryPtr4, lifetime);
                     }
                     currentInstancePointer->RefCount = 1;
                     return true;
                 }
                 finally
                 {
                     if (mutex != null)
                     {
                         mutex.ReleaseMutex();
                         mutex.Close();
                     }
                 }
             }
             return false;
         }
         if (currentInstancePointer->RefCount == 0)
         {
             foundFreeInstance = true;
         }
         entryPtr2 = currentInstancePointer;
         if (currentInstancePointer->NextInstanceOffset != 0)
         {
             currentInstancePointer = (InstanceEntry*) this.ResolveOffset(currentInstancePointer->NextInstanceOffset, InstanceEntrySize);
             goto Label_0156;
         }
         *((IntPtr*) returnInstancePointerReference) = entryPtr2;
         flag3 = false;
     }
     finally
     {
         CodeAccessPermission.RevertAssert();
         if (flag)
         {
             LastInstanceLifetimeSweepTick = DateTime.Now.Ticks;
         }
     }
     return flag3;
 }
示例#22
0
 private bool ShouldUpdate(InstanceEntry entry, ZooPickerOptions.InstanceOptions insOpts)
 {
     return(entry.State != insOpts.State ||
            entry.Weight != insOpts.Weight);
 }