Terraria v1.4.4.9
Terraria source code documentation
Loading...
Searching...
No Matches
MemoryMappedView.cs
Go to the documentation of this file.
4
6
7internal sealed class MemoryMappedView : IDisposable
8{
10
11 private readonly long _pointerOffset;
12
13 private readonly long _size;
14
16
18
20
21 public long Size => _size;
22
24
26
27 private MemoryMappedView(SafeMemoryMappedViewHandle viewHandle, long pointerOffset, long size, MemoryMappedFileAccess access)
28 {
29 _viewHandle = viewHandle;
30 _pointerOffset = pointerOffset;
31 _size = size;
32 _access = access;
33 }
34
35 private void Dispose(bool disposing)
36 {
38 {
40 }
41 }
42
43 public void Dispose()
44 {
45 Dispose(disposing: true);
46 GC.SuppressFinalize(this);
47 }
48
49 private static void ValidateSizeAndOffset(long size, long offset, long allocationGranularity, out ulong newSize, out long extraMemNeeded, out long newOffset)
50 {
51 extraMemNeeded = offset % allocationGranularity;
52 newOffset = offset - extraMemNeeded;
53 newSize = (ulong)((size != 0L) ? (size + extraMemNeeded) : 0);
54 if (IntPtr.Size == 4 && newSize > uint.MaxValue)
55 {
57 }
58 }
59
60 public static MemoryMappedView CreateView(SafeMemoryMappedFileHandle memMappedFileHandle, MemoryMappedFileAccess access, long offset, long size)
61 {
62 ValidateSizeAndOffset(size, offset, GetSystemPageAllocationGranularity(), out var newSize, out var extraMemNeeded, out var newOffset);
63 global::Interop.CheckForAvailableVirtualMemory(newSize);
64 SafeMemoryMappedViewHandle safeMemoryMappedViewHandle = global::Interop.MapViewOfFile(memMappedFileHandle, MemoryMappedFile.GetFileMapAccess(access), newOffset, new UIntPtr(newSize));
65 if (safeMemoryMappedViewHandle.IsInvalid)
66 {
67 safeMemoryMappedViewHandle.Dispose();
69 }
70 global::Interop.Kernel32.MEMORY_BASIC_INFORMATION lpBuffer = default(global::Interop.Kernel32.MEMORY_BASIC_INFORMATION);
71 global::Interop.Kernel32.VirtualQuery(safeMemoryMappedViewHandle, ref lpBuffer, (UIntPtr)(ulong)Marshal.SizeOf(lpBuffer));
72 ulong num = (ulong)lpBuffer.RegionSize;
73 if ((lpBuffer.State & 0x2000u) != 0 || num < newSize)
74 {
75 IntPtr intPtr = global::Interop.VirtualAlloc(safeMemoryMappedViewHandle, (UIntPtr)((newSize != 0L) ? newSize : num), 4096, MemoryMappedFile.GetPageAccess(access));
76 int lastPInvokeError = Marshal.GetLastPInvokeError();
77 if (safeMemoryMappedViewHandle.IsInvalid)
78 {
79 safeMemoryMappedViewHandle.Dispose();
80 throw System.IO.Win32Marshal.GetExceptionForWin32Error(lastPInvokeError);
81 }
82 lpBuffer = default(global::Interop.Kernel32.MEMORY_BASIC_INFORMATION);
83 global::Interop.Kernel32.VirtualQuery(safeMemoryMappedViewHandle, ref lpBuffer, (UIntPtr)(ulong)Marshal.SizeOf(lpBuffer));
84 num = (ulong)lpBuffer.RegionSize;
85 }
86 if (size == 0L)
87 {
88 size = (long)num - extraMemNeeded;
89 }
90 safeMemoryMappedViewHandle.Initialize((ulong)(size + extraMemNeeded));
91 return new MemoryMappedView(safeMemoryMappedViewHandle, extraMemNeeded, size, access);
92 }
93
94 public unsafe void Flush(UIntPtr capacity)
95 {
96 byte* pointer = null;
97 try
98 {
100 if (global::Interop.Kernel32.FlushViewOfFile((IntPtr)pointer, capacity))
101 {
102 return;
103 }
104 int lastPInvokeError = Marshal.GetLastPInvokeError();
105 if (lastPInvokeError != 33)
106 {
107 throw System.IO.Win32Marshal.GetExceptionForWin32Error(lastPInvokeError);
108 }
109 SpinWait spinWait = default(SpinWait);
110 for (int i = 0; i < 15; i++)
111 {
112 int millisecondsTimeout = 1 << i;
114 for (int j = 0; j < 20; j++)
115 {
116 if (global::Interop.Kernel32.FlushViewOfFile((IntPtr)pointer, capacity))
117 {
118 return;
119 }
120 lastPInvokeError = Marshal.GetLastPInvokeError();
121 if (lastPInvokeError != 33)
122 {
123 throw System.IO.Win32Marshal.GetExceptionForWin32Error(lastPInvokeError);
124 }
125 spinWait.SpinOnce();
126 }
127 }
128 throw System.IO.Win32Marshal.GetExceptionForWin32Error(lastPInvokeError);
129 }
130 finally
131 {
132 if (pointer != null)
133 {
135 }
136 }
137 }
138
140 {
141 global::Interop.Kernel32.GetSystemInfo(out var lpSystemInfo);
142 return lpSystemInfo.dwAllocationGranularity;
143 }
144}
static void SuppressFinalize(object obj)
Definition GC.cs:202
Definition GC.cs:8
static int GetFileMapAccess(MemoryMappedFileRights rights)
static int GetPageAccess(MemoryMappedFileAccess access)
static void ValidateSizeAndOffset(long size, long offset, long allocationGranularity, out ulong newSize, out long extraMemNeeded, out long newOffset)
MemoryMappedView(SafeMemoryMappedViewHandle viewHandle, long pointerOffset, long size, MemoryMappedFileAccess access)
readonly MemoryMappedFileAccess _access
static MemoryMappedView CreateView(SafeMemoryMappedFileHandle memMappedFileHandle, MemoryMappedFileAccess access, long offset, long size)
readonly SafeMemoryMappedViewHandle _viewHandle
static Exception GetExceptionForLastWin32Error(string path="")
static Exception GetExceptionForWin32Error(int errorCode, string path="")
static int SizeOf(object structure)
Definition Marshal.cs:697
unsafe void AcquirePointer(ref byte *pointer)
Definition SafeBuffer.cs:58
static string ArgumentOutOfRange_CapacityLargerThanLogicalAddressSpaceNotAllowed
Definition SR.cs:54
Definition SR.cs:7
static void Sleep(int millisecondsTimeout)
Definition Thread.cs:658
static int Size
Definition IntPtr.cs:21