Пример #1
0
        /// <summary>
        /// Sets the <see cref="ShuttingDown"/> flag, and disposes of the <see cref="MemoryMappedFile"/> and <see cref="MemoryMappedViewAccessor"/>.
        /// Attempting to read/write to the buffer after closing will result in a <see cref="NullReferenceException"/>.
        /// </summary>
        public virtual void Close()
        {
            if (IsOwnerOfSharedMemory && View != null)
            {
                // Indicates to any open instances that the owner is no longer open
#pragma warning disable 0420 // ignore ref to volatile warning - Interlocked API
                Interlocked.Exchange(ref Header->Shutdown, 1);
#pragma warning restore 0420
            }

            // Allow additional close logic
            DoClose();

            // Close the MemoryMappedFile and MemoryMappedViewAccessor
            if (View != null)
            {
                View.SafeMemoryMappedViewHandle.ReleasePointer();
                View.Dispose();
            }

            if (Mmf != null)
            {
                Mmf.Dispose();
            }

            Header         = null;
            ViewPtr        = null;
            BufferStartPtr = null;
            View           = null;
            Mmf            = null;
        }
Пример #2
0
        /// <summary>
        /// Creates a new or opens an existing shared memory buffer with the name of <see cref="Name"/> depending on the value of <see cref="IsOwnerOfSharedMemory"/>.
        /// </summary>
        /// <exception cref="System.IO.IOException">Trying to create a new shared memory buffer with a duplicate name as buffer owner.</exception>
        /// <exception cref="System.IO.FileNotFoundException">Trying to open a new shared memory buffer that does not exist as a consumer of existing buffer.</exception>
        /// <exception cref="System.ArgumentOutOfRangeException">Trying to create a new shared memory buffer with a size larger than the logical addressable space.</exception>
        /// <returns>`true` if the memory was successfully mapped. Otherwise, `false`.</returns>
        /// <remarks>
        /// If <see cref="IsOwnerOfSharedMemory"/> is `true`, the shared memory buffer will be created. Opening will fail in this case if the shared memory already
        /// exists. Otherwise, if <see cref="IsOwnerOfSharedMemory"/> is `false`, the shared memory buffer will be opened, which will fail if it doesn't already exist.
        /// </remarks>
        protected bool Open()
        {
            Close();

            try
            {
                // Attempts to create or open the shared memory with a name of this.Name
                if (IsOwnerOfSharedMemory)
                {
                    // Create a new shared memory mapping
                    Mmf = MemoryMappedFile.CreateNew(Name, SharedMemorySize);

                    // Create a view to the entire region of the shared memory
                    View = Mmf.CreateViewAccessor(0, SharedMemorySize, MemoryMappedFileAccess.ReadWrite);
                    View.SafeMemoryMappedViewHandle.AcquirePointer(ref ViewPtr);
                    Header         = (SharedBufferHeader *)(ViewPtr + HeaderOffset);
                    BufferStartPtr = ViewPtr + BufferOffset;
                    // Initialise the header
                    InitializeHeader();
                }
                else
                {
                    // Open an existing shared memory mapping
                    Mmf = MemoryMappedFile.OpenExisting(Name);

                    // Retrieve the header from the shared memory in order to initialise the correct size
                    using (var headerView = Mmf.CreateViewAccessor(0, HeaderOffset + Polyfill.GetMarshalSizeOf <SharedBufferHeader>(), MemoryMappedFileAccess.Read))
                    {
                        byte *headerPtr = null;
                        headerView.SafeMemoryMappedViewHandle.AcquirePointer(ref headerPtr);
                        var header = (SharedBufferHeader *)(headerPtr + HeaderOffset);
                        BufferSize = header->SharedMemorySize - Polyfill.GetMarshalSizeOf <SharedBufferHeader>();
                        headerView.SafeMemoryMappedViewHandle.ReleasePointer();
                    }

                    // Create a view to the entire region of the shared memory
                    View = Mmf.CreateViewAccessor(0, SharedMemorySize, MemoryMappedFileAccess.ReadWrite);
                    View.SafeMemoryMappedViewHandle.AcquirePointer(ref ViewPtr);
                    Header         = (SharedBufferHeader *)(ViewPtr + HeaderOffset);
                    BufferStartPtr = ViewPtr + HeaderOffset + Polyfill.GetMarshalSizeOf <SharedBufferHeader>();
                }
            }
            catch
            {
                Close();
                throw;
            }

            // Complete any additional open logic
            try
            {
                if (!DoOpen())
                {
                    Close();
                    return(false);
                }
                else
                {
                    return(true);
                }
            }
            catch
            {
                Close();
                throw;
            }
        }