Common File Mapping Problems and Platform DifferencesLast reviewed: September 25, 1995Article ID: Q125713 |
The information in this article applies to:
SUMMARYThis article addresses some common problems encountered when using file mapping. It also points out some platform differences in the file mapping implementation. This article does not describe the procedures for performing file mapping. For information on using file mapping, please see the File Mapping overview in the Microsoft Win32 Programmer's Reference. Also see the descriptions for CreateFileMapping(), OpenFileMapping(), MapViewOfFile(), MapViewOfFileEx(), UnmapViewOfFile(), and FlushViewOfFile().
MORE INFORMATION
Name Space ConflictsThe names of event, semaphore, mutex, and file-mapping objects share the same name space, so it is not possible to have two different object types with the same name. It is an error to attempt to create or open an object of one type using a name that is already being used by an object of another type. CreateFileMapping() and OpenFileMapping() will fail if they specify an object name that is in use by an object of another type. In both cases, GetLastError() will return ERROR_INVALID_HANDLE (6). To avoid conflicts between object types, one solution is to include the object type in the name. For example, use "EV_myapp_block_ready" for an event object name and "FM_myapp_missile_data" for a file mapping object name.
Necessity of Unmapping All Views of a Mapped FileWindows maintains an internal handle to a file mapping object for each view of that object, whether created by MapViewOfFile() or MapViewOfFileEx(). This internal handle is kept in addition to the handle returned by CreateFileMapping(). The internal handle is not closed until the view associated with the handle is unmapped by calling UnmapViewOfFile(). To completely close a file mapping object requires that all handles for the object, including internal handles, be closed. Thus, to close a file mapping object, all views of that object must be unmapped, and the handle returned by CreateFileMapping() must be closed. Extant unmapped views of a file mapping object will NOT cause a CloseHandle() on the object's handle to fail. In other words, when your handle to the object is closed successfully, it is not necessarily true that all views have been unmapped, so the file mapping object has not necessarily been freed. Failure to properly unmap all views of the object and to close the handle to the object will cause leaks in the application's paged pool, nonpaged pool, virtual bytes, and also in the system wide committed bytes.
Restrictions on the Size of File Mapping ObjectsThe size of a file mapping object backed by the system paging file is limited to available system virtual memory (meaning the amount of memory that could be committed with a call to VirtualAlloc()). On Windows NT, the size of a file mapping object backed by a named disk file is limited by available disk space. The size of a mapped view of an object is limited to the largest contiguous block of unreserved virtual memory in the process performing the mapping (at most, 2GB minus the virtual memory already reserved by the process). On Win32s, the size of a file mapping object backed by a named disk file is limited to available system virtual memory, due to the virtual memory management implementation of Win32s. Win32s allocates regular virtual memory for the memory mapped section even though it does not need swap space, and the amount of VM set by Windows is too small to use for mapping large files. As with Windows NT, available disk space will also impose a limitation. On Windows 95, the size of a file mapping object backed by a named disk file is limited to available disk space. The size of a mapped view of an object is limited to the largest contiguous block of unreserved virtual memory in the shared virtual arena. This block will be at most 1GB, minus any memory in use by other components of Windows 95 which use the shared virtual arena (such as 16-bit Windows-based applications). Each mapped view will use memory from this arena, so this limit applies to the total size of all non-overlapping mapped views for all applications running on the system.
Mapped File May Not be Automatically GrownIf the size specified for a file mapping object backed by a named disk file in a call to CreateFileMapping() is larger than the size of the file used to back the mapping, the file will normally be grown to the specified size by the CreateFileMapping() call. On Windows NT only, if PAGE_WRITECOPY is specified for the fdwProtect parameter, the file will not automatically be grown. This will cause CreateFileMapping() to fail, and GetLastError() will return ERROR_NOT_ENOUGH_MEMORY (8). To set the size of the file before calling CreateFileMapping(), use SetFilePointer() and SetEndOfFile().
MapViewOfFileEx() and Valid Range of lpvBaseOn Windows NT, views of file mapping objects are mapped in the address range of 0-2 GB. Passing an address outside of this range as the lpvBase parameter to MapViewOfFileEx() will cause it to fail, and GetLastError() will return ERROR_INVALID_PARAMETER (87). On Windows 95, views of file mapping objects are mapped in the address range of 2-3 GB (the shared virtual arena). Passing an address outside of this range will cause MapViewOfFileEx() to fail, and GetLastError() will return ERROR_INVALID_ADDRESS (487). Note that future updates to Windows 95 may change the mapping range to 0-2 GB, as on Windows NT.
MapViewOfFileEx() and Allocation Status of lpvBaseIf an address is specified for the lpvBase parameter of MapViewOfFileEx(), and there is not a block of unreserved virtual address space at that address large enough to satisfy the number of bytes specified in the cbMap parameter, then MapViewOfFileEx() will fail, and GetLastError() will return ERROR_NOT_ENOUGH_MEMORY (8). This does not mean that the system is low on memory or that the process cannot allocate more memory. It simply means that the virtual address range requested has already been reserved in that process. Prior to calling MapViewOfFileEx(), VirtualQuery() can be used to determine an appropriate range of unreserved virtual address space.
MapViewOfFileEx() and Granularity of lpvBaseFor the lpvBase parameter specified in a call to MapViewOfFileEx(), you should use an integral multiple of the system's allocation granularity. On Windows NT, not specifying such a value will cause MapViewOfFileEx() to fail, and GetLastError() to return ERROR_MAPPED_ALIGNMENT (1132). On Windows 95, the address is rounded down to the nearest integral multiple of the system's allocation granularity. To determine the system's allocation granularity, call GetSystemInfo().
Addresses of Mapped ViewsWhen mapping a view of a file (or shared memory), it is possible to either let the operating system determine the address of the view, or to specify an address as the lpvBase parameter of the MapViewOfFileEx() function. If the file mapping is going to be shared among multiple processes, then the recommended method is to use MapViewOfFile() and let the operating system select the mapping address for you. There are good reasons for doing so:
When views are mapped to different addresses under Windows NT, the difficulty that arises is storing pointers to the mapping within the mapping itself. This is because a pointer in one process does not point to the same location within the mapping in another process. To overcome this problem, store offsets rather than pointers in the mapping, and calculate actual addresses in each process by adding the base address of the mapping to the offset. It is also possible to used based pointers and thus perform the base + offset conversion implicitly. A short SDK sample called BPOINTER demonstrates this technique.
Additional Platform DifferencesAdditional limitations when performing file mapping under Windows 95:
|
Additional reference words: 1.30 3.50 4.00 95
© 1998 Microsoft Corporation. All rights reserved. Terms of Use. |