| @@ -966,16 +966,16 @@ bool File::createSymbolicLink (const File& linkFileToCreate, bool overwriteExist | |||||
| } | } | ||||
| //============================================================================== | //============================================================================== | ||||
| MemoryMappedFile::MemoryMappedFile (const File& file, MemoryMappedFile::AccessMode mode) | |||||
| MemoryMappedFile::MemoryMappedFile (const File& file, MemoryMappedFile::AccessMode mode, bool exclusive) | |||||
| : address (nullptr), range (0, file.getSize()), fileHandle (0) | : address (nullptr), range (0, file.getSize()), fileHandle (0) | ||||
| { | { | ||||
| openInternal (file, mode); | |||||
| openInternal (file, mode, exclusive); | |||||
| } | } | ||||
| MemoryMappedFile::MemoryMappedFile (const File& file, const Range<int64>& fileRange, AccessMode mode) | |||||
| MemoryMappedFile::MemoryMappedFile (const File& file, const Range<int64>& fileRange, AccessMode mode, bool exclusive) | |||||
| : address (nullptr), range (fileRange.getIntersectionWith (Range<int64> (0, file.getSize()))), fileHandle (0) | : address (nullptr), range (fileRange.getIntersectionWith (Range<int64> (0, file.getSize()))), fileHandle (0) | ||||
| { | { | ||||
| openInternal (file, mode); | |||||
| openInternal (file, mode, exclusive); | |||||
| } | } | ||||
| @@ -56,8 +56,13 @@ public: | |||||
| will lazily pull the data into memory when blocks are accessed. | will lazily pull the data into memory when blocks are accessed. | ||||
| If the file can't be opened for some reason, the getData() method will return a null pointer. | If the file can't be opened for some reason, the getData() method will return a null pointer. | ||||
| If exclusive is false then other apps can also open the same memory mapped file and use this | |||||
| mapping as an effective way of communicating. If exclusive is true then the mapped file will | |||||
| be opened exclusively - preventing other apps to access the file which may improve the | |||||
| performance of accessing the file. | |||||
| */ | */ | ||||
| MemoryMappedFile (const File& file, AccessMode mode); | |||||
| MemoryMappedFile (const File& file, AccessMode mode, bool exclusive = false); | |||||
| /** Opens a section of a file and maps it to an area of virtual memory. | /** Opens a section of a file and maps it to an area of virtual memory. | ||||
| @@ -77,7 +82,8 @@ public: | |||||
| */ | */ | ||||
| MemoryMappedFile (const File& file, | MemoryMappedFile (const File& file, | ||||
| const Range<int64>& fileRange, | const Range<int64>& fileRange, | ||||
| AccessMode mode); | |||||
| AccessMode mode, | |||||
| bool exclusive = false); | |||||
| /** Destructor. */ | /** Destructor. */ | ||||
| ~MemoryMappedFile(); | ~MemoryMappedFile(); | ||||
| @@ -106,7 +112,7 @@ private: | |||||
| int fileHandle; | int fileHandle; | ||||
| #endif | #endif | ||||
| void openInternal (const File&, AccessMode); | |||||
| void openInternal (const File&, AccessMode, bool); | |||||
| JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (MemoryMappedFile) | JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (MemoryMappedFile) | ||||
| }; | }; | ||||
| @@ -586,7 +586,7 @@ String SystemStats::getEnvironmentVariable (const String& name, const String& de | |||||
| } | } | ||||
| //============================================================================== | //============================================================================== | ||||
| void MemoryMappedFile::openInternal (const File& file, AccessMode mode) | |||||
| void MemoryMappedFile::openInternal (const File& file, AccessMode mode, bool exclusive) | |||||
| { | { | ||||
| jassert (mode == readOnly || mode == readWrite); | jassert (mode == readOnly || mode == readWrite); | ||||
| @@ -603,7 +603,7 @@ void MemoryMappedFile::openInternal (const File& file, AccessMode mode) | |||||
| { | { | ||||
| void* m = mmap (0, (size_t) range.getLength(), | void* m = mmap (0, (size_t) range.getLength(), | ||||
| mode == readWrite ? (PROT_READ | PROT_WRITE) : PROT_READ, | mode == readWrite ? (PROT_READ | PROT_WRITE) : PROT_READ, | ||||
| MAP_SHARED, fileHandle, | |||||
| exclusive ? MAP_PRIVATE : MAP_SHARED, fileHandle, | |||||
| (off_t) range.getStart()); | (off_t) range.getStart()); | ||||
| if (m != MAP_FAILED) | if (m != MAP_FAILED) | ||||
| @@ -325,7 +325,7 @@ Result FileOutputStream::truncate() | |||||
| } | } | ||||
| //============================================================================== | //============================================================================== | ||||
| void MemoryMappedFile::openInternal (const File& file, AccessMode mode) | |||||
| void MemoryMappedFile::openInternal (const File& file, AccessMode mode, bool exclusive) | |||||
| { | { | ||||
| jassert (mode == readOnly || mode == readWrite); | jassert (mode == readOnly || mode == readWrite); | ||||
| @@ -348,7 +348,8 @@ void MemoryMappedFile::openInternal (const File& file, AccessMode mode) | |||||
| access = FILE_MAP_ALL_ACCESS; | access = FILE_MAP_ALL_ACCESS; | ||||
| } | } | ||||
| HANDLE h = CreateFile (file.getFullPathName().toWideCharPointer(), accessMode, FILE_SHARE_READ, 0, | |||||
| HANDLE h = CreateFile (file.getFullPathName().toWideCharPointer(), accessMode, | |||||
| exclusive ? 0 : (FILE_SHARE_READ | (mode == readWrite ? FILE_SHARE_WRITE : 0)), 0, | |||||
| createType, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN, 0); | createType, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN, 0); | ||||
| if (h != INVALID_HANDLE_VALUE) | if (h != INVALID_HANDLE_VALUE) | ||||