private SafeFileHandle CreateHandle(int segmentId) { uint fileAccess = Native32.GENERIC_READ | Native32.GENERIC_WRITE; uint fileShare = unchecked (((uint)FileShare.ReadWrite & ~(uint)FileShare.Inheritable)); uint fileCreation = unchecked ((uint)FileMode.OpenOrCreate); uint fileFlags = Native32.FILE_FLAG_OVERLAPPED; fileFlags = fileFlags | Native32.FILE_FLAG_NO_BUFFERING; if (deleteOnClose) { fileFlags = fileFlags | Native32.FILE_FLAG_DELETE_ON_CLOSE; } var logHandle = Native32.CreateFileW( GetSegmentName(segmentId), fileAccess, fileShare, IntPtr.Zero, fileCreation, fileFlags, IntPtr.Zero); if (preallocateSegment) { SetFileSize(FileName, logHandle, SegmentSize); } try { ThreadPool.BindHandle(logHandle); } catch (Exception e) { throw new Exception("Error binding log handle for " + GetSegmentName(segmentId) + ": " + e.ToString()); } return(logHandle); }
/// <summary> /// Creates a SafeFileHandle for the specified segment. This can be used by derived classes to prepopulate logHandles in the constructor. /// </summary> protected internal static SafeFileHandle CreateHandle(int segmentId, bool disableFileBuffering, bool deleteOnClose, bool preallocateFile, long segmentSize, string fileName, IntPtr ioCompletionPort) { uint fileAccess = Native32.GENERIC_READ | Native32.GENERIC_WRITE; uint fileShare = unchecked (((uint)FileShare.ReadWrite & ~(uint)FileShare.Inheritable)); uint fileCreation = unchecked ((uint)FileMode.OpenOrCreate); uint fileFlags = Native32.FILE_FLAG_OVERLAPPED; if (disableFileBuffering) { fileFlags = fileFlags | Native32.FILE_FLAG_NO_BUFFERING; } if (deleteOnClose) { fileFlags = fileFlags | Native32.FILE_FLAG_DELETE_ON_CLOSE; // FILE_SHARE_DELETE allows multiple FASTER instances to share a single log directory and each can specify deleteOnClose. // This will allow the files to persist until all handles across all instances have been closed. fileShare = fileShare | Native32.FILE_SHARE_DELETE; } var logHandle = Native32.CreateFileW( GetSegmentName(fileName, segmentId), fileAccess, fileShare, IntPtr.Zero, fileCreation, fileFlags, IntPtr.Zero); if (logHandle.IsInvalid) { var error = Marshal.GetLastWin32Error(); throw new IOException($"Error creating log file for {GetSegmentName(fileName, segmentId)}, error: {error}", Native32.MakeHRFromErrorCode(error)); } if (preallocateFile && segmentSize != -1) { SetFileSize(fileName, logHandle, segmentSize); } if (ioCompletionPort != IntPtr.Zero) { ThreadPool.GetMaxThreads(out int workerThreads, out _); Native32.CreateIoCompletionPort(logHandle, ioCompletionPort, (UIntPtr)(long)logHandle.DangerousGetHandle(), (uint)(workerThreads + NumCompletionThreads)); } else { try { ThreadPool.BindHandle(logHandle); } catch (Exception e) { throw new FasterException("Error binding log handle for " + GetSegmentName(fileName, segmentId) + ": " + e.ToString()); } } return(logHandle); }
private SafeFileHandle GetOrAddHandle(int _segmentId) { return(logHandles.GetOrAdd(_segmentId, segmentId => { uint fileAccess = Native32.GENERIC_READ | Native32.GENERIC_WRITE; uint fileShare = unchecked (((uint)FileShare.ReadWrite & ~(uint)FileShare.Inheritable)); uint fileCreation = unchecked ((uint)FileMode.OpenOrCreate); uint fileFlags = Native32.FILE_FLAG_OVERLAPPED; if (unbuffered) { fileFlags = fileFlags | Native32.FILE_FLAG_NO_BUFFERING; } if (deleteOnClose) { fileFlags = fileFlags | Native32.FILE_FLAG_DELETE_ON_CLOSE; } var logHandle = Native32.CreateFileW( GetSegmentName(segmentId), fileAccess, fileShare, IntPtr.Zero, fileCreation, fileFlags, IntPtr.Zero); if (enablePrivileges) { Native32.EnableVolumePrivileges(ref dirname, logHandle); } SetFileSize(logHandle, segmentSize); if (useIoCompletionPort) { ioCompletionPort = Native32.CreateIoCompletionPort( logHandle, IntPtr.Zero, (uint)logHandle.DangerousGetHandle().ToInt64(), 0); } try { ThreadPool.BindHandle(logHandle); } catch (Exception e) { Console.WriteLine("Log handle! : {0}", logHandle.ToString()); Console.WriteLine(e.ToString()); Environment.Exit(0); } return logHandle; })); }
private SafeFileHandle CreateHandle(int segmentId) { uint fileAccess = Native32.GENERIC_READ | Native32.GENERIC_WRITE; uint fileShare = unchecked (((uint)FileShare.ReadWrite & ~(uint)FileShare.Inheritable)); uint fileCreation = unchecked ((uint)FileMode.OpenOrCreate); uint fileFlags = Native32.FILE_FLAG_OVERLAPPED; if (this.disableFileBuffering) { fileFlags = fileFlags | Native32.FILE_FLAG_NO_BUFFERING; } if (deleteOnClose) { fileFlags = fileFlags | Native32.FILE_FLAG_DELETE_ON_CLOSE; // FILE_SHARE_DELETE allows multiple FASTER instances to share a single log directory and each can specify deleteOnClose. // This will allow the files to persist until all handles across all instances have been closed. fileShare = fileShare | Native32.FILE_SHARE_DELETE; } var logHandle = Native32.CreateFileW( GetSegmentName(segmentId), fileAccess, fileShare, IntPtr.Zero, fileCreation, fileFlags, IntPtr.Zero); if (logHandle.IsInvalid) { var error = Marshal.GetLastWin32Error(); throw new IOException($"Error creating log file for {GetSegmentName(segmentId)}, error: {error}", Native32.MakeHRFromErrorCode(error)); } if (preallocateFile) { SetFileSize(FileName, logHandle, segmentSize); } try { ThreadPool.BindHandle(logHandle); } catch (Exception e) { throw new Exception("Error binding log handle for " + GetSegmentName(segmentId) + ": " + e.ToString()); } return(logHandle); }
public LocalStorageDevice(string filename, bool enablePrivileges = false, bool useIoCompletionPort = false, bool unbuffered = false, bool deleteOnClose = false) { this.filename = filename; this.enablePrivileges = enablePrivileges; this.useIoCompletionPort = useIoCompletionPort; if (enablePrivileges) { Native32.EnableProcessPrivileges(); } Native32.GetDiskFreeSpace(filename.Substring(0, 3), out lpSectorsPerCluster, out lpBytesPerSector, out lpNumberOfFreeClusters, out lpTotalNumberOfClusters); uint fileAccess = Native32.GENERIC_READ | Native32.GENERIC_WRITE; uint fileShare = unchecked (((uint)FileShare.ReadWrite & ~(uint)FileShare.Inheritable)); uint fileCreation = unchecked ((uint)FileMode.OpenOrCreate); uint fileFlags = Native32.FILE_FLAG_OVERLAPPED; if (unbuffered) { fileFlags = fileFlags | Native32.FILE_FLAG_NO_BUFFERING; } if (deleteOnClose) { fileFlags = fileFlags | Native32.FILE_FLAG_DELETE_ON_CLOSE; } logHandle = Native32.CreateFileW(filename, fileAccess, fileShare, IntPtr.Zero, fileCreation, fileFlags, IntPtr.Zero); if (enablePrivileges) { Native32.EnableVolumePrivileges(ref filename, logHandle); } if (useIoCompletionPort) { ioCompletionPort = Native32.CreateIoCompletionPort( logHandle, IntPtr.Zero, (uint)logHandle.DangerousGetHandle().ToInt64(), 0); } try { ThreadPool.BindHandle(logHandle); } catch (Exception e) { Console.WriteLine("Log handle! : {0}", logHandle.ToString()); Console.WriteLine(e.ToString()); Environment.Exit(0); } }