Beispiel #1
0
        /// <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;
        }
Beispiel #2
0
        /// <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));
        }
Beispiel #3
0
 /// <summary>
 /// Tries to open an exiting named event.
 /// </summary>
 /// <param name="name"></param>
 /// <param name="namedEvent"></param>
 /// <returns></returns>
 public static bool TryOpenExisting(string name, out NamedEvent namedEvent)
 {
     if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
     {
         return(Windows.NamedEvent.TryOpenExisting(name, out namedEvent));
     }
     else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
     {
         return(Linux.NamedSemaphore.TryOpenExisting(name, out namedEvent));
     }
     else
     {
         throw new InvalidOperationException("Unsupported OS.");
     }
 }
Beispiel #4
0
        /// <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 },
            };
        }
Beispiel #5
0
        /// <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>
        /// Initializes a new instance of the <see cref="InterProcessMlosContext"/> class.
        /// </summary>
        /// <returns>InterProcessMlosContext instance.</returns>
        public static InterProcessMlosContext Create()
        {
            var targetProcessNamedEvent = NamedEvent.CreateOrOpen(TargetProcessEventName);
            {
                bool shouldWaitForTargetProcess = false;

                try
                {
                    // Try open a global shared memory and check if the target process is fully initialized.
                    //
                    using var targetProcessMemoryRegionView = SharedMemoryRegionView.OpenExisting <MlosProxyInternal.GlobalMemoryRegion>(GlobalMemoryMapName, MlosInternal.GlobalMemoryRegion.GlobalSharedMemorySize);

                    // If RegisteredSettingsAssemblyCount is 0, the context is not created.
                    //
                    if (targetProcessMemoryRegionView.MemoryRegion().RegisteredSettingsAssemblyCount.Load() == 0)
                    {
                        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();
                }
            }

            // Open global memory region.
            //
            var globalMemoryRegionView            = SharedMemoryRegionView.OpenExisting <MlosProxyInternal.GlobalMemoryRegion>(GlobalMemoryMapName, MlosInternal.GlobalMemoryRegion.GlobalSharedMemorySize);
            GlobalMemoryRegion globalMemoryRegion = globalMemoryRegionView.MemoryRegion();

            // Open existing shared channels memory maps.
            //
            globalMemoryRegion.TryOpenExisting(
                new MlosInternal.MemoryRegionId {
                Type = MlosInternal.MemoryRegionType.ControlChannel, Index = 0,
            },
                out SharedMemoryMapView controlChannelMemoryMapView);

            globalMemoryRegion.TryOpenExisting(
                new MlosInternal.MemoryRegionId {
                Type = MlosInternal.MemoryRegionType.FeedbackChannel, Index = 0,
            },
                out SharedMemoryMapView feedbackChannelMemoryMapView);

            // Open existing channel synchronization primitives.
            //
            globalMemoryRegion.TryOpenExisting(
                new MlosInternal.MemoryRegionId {
                Type = MlosInternal.MemoryRegionType.ControlChannel, Index = 0,
            },
                out NamedEvent controlChannelNamedEvent);

            globalMemoryRegion.TryOpenExisting(
                new MlosInternal.MemoryRegionId {
                Type = MlosInternal.MemoryRegionType.FeedbackChannel, Index = 0,
            },
                out NamedEvent feedbackChannelNamedEvent);

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