/// <summary>Create a syncronized shared memory file</summary> /// <param name="name">The suffix of the shared memory file and semaphore.</param> public ProcessValueCoordinator(string name) { if (String.IsNullOrWhiteSpace(name)) { throw new ArgumentNullException(name); } bool created = false; this.semaphore = new Semaphore(1, 1, SemaphoreName + name, out created); this.sharedMemoryHandle = Win32Native.CreateFileMapping(new SafeFileHandle(IntPtr.Zero, false), IntPtr.Zero, FileMapProtection.PageReadWrite, 0, BufferSize, SharedMemoryName + name); this.sharedMemoryMap = Win32Native.MapViewOfFile(this.sharedMemoryHandle, FileMapAccess.FileMapAllAccess, 0, 0, BufferSize); }
/// <summary>Method to syncronize the shared memory.</summary> /// <typeparam name="T">The TypeOf the value type structure being read/write in shared memory.</typeparam> /// <param name="read">Delegate to read from shared memory.</param> /// <param name="action">Delegate that takes the value read from shared memory and returns the value to write to shared memory.</param> /// <param name="write">Delegate to write to shared memory.</param> /// <param name="offset">Byte offset in the shared memory buffer.</param> /// <returns>The value written to shared memory.</returns> public T Operate <T>(Func <IntPtr, int, T> read, Func <T, T> action, Action <IntPtr, int, T> write, int offset) where T : struct { if ((offset < 0) || (BufferSize < (offset + Marshal.SizeOf(typeof(T))))) { throw new ArgumentOutOfRangeException("offset"); } T current = default(T); Semaphore local = this.semaphore; SafeMapViewOfFileHandle handle = this.sharedMemoryMap; if ((null != local) && (null != handle)) { bool waitSuccess = false; RuntimeHelpers.PrepareConstrainedRegions(); try { if (WaitOne(local, UInt32.MaxValue, ref waitSuccess)) { bool memorySuccess = false; RuntimeHelpers.PrepareConstrainedRegions(); try { handle.DangerousAddRef(ref memorySuccess); IntPtr memory = handle.DangerousGetHandle(); write(memory, offset, current = action(read(memory, offset))); } finally { if (memorySuccess) { handle.DangerousRelease(); } } } } finally { if (waitSuccess) { local.Release(); } } } return(current); }