Beispiel #1
0
        /// <summary>
        /// Tries to open a named event.
        /// </summary>
        /// <param name="globalMemoryRegion"></param>
        /// <param name="memoryRegionId"></param>
        /// <param name="namedEvent"></param>
        /// <returns></returns>
        public static bool TryOpenExisting(
            this GlobalMemoryRegion globalMemoryRegion,
            MlosInternal.MemoryRegionId memoryRegionId,
            out NamedEvent namedEvent)
        {
            MlosInternal.RegisteredNamedEventConfig.CodegenKey namedEventLookupKey = default;
            namedEventLookupKey.MemoryRegionId = memoryRegionId;

            // Locate named event config.
            //
            SharedConfig <MlosProxyInternal.RegisteredNamedEventConfig> registeredNamedEventSharedConfig =
                SharedConfigManager.Lookup(globalMemoryRegion.SharedConfigDictionary, namedEventLookupKey);

            if (!registeredNamedEventSharedConfig.HasSharedConfig)
            {
                namedEvent = null;
                return(false);
            }

            // Config exists, create a named event.
            //
            MlosProxyInternal.RegisteredNamedEventConfig registeredNamedEventConfig = registeredNamedEventSharedConfig.Config;

            namedEvent = NamedEvent.CreateOrOpen(registeredNamedEventConfig.EventName.Value);

            return(true);
        }
        /// <summary>
        /// Handle requests.
        /// </summary>
        public void HandleRequests()
        {
            File.Delete(socketName);

            serverSocket = new Socket(AddressFamily.Unix, SocketType.Stream, ProtocolType.Unspecified);

            // Start listening on the Unix socket.
            //
            serverSocket.Bind(new UnixDomainSocketEndPoint(socketName));
            serverSocket.Listen(backlog: 1);

            // Signal the target process, the Agent is ready.
            //
            using NamedEvent namedEvent = NamedEvent.CreateOrOpen(semaphoreName);
            namedEvent.Signal();
            {
                // Accept the connection and obtain the list of the shared memory regions.
                //
                using Socket acceptedSocket = serverSocket.Accept();
                HandleAcceptedRequest(acceptedSocket);
            }

            Thread handlerThread = new Thread(
                start: () =>
            {
                while (!isDisposed)
                {
                    Socket socket = serverSocket;
                    if (socket == null)
                    {
                        // Stop processing the request after we disposed the socket.
                        //
                        break;
                    }

                    try
                    {
                        using Socket acceptedSocket = socket.Accept();
                        HandleAcceptedRequest(acceptedSocket);
                    }
                    catch (SocketException)
                    {
                        // Ignore the exception.
                        //
                    }
                    catch (ObjectDisposedException)
                    {
                        // Ignore the exception.
                        //
                    }
                }
            });

            handlerThread.Start();
        }
        /// <summary>
        /// Creates InterProcessMlosContext.
        /// </summary>
        /// <returns></returns>
        public static AnonymousMemoryMlosContext Create()
        {
            var fdExchangeServer = new FileDescriptorExchangeServer(FdUnitDomainSocketName, FdExchangeSemaphoreName);

            fdExchangeServer.HandleRequests();

            MemoryRegionId memoryRegionId = new MemoryRegionId {
                Type = MemoryRegionType.Global
            };
            SharedMemoryRegionView <MlosProxyInternal.GlobalMemoryRegion> globalMemoryRegionView =
                SharedMemoryRegionView.OpenAnonymousFromFileDescriptor <MlosProxyInternal.GlobalMemoryRegion>(
                    fdExchangeServer.GetSharedMemoryFd(memoryRegionId),
                    fdExchangeServer.GetSharedMemorySize(memoryRegionId));

            memoryRegionId = new MemoryRegionId {
                Type = MemoryRegionType.ControlChannel
            };
            SharedMemoryMapView controlChannelMemoryMapView = SharedMemoryMapView.OpenAnonymousFromFileDescriptor(
                fdExchangeServer.GetSharedMemoryFd(memoryRegionId),
                fdExchangeServer.GetSharedMemorySize(memoryRegionId));

            memoryRegionId = new MemoryRegionId {
                Type = MemoryRegionType.FeedbackChannel
            };
            SharedMemoryMapView feedbackChannelMemoryMapView = SharedMemoryMapView.OpenAnonymousFromFileDescriptor(
                fdExchangeServer.GetSharedMemoryFd(memoryRegionId),
                fdExchangeServer.GetSharedMemorySize(memoryRegionId));

            memoryRegionId = new MemoryRegionId {
                Type = MemoryRegionType.SharedConfig
            };
            SharedMemoryRegionView <MlosProxyInternal.SharedConfigMemoryRegion> sharedConfigMemoryRegionView =
                SharedMemoryRegionView.OpenAnonymousFromFileDescriptor <MlosProxyInternal.SharedConfigMemoryRegion>(
                    fdExchangeServer.GetSharedMemoryFd(memoryRegionId),
                    fdExchangeServer.GetSharedMemorySize(memoryRegionId));

            // Create channel synchronization primitives.
            //
            NamedEvent controlChannelNamedEvent  = NamedEvent.CreateOrOpen(ControlChannelSemaphoreName);
            NamedEvent feedbackChannelNamedEvent = NamedEvent.CreateOrOpen(FeedbackChannelSemaphoreName);

            return(new AnonymousMemoryMlosContext(
                       globalMemoryRegionView,
                       controlChannelMemoryMapView,
                       feedbackChannelMemoryMapView,
                       sharedConfigMemoryRegionView,
                       controlChannelNamedEvent,
                       feedbackChannelNamedEvent,
                       fdExchangeServer));
        }
