/// <summary> /// Blocks if no release is signaled or removes a release signal. Enter a critical section. /// In theory, this method is often called P() [Dijkstra, dutch: passeeren] /// </summary> /// <remarks>This member is thread-safe.</remarks> public void Acquire() { while (true) { //looped 0.5s timeout to make blocked threads abortable. uint res = NTKernel.WaitForSingleObject(handle, interruptReactionTime); try { System.Threading.Thread.Sleep(0); } catch (System.Threading.ThreadInterruptedException e) { if (res == 0) { int previousCount; NTKernel.ReleaseSemaphore(handle, 1, out previousCount); } throw e; } if (res == 0) { return; } if (res != 258) { throw new SemaphoreFailedException(); } } }
/// <summary> /// Instanciate a new Inter-Process semaphore. /// </summary> /// <param name="name">The semaphore's name.</param> /// <param name="initial">The initial count of releases signaled.</param> /// <param name="max">The maximum count of release signaled.</param> /// <param name="interruptReactionTime">The maximum time [ms] needed to react to interrupts.</param> public ProcessSemaphore(string name, int initial, int max, int interruptReactionTime) { this.interruptReactionTime = (uint)interruptReactionTime; this.handle = NTKernel.CreateSemaphore(null, initial, max, name); if (handle == 0) { throw new SemaphoreFailedException(); } }
/// <summary> /// Signals a release and allows a blocked thread to continue. Leave a critical section. /// In theory, this method is often called V() [Dijkstra, dutch: vrijgeven] /// </summary> /// <remarks>This member is thread-safe.</remarks> public void Release() { int previousCount; if (!NTKernel.ReleaseSemaphore(handle, 1, out previousCount)) { throw new SemaphoreFailedException(); } }
/// <summary> /// Blocks if no release is signaled or removes a release signal. Enter a critical section. /// In theory, this method is often called P() [Dijkstra, dutch: passeeren] /// </summary> /// <param name="timeout">The maximum blocking time. Usually an Exceptions is thrown if a timeout exceeds.</param> /// <remarks>This member is thread-safe.</remarks> public void Acquire(TimeSpan timeout) { uint milliseconds = (uint)timeout.TotalMilliseconds; if (NTKernel.WaitForSingleObject(handle, milliseconds) != 0) { throw new SemaphoreFailedException(); } }
public void Dispose() { if (fileMapping != IntPtr.Zero) { if (NTKernel.CloseHandle((uint)fileMapping)) { fileMapping = IntPtr.Zero; } } }
/// <summary> /// Don't forget to dispose this object before destruction. /// </summary> public void Dispose() { if (handle != 0) { if (NTKernel.CloseHandle(handle)) { handle = 0; } } }
public void Dispose() { if (mappedView != IntPtr.Zero) { if (NTKernel.UnmapViewOfFile(mappedView)) { mappedView = IntPtr.Zero; } } }
/// <summary> /// Create a view of the memory mapped file, allowing to read/write bytes. /// </summary> /// <param name="offset">An optional offset to the file.</param> /// <param name="size">The size of the view in terms of bytes.</param> /// <param name="access">Whether you need write access to the view.</param> /// <returns>A MemoryMappedFileView instance representing the view.</returns> public MemoryMappedFileView CreateView(int offset, int size, MemoryMappedFileView.ViewAccess access) { if (this.access == FileAccess.ReadOnly && access == MemoryMappedFileView.ViewAccess.ReadWrite) { throw new ArgumentException("Only read access to views allowed on files without write access", "access"); } if (offset < 0) { throw new ArgumentException("Offset must not be negative", "size"); } if (size < 0) { throw new ArgumentException("Size must not be negative", "size"); } IntPtr mappedView = NTKernel.MapViewOfFile(fileMapping, (uint)access, 0, (uint)offset, (uint)size); return(new MemoryMappedFileView(mappedView, size, access)); }
/// <summary> /// Create a virtual memory mapped file located in the system page file. /// </summary> /// <param name="name">The name of the file. Prefix it with "Global\" or "Local\" to control its scope between NT services and user applications in Terminal Server scenarios.</param> /// <param name="access">Whether you need write access to the file.</param> /// <param name="size">The preferred size of the file in terms of bytes.</param> /// <returns>A MemoryMappedFile instance representing the file.</returns> public static MemoryMappedFile CreateFile(string name, FileAccess access, int size) { if (size < 0) { throw new ArgumentException("Size must not be negative", "size"); } //object descriptor = null; //NTAdvanced.InitializeSecurityDescriptor(out descriptor,1); //NTAdvanced.SetSecurityDescriptorDacl(ref descriptor,true,null,false); //NTKernel.SecurityAttributes sa = new NTKernel.SecurityAttributes(descriptor); IntPtr fileMapping = NTKernel.CreateFileMapping(0xFFFFFFFFu, null, (uint)access, 0, (uint)size, name); if (fileMapping == IntPtr.Zero) { throw new MemoryMappingFailedException(); } return(new MemoryMappedFile(fileMapping, size, access)); }