Beispiel #1
0
        public static unsafe void Advise <T>(this Ipc scope, string method, Action <T> proxy)
            where T : struct
        {
            CallFrameListDescriptor *descriptor = null; //scope.GetObject<CallFrameListDescriptor>("CallFrameListDescriptor:" + method);
            CallFrameListNode *      node       = null; //scope.GetObject<CallFrameListNode>("CallFrameListNode:" + descriptor->CallFrameListHead);

            //Seek to the end of the frame list
            while (Interlocked.CompareExchange(ref node->NextCallFrame, 0, 0) != 0)
            {
                node = null; //scope.GetObject<CallFrameListNode>("CallFrameListNode:" + node->NextCallFrame);
            }

            //The current value of node is the one before any calls we'd process
            new Thread(() =>
            {
                while (true)
                {
                    //while there's no node to process, wait patiently
                    while (Interlocked.CompareExchange(ref node->NextCallFrame, 0, 0) == 0)
                    {
                        Thread.Sleep(1);
                    }

                    //Move to the unprocessed frame
                    node = null; //scope.GetObject<CallFrameListNode>("CallFrameListNode:" + node->NextCallFrame);

                    //Process it
                    Ipc <T> frameData = scope.GetObject <T>("CallFrame:" + node->FrameId);
                    proxy(frameData.Value);
                }
            }).Start();
        }
Beispiel #2
0
        public static unsafe void QueueCall <T>(this Ipc scope, string method, T frameContent)
            where T : struct
        {
            CallFrameListDescriptor *descriptor = null; //scope.GetObject<CallFrameListDescriptor>("CallFrameListDescriptor:" + method);
            CallFrameListNode *      node       = null; //scope.GetObject<CallFrameListNode>("CallFrameListNode:" + descriptor->CallFrameListHead);
            Luid id = new Luid {
                Whole = Guid.NewGuid()
            };
            MemoryMappedFile data;

            //Get a space to store the frame in
            do
            {
                try
                {
                    data = MemoryMappedFile.CreateNew($"{scope.Name}:CallFrames:{id.Low}", Marshal.SizeOf <T>(), MemoryMappedFileAccess.ReadWrite);
                    //Write frameContent into data
                    break;
                }
                catch
                {
                    id = new Luid {
                        Whole = Guid.NewGuid()
                    };
                }
            } while (true);

            //Acquire the tail of the call frame list
            while (Interlocked.CompareExchange(ref node->NextCallFrame, id.Low, 0) != 0)
            {
                node = null; //scope.GetObject<CallFrameListNode>("CallFrameListNode:" + node->NextCallFrame);
            }

            node = null; //scope.GetObject<CallFrameListNode>("CallFrameListNode:" + id.Low);
            //Write the current time to the call frame so it may be reclaimed at some point
            //write

            Interlocked.Exchange(ref descriptor->CallFrameListHead, id.Low);
        }