/// <summary> /// Allocate a new entry in epoch table. This is called /// once for a thread. /// </summary> /// <returns>Reserved entry</returns> private static int ReserveEntryForThread() { if (threadId == 0) // run once per thread for performance { // For portability (run on non-windows platform) threadId = Environment.OSVersion.Platform == PlatformID.Win32NT ? (int)Native32.GetCurrentThreadId() : Thread.CurrentThread.ManagedThreadId; threadIdHash = Utility.Murmur3(threadId); } return(ReserveEntry(threadIdHash, threadId)); }
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); } }
/// <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) { 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); } try { ThreadPool.BindHandle(logHandle); } catch (Exception e) { throw new FasterException("Error binding log handle for " + GetSegmentName(fileName, segmentId) + ": " + e.ToString()); } return(logHandle); }
public void Close() { Native32.CloseHandle(logHandle); }
/// <summary> /// Allocate a new entry in epoch table. This is called /// once for a thread. /// </summary> /// <returns>Reserved entry</returns> private int ReserveEntryForThread() { // for portability(run on non-windows platform) int threadId = Environment.OSVersion.Platform == PlatformID.Win32NT ? (int)Native32.GetCurrentThreadId() : Thread.CurrentThread.ManagedThreadId; int startIndex = Utility.Murmur3(threadId); return(ReserveEntry(startIndex, threadId)); }