/// <summary> /// Protected implementation of Dispose pattern. /// </summary> /// <param name="disposing"></param> protected virtual void Dispose(bool disposing) { if (isDisposed || !disposing) { return; } // Close shared memory. // globalMemoryRegionView?.Dispose(); globalMemoryRegionView = null; controlChannelMemoryMapView?.Dispose(); controlChannelMemoryMapView = null; feedbackChannelMemoryMapView?.Dispose(); feedbackChannelMemoryMapView = null; controlChannelNamedEvent?.Dispose(); controlChannelNamedEvent = null; feedbackChannelNamedEvent?.Dispose(); feedbackChannelNamedEvent = null; // Finally dispose the shared config manager. // SharedConfigManager?.Dispose(); SharedConfigManager = null; isDisposed = true; }
/// <summary> /// Creates a shared memory region view. /// </summary> /// <param name="sharedMemoryMapName"></param> /// <param name="sharedMemorySize"></param> /// <returns></returns> /// <typeparam name="T">Memory region type.</typeparam> public static SharedMemoryRegionView <T> Create <T>(string sharedMemoryMapName, ulong sharedMemorySize) where T : ICodegenProxy, new() { var memoryRegionView = new SharedMemoryRegionView <T>(SharedMemoryMapView.Create(sharedMemoryMapName, sharedMemorySize)); MlosProxyInternal.MemoryRegionInitializer <T> memoryRegionInitializer = default; memoryRegionInitializer.Initalize(memoryRegionView); return(memoryRegionView); }
/// <summary> /// Initializes a new instance of the <see cref="InterProcessMlosContext"/> class. /// </summary> /// <returns>InterProcessMlosContext instance.</returns> public static InterProcessMlosContext CreateOrOpen() { NamedEvent targetProcessNamedEvent = NamedEvent.CreateOrOpen(TargetProcessEventName); { bool shouldWaitForTargetProcess = false; try { // Try open a global shared memory and check if the tager process is fully initialized. // using SharedMemoryRegionView <MlosProxyInternal.GlobalMemoryRegion> targetProcessMemoryRegionView = SharedMemoryRegionView.OpenExisting <MlosProxyInternal.GlobalMemoryRegion>(GlobalMemoryMapName, SharedMemorySize); if (targetProcessMemoryRegionView.MemoryRegion().GlobalMemoryRegionIndex == 1) { shouldWaitForTargetProcess = true; } } catch (FileNotFoundException) { // If the target process is not running. // shouldWaitForTargetProcess = true; } if (shouldWaitForTargetProcess) { // If the target process is not fully initialized, wait for the signal. // targetProcessNamedEvent.Wait(); targetProcessNamedEvent.Signal(); } } SharedMemoryRegionView <MlosProxyInternal.GlobalMemoryRegion> globalMemoryRegionView = SharedMemoryRegionView.OpenExisting <MlosProxyInternal.GlobalMemoryRegion>(GlobalMemoryMapName, SharedMemorySize); SharedMemoryMapView controlChannelMemoryMapView = SharedMemoryMapView.OpenExisting(ControlChannelMemoryMapName, SharedMemorySize); SharedMemoryMapView feedbackChannelMemoryMapView = SharedMemoryMapView.OpenExisting(FeedbackChannelMemoryMapName, SharedMemorySize); // Create channel synchronization primitives. // NamedEvent controlChannelNamedEvent = NamedEvent.CreateOrOpen(ControlChannelEventName); NamedEvent feedbackChannelNamedEvent = NamedEvent.CreateOrOpen(FeedbackChannelEventName); return(new InterProcessMlosContext( globalMemoryRegionView, controlChannelMemoryMapView, feedbackChannelMemoryMapView, controlChannelNamedEvent, feedbackChannelNamedEvent, targetProcessNamedEvent)); }
/// <summary> /// Initializes a new instance of the <see cref="InterProcessMlosContext"/> class. /// </summary> /// <param name="globalMemoryRegionView"></param> /// <param name="controlChannelMemoryMapView"></param> /// <param name="feedbackChannelMemoryMapView"></param> /// <param name="controlChannelNamedEvent"></param> /// <param name="feedbackChannelNamedEvent"></param> /// <param name="targetProcessNamedEvent"></param> internal InterProcessMlosContext( SharedMemoryRegionView <MlosProxyInternal.GlobalMemoryRegion> globalMemoryRegionView, SharedMemoryMapView controlChannelMemoryMapView, SharedMemoryMapView feedbackChannelMemoryMapView, NamedEvent controlChannelNamedEvent, NamedEvent feedbackChannelNamedEvent, NamedEvent targetProcessNamedEvent) { this.globalMemoryRegionView = globalMemoryRegionView; this.controlChannelMemoryMapView = controlChannelMemoryMapView; this.feedbackChannelMemoryMapView = feedbackChannelMemoryMapView; this.controlChannelNamedEvent = controlChannelNamedEvent; this.feedbackChannelNamedEvent = feedbackChannelNamedEvent; this.targetProcessNamedEvent = targetProcessNamedEvent; // Create the shared config manager. // SharedConfigManager = new SharedConfigManager(); MlosProxyInternal.GlobalMemoryRegion globalMemoryRegion = globalMemoryRegionView.MemoryRegion(); // Increase the usage counter. When closing global shared memory, we will decrease the counter. // If there is no process using the shared memory, we will clean the OS resources. On Windows OS, // this is no-op; on Linux, we unlink created files. // globalMemoryRegion.AttachedProcessesCount.FetchAdd(1); // Create the control channel instance. // ControlChannel = new SharedChannel <InterProcessSharedChannelPolicy, SharedChannelSpinPolicy>( buffer: controlChannelMemoryMapView.Buffer, size: (uint)controlChannelMemoryMapView.MemSize, sync: globalMemoryRegion.ControlChannelSynchronization) { ChannelPolicy = { NotificationEvent = controlChannelNamedEvent }, }; // Create the feedback channel instance. // FeedbackChannel = new SharedChannel <InterProcessSharedChannelPolicy, SharedChannelSpinPolicy>( buffer: feedbackChannelMemoryMapView.Buffer, size: (uint)feedbackChannelMemoryMapView.MemSize, sync: globalMemoryRegion.FeedbackChannelSynchronization) { ChannelPolicy = { NotificationEvent = feedbackChannelNamedEvent }, }; }
/// <summary> /// Creates or opens a shared memory region view. /// </summary> /// <param name="sharedMemoryMapName"></param> /// <param name="sharedMemorySize"></param> /// <returns></returns> /// <typeparam name="T">Memory region type.</typeparam> public static SharedMemoryRegionView <T> CreateOrOpen <T>(string sharedMemoryMapName, ulong sharedMemorySize) where T : ICodegenProxy, new() { try { return(new SharedMemoryRegionView <T>(SharedMemoryMapView.Open(sharedMemoryMapName, sharedMemorySize))); } catch (FileNotFoundException) { var memoryRegionView = new SharedMemoryRegionView <T>(SharedMemoryMapView.Create(sharedMemoryMapName, sharedMemorySize)); MlosProxyInternal.MemoryRegionInitializer <T> memoryRegionInitializer = default; memoryRegionInitializer.Initalize(memoryRegionView); return(memoryRegionView); } }
/// <summary> /// Initializes a new instance of the <see cref="InterProcessMlosContext"/> class. /// </summary> /// <returns>InterProcessMlosContext instance.</returns> public static InterProcessMlosContext CreateOrOpen() { // Create or open the memory mapped files. // SharedMemoryRegionView <MlosProxyInternal.GlobalMemoryRegion> globalMemoryRegionView = SharedMemoryRegionView.CreateOrOpen <MlosProxyInternal.GlobalMemoryRegion>(GlobalMemoryMapName, SharedMemorySize); SharedMemoryMapView controlChannelMemoryMapView = SharedMemoryMapView.CreateOrOpen(ControlChannelMemoryMapName, SharedMemorySize); SharedMemoryMapView feedbackChannelMemoryMapView = SharedMemoryMapView.CreateOrOpen(FeedbackChannelMemoryMapName, SharedMemorySize); // Create channel synchronization primitives. // NamedEvent controlChannelNamedEvent = NamedEvent.CreateOrOpen(ControlChannelSemaphoreName); NamedEvent feedbackChannelNamedEvent = NamedEvent.CreateOrOpen(FeedbackChannelSemaphoreName); return(new InterProcessMlosContext( globalMemoryRegionView, controlChannelMemoryMapView, feedbackChannelMemoryMapView, controlChannelNamedEvent, feedbackChannelNamedEvent)); }
/// <summary> /// Registers a shared config memory region created by the target process. /// </summary> /// <param name="sharedMemoryRegionIndex"></param> /// <param name="sharedMemoryMapName"></param> /// <param name="memoryRegionSize"></param> public void RegisterSharedConfigMemoryRegion(uint sharedMemoryRegionIndex, string sharedMemoryMapName, ulong memoryRegionSize) { if (sharedConfigMemoryRegionView != null) { if (sharedConfigMemoryRegionView.MemoryRegion().MemoryHeader.MemoryRegionId.Index == sharedMemoryRegionIndex) { // Shared memory region has been already registered. // return; } else { throw new NotImplementedException("Only a single shared config memory region is currently supported."); } } // Create a shared config memory region. // SharedMemoryMapView sharedConfigMemoryMapView = SharedMemoryMapView.OpenExisting( sharedMemoryMapName, memoryRegionSize); sharedConfigMemoryRegionView = new SharedMemoryRegionView <MlosProxyInternal.SharedConfigMemoryRegion>(sharedConfigMemoryMapView); }
/// <summary> /// Initializes a new instance of the <see cref="InterProcessMlosContext"/> class. /// </summary> /// <param name="globalMemoryRegionView"></param> /// <param name="controlChannelMemoryMapView"></param> /// <param name="feedbackChannelMemoryMapView"></param> /// <param name="controlChannelNamedEvent"></param> /// <param name="feedbackChannelNamedEvent"></param> /// <param name="targetProcessNamedEvent"></param> private InterProcessMlosContext( SharedMemoryRegionView <MlosProxyInternal.GlobalMemoryRegion> globalMemoryRegionView, SharedMemoryMapView controlChannelMemoryMapView, SharedMemoryMapView feedbackChannelMemoryMapView, NamedEvent controlChannelNamedEvent, NamedEvent feedbackChannelNamedEvent, NamedEvent targetProcessNamedEvent) { this.globalMemoryRegionView = globalMemoryRegionView ?? throw new ArgumentNullException(nameof(globalMemoryRegionView)); this.controlChannelMemoryMapView = controlChannelMemoryMapView ?? throw new ArgumentNullException(nameof(controlChannelMemoryMapView)); this.feedbackChannelMemoryMapView = feedbackChannelMemoryMapView ?? throw new ArgumentNullException(nameof(feedbackChannelMemoryMapView)); this.controlChannelNamedEvent = controlChannelNamedEvent ?? throw new ArgumentNullException(nameof(controlChannelNamedEvent)); this.feedbackChannelNamedEvent = feedbackChannelNamedEvent ?? throw new ArgumentNullException(nameof(feedbackChannelNamedEvent)); this.targetProcessNamedEvent = targetProcessNamedEvent ?? throw new ArgumentNullException(nameof(targetProcessNamedEvent)); // Create the shared config manager. // SharedConfigManager = new SharedConfigManager(); MlosProxyInternal.GlobalMemoryRegion globalMemoryRegion = globalMemoryRegionView.MemoryRegion(); // Increase the usage counter. When closing global shared memory, we will decrease the counter. // If there is no process using the shared memory, we will clean the OS resources. On Windows OS, // this is no-op; on Linux, we unlink created files. // globalMemoryRegion.AttachedProcessesCount.FetchAdd(1); // Create the control channel instance. // ControlChannel = new SharedChannel <InterProcessSharedChannelPolicy, SharedChannelSpinPolicy>( buffer: controlChannelMemoryMapView.Buffer, size: (uint)controlChannelMemoryMapView.MemSize, sync: globalMemoryRegion.ControlChannelSynchronization) { ChannelPolicy = { NotificationEvent = controlChannelNamedEvent }, }; // Create the feedback channel instance. // FeedbackChannel = new SharedChannel <InterProcessSharedChannelPolicy, SharedChannelSpinPolicy>( buffer: feedbackChannelMemoryMapView.Buffer, size: (uint)feedbackChannelMemoryMapView.MemSize, sync: globalMemoryRegion.FeedbackChannelSynchronization) { ChannelPolicy = { NotificationEvent = feedbackChannelNamedEvent }, }; // Register config region if available. // if (globalMemoryRegion.TryOpenExisting( new MlosInternal.MemoryRegionId { Type = MlosInternal.MemoryRegionType.SharedConfig, Index = 0, }, out SharedMemoryMapView sharedConfigMemoryMap)) { var sharedMemoryRegionView = new SharedMemoryRegionView <MlosProxyInternal.SharedConfigMemoryRegion>(sharedConfigMemoryMap); SharedConfigManager.RegisterSharedConfigMemoryRegion(sharedMemoryRegionView); } else { sharedConfigMemoryMap?.Dispose(); } }
/// <summary> /// Constructor. /// </summary> /// <param name="sharedMemoryMapView"></param> /// <param name="sync"></param> public SharedChannel(SharedMemoryMapView sharedMemoryMapView, MlosProxy.ChannelSynchronization sync) : this(sharedMemoryMapView.Buffer, (uint)sharedMemoryMapView.MemSize, sync) { }
/// <summary> /// Opens an existing shared memory region view. /// </summary> /// <param name="sharedMemoryMapName"></param> /// <param name="sharedMemorySize"></param> /// <returns></returns> /// <typeparam name="T">Memory region type.</typeparam> public static SharedMemoryRegionView <T> Open <T>(string sharedMemoryMapName, ulong sharedMemorySize) where T : ICodegenProxy, new() { return(new SharedMemoryRegionView <T>(SharedMemoryMapView.Open(sharedMemoryMapName, sharedMemorySize))); }