MemoryMappedFile.cs 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697
  1. //
  2. // MemoryMappedFile.cs
  3. //
  4. // Authors:
  5. // Zoltan Varga ([email protected])
  6. //
  7. // Copyright (C) 2009, Novell, Inc (http://www.novell.com)
  8. //
  9. // Permission is hereby granted, free of charge, to any person obtaining
  10. // a copy of this software and associated documentation files (the
  11. // "Software"), to deal in the Software without restriction, including
  12. // without limitation the rights to use, copy, modify, merge, publish,
  13. // distribute, sublicense, and/or sell copies of the Software, and to
  14. // permit persons to whom the Software is furnished to do so, subject to
  15. // the following conditions:
  16. //
  17. // The above copyright notice and this permission notice shall be
  18. // included in all copies or substantial portions of the Software.
  19. //
  20. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  21. // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  22. // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  23. // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
  24. // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
  25. // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
  26. // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  27. //
  28. #if NET_4_0
  29. using System;
  30. using System.IO;
  31. using System.Collections.Generic;
  32. using Microsoft.Win32.SafeHandles;
  33. using System.Runtime.InteropServices;
  34. #if !MOBILE
  35. using Mono.Unix.Native;
  36. using Mono.Unix;
  37. #else
  38. using System.Runtime.CompilerServices;
  39. #endif
  40. namespace System.IO.MemoryMappedFiles
  41. {
  42. #if !MOBILE
  43. internal static class MemoryMapImpl {
  44. //
  45. // Turns the FileMode into the first half of open(2) flags
  46. //
  47. static OpenFlags ToUnixMode (FileMode mode)
  48. {
  49. switch (mode){
  50. case FileMode.CreateNew:
  51. return OpenFlags.O_CREAT | OpenFlags.O_EXCL;
  52. case FileMode.Create:
  53. return OpenFlags.O_CREAT | OpenFlags.O_TRUNC;
  54. case FileMode.OpenOrCreate:
  55. return OpenFlags.O_CREAT;
  56. case FileMode.Truncate:
  57. return OpenFlags.O_TRUNC;
  58. case FileMode.Append:
  59. return OpenFlags.O_APPEND;
  60. default:
  61. case FileMode.Open:
  62. return 0;
  63. }
  64. }
  65. //
  66. // Turns the MemoryMappedFileAccess into the second half of open(2) flags
  67. //
  68. static OpenFlags ToUnixMode (MemoryMappedFileAccess access)
  69. {
  70. switch (access){
  71. case MemoryMappedFileAccess.CopyOnWrite:
  72. case MemoryMappedFileAccess.ReadWriteExecute:
  73. case MemoryMappedFileAccess.ReadWrite:
  74. return OpenFlags.O_RDWR;
  75. case MemoryMappedFileAccess.Write:
  76. return OpenFlags.O_WRONLY;
  77. case MemoryMappedFileAccess.ReadExecute:
  78. case MemoryMappedFileAccess.Read:
  79. default:
  80. return OpenFlags.O_RDONLY;
  81. }
  82. }
  83. static MmapProts ToUnixProts (MemoryMappedFileAccess access)
  84. {
  85. switch (access){
  86. case MemoryMappedFileAccess.ReadWrite:
  87. return MmapProts.PROT_WRITE | MmapProts.PROT_READ;
  88. case MemoryMappedFileAccess.Write:
  89. return MmapProts.PROT_WRITE;
  90. case MemoryMappedFileAccess.CopyOnWrite:
  91. return MmapProts.PROT_WRITE | MmapProts.PROT_READ;
  92. case MemoryMappedFileAccess.ReadExecute:
  93. return MmapProts.PROT_EXEC;
  94. case MemoryMappedFileAccess.ReadWriteExecute:
  95. return MmapProts.PROT_WRITE | MmapProts.PROT_READ | MmapProts.PROT_EXEC;
  96. case MemoryMappedFileAccess.Read:
  97. default:
  98. return MmapProts.PROT_READ;
  99. }
  100. }
  101. internal static int Open (string path, FileMode mode, ref long capacity, MemoryMappedFileAccess access)
  102. {
  103. if (MonoUtil.IsUnix){
  104. Stat buf;
  105. if (Syscall.stat (path, out buf) == -1)
  106. UnixMarshal.ThrowExceptionForLastError ();
  107. if (capacity == 0) {
  108. // Special files such as FIFOs, sockets, and devices can
  109. // have a size of 0. Specifying a capacity for these
  110. // also makes little sense, so don't do the check if the
  111. // file is one of these.
  112. if (buf.st_size == 0 &&
  113. (buf.st_mode & (FilePermissions.S_IFCHR |
  114. FilePermissions.S_IFBLK |
  115. FilePermissions.S_IFIFO |
  116. FilePermissions.S_IFSOCK)) == 0) {
  117. throw new ArgumentException ("A positive capacity must be specified for a Memory Mapped File backed by an empty file.");
  118. }
  119. capacity = buf.st_size;
  120. } else if (capacity < buf.st_size) {
  121. throw new ArgumentException ("The capacity may not be smaller than the file size.");
  122. }
  123. int fd = Syscall.open (path, ToUnixMode (mode) | ToUnixMode (access), FilePermissions.DEFFILEMODE);
  124. if (fd == -1)
  125. UnixMarshal.ThrowExceptionForLastError ();
  126. return fd;
  127. }
  128. throw new NotImplementedException ();
  129. }
  130. internal static void CloseFD (int fd) {
  131. Syscall.close (fd);
  132. }
  133. internal static void Flush (int fd) {
  134. if (MonoUtil.IsUnix)
  135. Syscall.fsync (fd);
  136. else
  137. throw new NotImplementedException ("Not implemented on Windows");
  138. }
  139. static int pagesize;
  140. internal static unsafe void Map (int file_handle, long offset, ref long size, MemoryMappedFileAccess access, out IntPtr map_addr, out int offset_diff)
  141. {
  142. if (!MonoUtil.IsUnix)
  143. throw new NotImplementedException ("Not implemented on windows.");
  144. if (pagesize == 0)
  145. pagesize = Syscall.getpagesize ();
  146. Stat buf;
  147. Syscall.fstat (file_handle, out buf);
  148. long fsize = buf.st_size;
  149. if (size == 0 || size > fsize)
  150. size = fsize;
  151. // Align offset
  152. long real_offset = offset & ~(pagesize - 1);
  153. offset_diff = (int)(offset - real_offset);
  154. // FIXME: Need to determine the unix fd for the file, Handle is only
  155. // equal to it by accident
  156. //
  157. // The new API no longer uses FileStream everywhere, but exposes instead
  158. // the filename (with one exception), we could move this API to use
  159. // file descriptors instead of the FileStream plus its Handle.
  160. //
  161. map_addr = Syscall.mmap (IntPtr.Zero, (ulong) size,
  162. ToUnixProts (access),
  163. access == MemoryMappedFileAccess.CopyOnWrite ? MmapFlags.MAP_PRIVATE : MmapFlags.MAP_SHARED,
  164. file_handle, real_offset);
  165. if (map_addr == (IntPtr)(-1))
  166. throw new IOException ("mmap failed for fd#" + file_handle + "(" + offset + ", " + size + ")");
  167. }
  168. internal static bool Unmap (IntPtr map_addr, ulong map_size)
  169. {
  170. if (!MonoUtil.IsUnix)
  171. return false;
  172. return Syscall.munmap (map_addr, map_size) == 0;
  173. }
  174. static void ConfigureUnixFD (IntPtr handle, HandleInheritability h)
  175. {
  176. // TODO: Mono.Posix is lacking O_CLOEXEC definitions for fcntl.
  177. }
  178. [DllImport("kernel32", SetLastError = true)]
  179. static extern bool SetHandleInformation (IntPtr hObject, int dwMask, int dwFlags);
  180. static void ConfigureWindowsFD (IntPtr handle, HandleInheritability h)
  181. {
  182. SetHandleInformation (handle, 1 /* FLAG_INHERIT */, h == HandleInheritability.None ? 0 : 1);
  183. }
  184. internal static void ConfigureFD (IntPtr handle, HandleInheritability inheritability)
  185. {
  186. if (MonoUtil.IsUnix)
  187. ConfigureUnixFD (handle, inheritability);
  188. else
  189. ConfigureWindowsFD (handle, inheritability);
  190. }
  191. }
  192. #else
  193. internal static class MemoryMapImpl {
  194. [DllImport ("libc")]
  195. static extern int fsync (int fd);
  196. [DllImport ("libc")]
  197. static extern int close (int fd);
  198. [DllImport ("libc")]
  199. static extern int fcntl (int fd, int cmd, int arg0);
  200. //XXX check if android off_t is 64bits or not. on iOS / darwin it is.
  201. [DllImport ("libc")]
  202. static extern IntPtr mmap (IntPtr addr, IntPtr len, int prot, int flags, int fd, long offset);
  203. [DllImport ("libc")]
  204. static extern int munmap (IntPtr addr, IntPtr size);
  205. [DllImport ("libc", SetLastError=true)]
  206. static extern int open (string path, int flags, int access);
  207. #if MONODROID
  208. [DllImport ("__Internal")]
  209. static extern int monodroid_getpagesize ();
  210. static int getpagesize ()
  211. {
  212. return monodroid_getpagesize ();
  213. }
  214. #else
  215. [DllImport ("libc")]
  216. static extern int getpagesize ();
  217. #endif
  218. [MethodImplAttribute (MethodImplOptions.InternalCall)]
  219. static extern long mono_filesize_from_path (string str);
  220. [MethodImplAttribute (MethodImplOptions.InternalCall)]
  221. static extern long mono_filesize_from_fd (int fd);
  222. //Values valid on iOS/OSX and android ndk r6
  223. const int F_GETFD = 1;
  224. const int F_SETFD = 2;
  225. const int FD_CLOEXEC = 1;
  226. const int DEFFILEMODE = 0x666;
  227. const int O_RDONLY = 0x0;
  228. const int O_WRONLY = 0x1;
  229. const int O_RDWR = 0x2;
  230. const int PROT_READ = 0x1;
  231. const int PROT_WRITE = 0x2;
  232. const int PROT_EXEC = 0x4;
  233. const int MAP_PRIVATE = 0x2;
  234. const int MAP_SHARED = 0x1;
  235. const int EINVAL = 22;
  236. #if MONODROID
  237. const int O_CREAT = 0x040;
  238. const int O_TRUNC = 0x080;
  239. const int O_EXCL = 0x200;
  240. const int ENAMETOOLONG = 63;
  241. #else
  242. /* MONOTOUCH - usr/include/sys/fcntl.h */
  243. const int O_CREAT = 0x0200;
  244. const int O_TRUNC = 0x0400;
  245. const int O_EXCL = 0x0800;
  246. // usr/include/sys/errno.h
  247. const int ENAMETOOLONG = 63;
  248. #endif
  249. static int ToUnixMode (FileMode mode)
  250. {
  251. switch (mode) {
  252. case FileMode.CreateNew:
  253. return O_CREAT | O_EXCL;
  254. case FileMode.Create:
  255. return O_CREAT | O_TRUNC;
  256. case FileMode.OpenOrCreate:
  257. return O_CREAT;
  258. case FileMode.Truncate:
  259. return O_TRUNC;
  260. default:
  261. case FileMode.Open:
  262. return 0;
  263. }
  264. }
  265. //
  266. // Turns the MemoryMappedFileAccess into the second half of open(2) flags
  267. //
  268. static int ToUnixMode (MemoryMappedFileAccess access)
  269. {
  270. switch (access) {
  271. case MemoryMappedFileAccess.CopyOnWrite:
  272. case MemoryMappedFileAccess.ReadWriteExecute:
  273. case MemoryMappedFileAccess.ReadWrite:
  274. return O_RDWR;
  275. case MemoryMappedFileAccess.Write:
  276. return O_WRONLY;
  277. case MemoryMappedFileAccess.ReadExecute:
  278. case MemoryMappedFileAccess.Read:
  279. default:
  280. return O_RDONLY;
  281. }
  282. }
  283. static int ToUnixProts (MemoryMappedFileAccess access)
  284. {
  285. switch (access){
  286. case MemoryMappedFileAccess.ReadWrite:
  287. return PROT_WRITE | PROT_READ;
  288. case MemoryMappedFileAccess.Write:
  289. return PROT_WRITE;
  290. case MemoryMappedFileAccess.CopyOnWrite:
  291. return PROT_WRITE | PROT_READ;
  292. case MemoryMappedFileAccess.ReadExecute:
  293. return PROT_EXEC;
  294. case MemoryMappedFileAccess.ReadWriteExecute:
  295. return PROT_WRITE | PROT_READ | PROT_EXEC;
  296. case MemoryMappedFileAccess.Read:
  297. default:
  298. return PROT_READ;
  299. }
  300. }
  301. static void ThrowErrorFromErrno (int errno)
  302. {
  303. switch (errno) {
  304. case EINVAL: throw new ArgumentException ();
  305. case ENAMETOOLONG: throw new PathTooLongException ();
  306. default: throw new IOException ("Failed with errno " + errno);
  307. }
  308. }
  309. internal static int Open (string path, FileMode mode, ref long capacity, MemoryMappedFileAccess access)
  310. {
  311. long file_size = mono_filesize_from_path (path);
  312. if (file_size < 0)
  313. throw new FileNotFoundException (path);
  314. if (capacity > file_size)
  315. throw new ArgumentException ("capacity");
  316. int fd = open (path, ToUnixMode (mode) | ToUnixMode (access), DEFFILEMODE);
  317. if (fd == -1)
  318. ThrowErrorFromErrno (Marshal.GetLastWin32Error ());
  319. return fd;
  320. }
  321. internal static void CloseFD (int fd)
  322. {
  323. close (fd);
  324. }
  325. internal static void Flush (int fd)
  326. {
  327. fsync (fd);
  328. }
  329. internal static bool Unmap (IntPtr map_addr, ulong map_size)
  330. {
  331. return munmap (map_addr, (IntPtr)map_size) == 0;
  332. }
  333. static int pagesize;
  334. internal static unsafe void Map (int file_handle, long offset, ref long size, MemoryMappedFileAccess access, out IntPtr map_addr, out int offset_diff)
  335. {
  336. if (pagesize == 0)
  337. pagesize = getpagesize ();
  338. long fsize = mono_filesize_from_fd (file_handle);
  339. if (fsize < 0)
  340. throw new FileNotFoundException ();
  341. if (size == 0 || size > fsize)
  342. size = fsize;
  343. // Align offset
  344. long real_offset = offset & ~(pagesize - 1);
  345. offset_diff = (int)(offset - real_offset);
  346. map_addr = mmap (IntPtr.Zero, (IntPtr) size,
  347. ToUnixProts (access),
  348. access == MemoryMappedFileAccess.CopyOnWrite ? MAP_PRIVATE : MAP_SHARED,
  349. file_handle, real_offset);
  350. if (map_addr == (IntPtr)(-1))
  351. throw new IOException ("mmap failed for fd#" + file_handle + "(" + offset + ", " + size + ")");
  352. }
  353. internal static void ConfigureFD (IntPtr handle, HandleInheritability inheritability)
  354. {
  355. int fd = (int)handle;
  356. int flags = fcntl (fd, F_GETFD, 0);
  357. if (inheritability == HandleInheritability.None)
  358. flags &= ~FD_CLOEXEC;
  359. else
  360. flags |= FD_CLOEXEC;
  361. fcntl (fd, F_SETFD, flags);
  362. }
  363. }
  364. #endif
  365. public class MemoryMappedFile : IDisposable {
  366. MemoryMappedFileAccess fileAccess;
  367. string name;
  368. long fileCapacity;
  369. //
  370. // We allow the use of either the FileStream/keepOpen combo
  371. // or a Unix file descriptor. This way we avoid the dependency on
  372. // Mono's io-layer having the Unix file descriptors mapped to
  373. // the same io-layer handle
  374. //
  375. FileStream stream;
  376. bool keepOpen;
  377. int unix_fd;
  378. public static MemoryMappedFile CreateFromFile (string path)
  379. {
  380. return CreateFromFile (path, FileMode.Open, null, 0, MemoryMappedFileAccess.ReadWrite);
  381. }
  382. public static MemoryMappedFile CreateFromFile (string path, FileMode mode)
  383. {
  384. return CreateFromFile (path, mode, null, 0, MemoryMappedFileAccess.ReadWrite);
  385. }
  386. public static MemoryMappedFile CreateFromFile (string path, FileMode mode, string mapName)
  387. {
  388. return CreateFromFile (path, mode, mapName, 0, MemoryMappedFileAccess.ReadWrite);
  389. }
  390. public static MemoryMappedFile CreateFromFile (string path, FileMode mode, string mapName, long capacity)
  391. {
  392. return CreateFromFile (path, mode, mapName, capacity, MemoryMappedFileAccess.ReadWrite);
  393. }
  394. public static MemoryMappedFile CreateFromFile (string path, FileMode mode, string mapName, long capacity, MemoryMappedFileAccess access)
  395. {
  396. if (path == null)
  397. throw new ArgumentNullException ("path");
  398. if (path.Length == 0)
  399. throw new ArgumentException ("path");
  400. if (mapName != null && mapName.Length == 0)
  401. throw new ArgumentException ("mapName");
  402. if (mode == FileMode.Append)
  403. throw new ArgumentException ("mode");
  404. if (capacity < 0)
  405. throw new ArgumentOutOfRangeException ("capacity");
  406. int fd = MemoryMapImpl.Open (path, mode, ref capacity, access);
  407. return new MemoryMappedFile () {
  408. unix_fd = fd,
  409. fileAccess = access,
  410. name = mapName,
  411. fileCapacity = capacity
  412. };
  413. }
  414. #if MOBILE
  415. public static MemoryMappedFile CreateFromFile (FileStream fileStream, string mapName, long capacity, MemoryMappedFileAccess access,
  416. HandleInheritability inheritability,
  417. bool leaveOpen)
  418. #else
  419. [MonoLimitation ("memoryMappedFileSecurity is currently ignored")]
  420. public static MemoryMappedFile CreateFromFile (FileStream fileStream, string mapName, long capacity, MemoryMappedFileAccess access,
  421. MemoryMappedFileSecurity memoryMappedFileSecurity, HandleInheritability inheritability,
  422. bool leaveOpen)
  423. #endif
  424. {
  425. if (fileStream == null)
  426. throw new ArgumentNullException ("fileStream");
  427. if (mapName != null && mapName.Length == 0)
  428. throw new ArgumentException ("mapName");
  429. if ((!MonoUtil.IsUnix && capacity == 0 && fileStream.Length == 0) || (capacity > fileStream.Length))
  430. throw new ArgumentException ("capacity");
  431. MemoryMapImpl.ConfigureFD (fileStream.Handle, inheritability);
  432. return new MemoryMappedFile () {
  433. stream = fileStream,
  434. fileAccess = access,
  435. name = mapName,
  436. fileCapacity = capacity,
  437. keepOpen = leaveOpen
  438. };
  439. }
  440. [MonoLimitation ("CreateNew requires that mapName be a file name on Unix")]
  441. public static MemoryMappedFile CreateNew (string mapName, long capacity)
  442. {
  443. #if MOBILE
  444. return CreateNew (mapName, capacity, MemoryMappedFileAccess.ReadWrite, MemoryMappedFileOptions.DelayAllocatePages, 0);
  445. #else
  446. return CreateNew (mapName, capacity, MemoryMappedFileAccess.ReadWrite, MemoryMappedFileOptions.DelayAllocatePages, null, 0);
  447. #endif
  448. }
  449. [MonoLimitation ("CreateNew requires that mapName be a file name on Unix")]
  450. public static MemoryMappedFile CreateNew (string mapName, long capacity, MemoryMappedFileAccess access)
  451. {
  452. #if MOBILE
  453. return CreateNew (mapName, capacity, access, MemoryMappedFileOptions.DelayAllocatePages, 0);
  454. #else
  455. return CreateNew (mapName, capacity, access, MemoryMappedFileOptions.DelayAllocatePages, null, 0);
  456. #endif
  457. }
  458. #if MOBILE
  459. public static MemoryMappedFile CreateNew (string mapName, long capacity, MemoryMappedFileAccess access,
  460. MemoryMappedFileOptions options,
  461. HandleInheritability handleInheritability)
  462. #else
  463. [MonoLimitation ("CreateNew requires that mapName be a file name on Unix; options and memoryMappedFileSecurity are ignored")]
  464. public static MemoryMappedFile CreateNew (string mapName, long capacity, MemoryMappedFileAccess access,
  465. MemoryMappedFileOptions options, MemoryMappedFileSecurity memoryMappedFileSecurity,
  466. HandleInheritability inheritability)
  467. #endif
  468. {
  469. return CreateFromFile (mapName, FileMode.CreateNew, mapName, capacity, access);
  470. }
  471. [MonoLimitation ("CreateOrOpen requires that mapName be a file name on Unix")]
  472. public static MemoryMappedFile CreateOrOpen (string mapName, long capacity)
  473. {
  474. return CreateOrOpen (mapName, capacity, MemoryMappedFileAccess.ReadWrite);
  475. }
  476. [MonoLimitation ("CreateOrOpen requires that mapName be a file name on Unix")]
  477. public static MemoryMappedFile CreateOrOpen (string mapName, long capacity, MemoryMappedFileAccess access)
  478. {
  479. return CreateFromFile (mapName, FileMode.OpenOrCreate, mapName, capacity, access);
  480. }
  481. [MonoTODO]
  482. #if MOBILE
  483. public static MemoryMappedFile CreateOrOpen (string mapName, long capacity, MemoryMappedFileAccess access, MemoryMappedFileOptions options, HandleInheritability inheritability)
  484. #else
  485. public static MemoryMappedFile CreateOrOpen (string mapName, long capacity, MemoryMappedFileAccess access, MemoryMappedFileOptions options, MemoryMappedFileSecurity memoryMappedFileSecurity, HandleInheritability inheritability)
  486. #endif
  487. {
  488. throw new NotImplementedException ();
  489. }
  490. [MonoTODO]
  491. public static MemoryMappedFile OpenExisting (string mapName)
  492. {
  493. throw new NotImplementedException ();
  494. }
  495. [MonoTODO]
  496. public static MemoryMappedFile OpenExisting (string mapName, MemoryMappedFileRights desiredAccessRights)
  497. {
  498. throw new NotImplementedException ();
  499. }
  500. [MonoTODO]
  501. public static MemoryMappedFile OpenExisting (string mapName, MemoryMappedFileRights desiredAccessRights, HandleInheritability inheritability)
  502. {
  503. throw new NotImplementedException ();
  504. }
  505. public MemoryMappedViewStream CreateViewStream ()
  506. {
  507. return CreateViewStream (0, 0);
  508. }
  509. public MemoryMappedViewStream CreateViewStream (long offset, long size)
  510. {
  511. return CreateViewStream (offset, size, MemoryMappedFileAccess.ReadWrite);
  512. }
  513. public MemoryMappedViewStream CreateViewStream (long offset, long size, MemoryMappedFileAccess access)
  514. {
  515. return new MemoryMappedViewStream (stream != null ? (int)stream.Handle : unix_fd, offset, size, access);
  516. }
  517. public MemoryMappedViewAccessor CreateViewAccessor ()
  518. {
  519. return CreateViewAccessor (0, 0);
  520. }
  521. public MemoryMappedViewAccessor CreateViewAccessor (long offset, long size)
  522. {
  523. return CreateViewAccessor (offset, size, MemoryMappedFileAccess.ReadWrite);
  524. }
  525. public MemoryMappedViewAccessor CreateViewAccessor (long offset, long size, MemoryMappedFileAccess access)
  526. {
  527. int file_handle = stream != null ? (int) stream.Handle : unix_fd;
  528. return new MemoryMappedViewAccessor (file_handle, offset, size, access);
  529. }
  530. MemoryMappedFile ()
  531. {
  532. }
  533. public void Dispose ()
  534. {
  535. Dispose (true);
  536. }
  537. protected virtual void Dispose (bool disposing)
  538. {
  539. if (disposing){
  540. if (stream != null){
  541. if (keepOpen == false)
  542. stream.Close ();
  543. unix_fd = -1;
  544. stream = null;
  545. }
  546. if (unix_fd != -1) {
  547. MemoryMapImpl.CloseFD (unix_fd);
  548. unix_fd = -1;
  549. }
  550. }
  551. }
  552. #if !MOBILE
  553. [MonoTODO]
  554. public MemoryMappedFileSecurity GetAccessControl ()
  555. {
  556. throw new NotImplementedException ();
  557. }
  558. [MonoTODO]
  559. public void SetAccessControl (MemoryMappedFileSecurity memoryMappedFileSecurity)
  560. {
  561. throw new NotImplementedException ();
  562. }
  563. #endif
  564. [MonoTODO]
  565. public SafeMemoryMappedFileHandle SafeMemoryMappedFileHandle {
  566. get {
  567. throw new NotImplementedException ();
  568. }
  569. }
  570. }
  571. }
  572. #endif