/// <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)); }
/// <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); } }