From 512c2284cafb3eb23d06fc5cdc4e424b711a04b7 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Jo=C3=A3o=20Abecasis?= Date: Wed, 7 Oct 2009 17:42:39 +0200 Subject: [PATCH] (Windows) Don't create a file mapping for each view that is mapped Creating a file mapping for each view mapped to memory is sub-optimal and slow. With this change, a single mapping is created and reused when mapping subsequent views of the file. The handle returned from CreateFileForMapping (used in WinCE 5) is now discarded, since the kernel manages it automatically with the file mapping. This simplifies use of the deprecated map API. Reviewed-by: Maurice Kalinowski Reviewed-by: Marius Storm-Olsen --- src/corelib/io/qfsfileengine.cpp | 4 +- src/corelib/io/qfsfileengine_p.h | 8 +--- src/corelib/io/qfsfileengine_win.cpp | 84 +++++++++++++----------------------- 3 files changed, 34 insertions(+), 62 deletions(-) diff --git a/src/corelib/io/qfsfileengine.cpp b/src/corelib/io/qfsfileengine.cpp index fb096a77f8..2c5451dfd9 100644 --- a/src/corelib/io/qfsfileengine.cpp +++ b/src/corelib/io/qfsfileengine.cpp @@ -122,11 +122,9 @@ void QFSFileEnginePrivate::init() #ifdef Q_OS_WIN fileAttrib = INVALID_FILE_ATTRIBUTES; fileHandle = INVALID_HANDLE_VALUE; + mapHandle = INVALID_HANDLE_VALUE; cachedFd = -1; #endif -#ifdef Q_USE_DEPRECATED_MAP_API - fileMapHandle = INVALID_HANDLE_VALUE; -#endif } /*! diff --git a/src/corelib/io/qfsfileengine_p.h b/src/corelib/io/qfsfileengine_p.h index ee127c1313..87f0737c1e 100644 --- a/src/corelib/io/qfsfileengine_p.h +++ b/src/corelib/io/qfsfileengine_p.h @@ -110,7 +110,8 @@ public: FILE *fh; #ifdef Q_WS_WIN HANDLE fileHandle; - QHash > maps; + HANDLE mapHandle; + QHash maps; mutable int cachedFd; mutable DWORD fileAttrib; #else @@ -119,11 +120,6 @@ public: #endif int fd; -#ifdef Q_USE_DEPRECATED_MAP_API - void mapHandleClose(); - HANDLE fileMapHandle; -#endif - enum LastIOCommand { IOFlushCommand, diff --git a/src/corelib/io/qfsfileengine_win.cpp b/src/corelib/io/qfsfileengine_win.cpp index 898447cc2e..151eabd7fa 100644 --- a/src/corelib/io/qfsfileengine_win.cpp +++ b/src/corelib/io/qfsfileengine_win.cpp @@ -455,17 +455,10 @@ bool QFSFileEnginePrivate::nativeClose() // Windows native mode. bool ok = true; - if ((fileHandle == INVALID_HANDLE_VALUE || !CloseHandle(fileHandle)) -#ifdef Q_USE_DEPRECATED_MAP_API - && (fileMapHandle == INVALID_HANDLE_VALUE || !CloseHandle(fileMapHandle)) -#endif - ) { + if ((fileHandle == INVALID_HANDLE_VALUE || !::CloseHandle(fileHandle))) { q->setError(QFile::UnspecifiedError, qt_error_string()); ok = false; } -#ifdef Q_USE_DEPRECATED_MAP_API - fileMapHandle = INVALID_HANDLE_VALUE; -#endif fileHandle = INVALID_HANDLE_VALUE; cachedFd = -1; // gets closed by CloseHandle above @@ -1931,42 +1924,42 @@ uchar *QFSFileEnginePrivate::map(qint64 offset, qint64 size, return 0; } + if (mapHandle == INVALID_HANDLE_VALUE) { + // get handle to the file + HANDLE handle = fileHandle; - // get handle to the file - HANDLE handle = fileHandle; #ifndef Q_OS_WINCE - if (handle == INVALID_HANDLE_VALUE && fh) - handle = (HANDLE)_get_osfhandle(QT_FILENO(fh)); + if (handle == INVALID_HANDLE_VALUE && fh) + handle = (HANDLE)::_get_osfhandle(QT_FILENO(fh)); #endif #ifdef Q_USE_DEPRECATED_MAP_API - if (fileMapHandle == INVALID_HANDLE_VALUE) { nativeClose(); - fileMapHandle = CreateFileForMapping((const wchar_t*)nativeFilePath.constData(), + // handle automatically closed by kernel with mapHandle (below). + handle = ::CreateFileForMapping((const wchar_t*)nativeFilePath.constData(), GENERIC_READ | (openMode & QIODevice::WriteOnly ? GENERIC_WRITE : 0), 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); - } - handle = fileMapHandle; #endif - if (handle == INVALID_HANDLE_VALUE) { - q->setError(QFile::PermissionsError, qt_error_string(ERROR_ACCESS_DENIED)); - return 0; - } + if (handle == INVALID_HANDLE_VALUE) { + q->setError(QFile::PermissionsError, qt_error_string(ERROR_ACCESS_DENIED)); + return 0; + } - // first create the file mapping handle - DWORD protection = (openMode & QIODevice::WriteOnly) ? PAGE_READWRITE : PAGE_READONLY; - HANDLE mapHandle = ::CreateFileMapping(handle, 0, protection, 0, 0, 0); - if (mapHandle == NULL) { - q->setError(QFile::PermissionsError, qt_error_string()); + // first create the file mapping handle + DWORD protection = (openMode & QIODevice::WriteOnly) ? PAGE_READWRITE : PAGE_READONLY; + mapHandle = ::CreateFileMapping(handle, 0, protection, 0, 0, 0); + if (mapHandle == INVALID_HANDLE_VALUE) { + q->setError(QFile::PermissionsError, qt_error_string()); #ifdef Q_USE_DEPRECATED_MAP_API - mapHandleClose(); + ::CloseHandle(handle); #endif - return 0; + return 0; + } } // setup args to map @@ -1978,17 +1971,17 @@ uchar *QFSFileEnginePrivate::map(qint64 offset, qint64 size, DWORD offsetLo = offset & Q_UINT64_C(0xffffffff); SYSTEM_INFO sysinfo; ::GetSystemInfo(&sysinfo); - int mask = sysinfo.dwAllocationGranularity - 1; - int extra = offset & mask; + DWORD mask = sysinfo.dwAllocationGranularity - 1; + DWORD extra = offset & mask; if (extra) offsetLo &= ~mask; // attempt to create the map - LPVOID mapAddress = MapViewOfFile(mapHandle, access, + LPVOID mapAddress = ::MapViewOfFile(mapHandle, access, offsetHi, offsetLo, size + extra); if (mapAddress) { uchar *address = extra + static_cast(mapAddress); - maps[address] = QPair(extra, mapHandle); + maps[address] = extra; return address; } @@ -2001,10 +1994,8 @@ uchar *QFSFileEnginePrivate::map(qint64 offset, qint64 size, default: q->setError(QFile::UnspecifiedError, qt_error_string()); } - CloseHandle(mapHandle); -#ifdef Q_USE_DEPRECATED_MAP_API - mapHandleClose(); -#endif + + ::CloseHandle(mapHandle); return 0; } @@ -2015,32 +2006,19 @@ bool QFSFileEnginePrivate::unmap(uchar *ptr) q->setError(QFile::PermissionsError, qt_error_string(ERROR_ACCESS_DENIED)); return false; } - uchar *start = ptr - maps[ptr].first; + uchar *start = ptr - maps[ptr]; if (!UnmapViewOfFile(start)) { q->setError(QFile::PermissionsError, qt_error_string()); return false; } - if (!CloseHandle((HANDLE)maps[ptr].second)) { - q->setError(QFile::UnspecifiedError, qt_error_string()); - return false; - } maps.remove(ptr); - -#ifdef Q_USE_DEPRECATED_MAP_API - mapHandleClose(); -#endif - return true; -} - -#ifdef Q_USE_DEPRECATED_MAP_API -void QFSFileEnginePrivate::mapHandleClose() -{ if (maps.isEmpty()) { - CloseHandle(fileMapHandle); - fileMapHandle = INVALID_HANDLE_VALUE; + ::CloseHandle(mapHandle); + mapHandle = INVALID_HANDLE_VALUE; } + + return true; } -#endif QT_END_NAMESPACE -- 2.11.4.GIT