Beispiel #4
0
        /// <summary>
        /// Initialize shared channel.
        /// </summary>
        public static void InitializeSharedChannel()
        {
            // Create or open the memory mapped files.
            //
            globalMemoryRegionView       = SharedMemoryRegionView.CreateOrOpen <MlosProxyInternal.GlobalMemoryRegion>(GlobalMemoryMapName, SharedMemorySize);
            controlChannelMemoryMapView  = SharedMemoryMapView.CreateOrOpen(ControlChannelMemoryMapName, SharedMemorySize);
            feedbackChannelMemoryMapView = SharedMemoryMapView.CreateOrOpen(FeedbackChannelMemoryMapName, SharedMemorySize);
            sharedConfigMemoryMapView    = SharedMemoryRegionView.CreateOrOpen <MlosProxyInternal.SharedConfigMemoryRegion>(SharedConfigMemoryMapName, SharedMemorySize);

            // Create channel synchronization primitives.
            //
            controlChannelNamedEvent  = NamedEvent.CreateOrOpen(ControlChannelSemaphoreName);
            feedbackChannelNamedEvent = NamedEvent.CreateOrOpen(FeedbackChannelSemaphoreName);

            // Setup feedback channel.
            //
            MlosProxyInternal.GlobalMemoryRegion globalMemoryRegion = globalMemoryRegionView.MemoryRegion();

            // Enable channels.
            //
            globalMemoryRegion.ControlChannelSynchronization.TerminateChannel.Store(false);
            globalMemoryRegion.FeedbackChannelSynchronization.TerminateChannel.Store(false);

            var feedbackChannel = new SharedChannel <InterProcessSharedChannelPolicy, SharedChannelSpinPolicy>(
                buffer: feedbackChannelMemoryMapView.Buffer,
                size: (uint)feedbackChannelMemoryMapView.MemSize,
                sync: globalMemoryRegion.FeedbackChannelSynchronization);

            feedbackChannel.ChannelPolicy.NotificationEvent = feedbackChannelNamedEvent;

            // Set SharedConfig memory region.
            //
            SharedConfigManager.SetMemoryRegion(new MlosProxyInternal.SharedConfigMemoryRegion()
            {
                Buffer = sharedConfigMemoryMapView.MemoryRegion().Buffer
            });

            // Setup MlosContext.
            //
            MlosContext.FeedbackChannel     = feedbackChannel;
            MlosContext.SharedConfigManager = SharedConfigManager;

            // Initialize callbacks.
            //
            MlosProxyInternal.RegisterAssemblyRequestMessage.Callback                 = RegisterAssemblyCallback;
            MlosProxyInternal.RegisterMemoryRegionRequestMessage.Callback             = RegisterMemoryRegionMessageCallback;
            MlosProxyInternal.RegisterSharedConfigMemoryRegionRequestMessage.Callback = RegisterSharedConfigMemoryRegionRequestMessageCallback;
            MlosProxy.TerminateReaderThreadRequestMessage.Callback = TerminateReaderThreadRequestMessageCallback;

            // Register Mlos.Core assembly.
            //
            RegisterAssembly(typeof(MlosContext).Assembly, dispatchTableBaseIndex: 0);

            // Register assemblies from the shared config.
            // Assembly Mlos.NetCore does not have a config, as it is always registered first.
            //
            for (uint index = 1; index < globalMemoryRegion.RegisteredSettingsAssemblyCount.Load(); index++)
            {
                RegisterSettingsAssembly(assemblyIndex: index);
            }
        }