From 4846920c4c42615ecca40b5d2daed276e1de3805 Mon Sep 17 00:00:00 2001 From: Shane Kearns Date: Fri, 1 Oct 2010 14:14:01 +0100 Subject: Create QScopedResource class This has similar purpose to QScopedPointer, and is implemented using it. Symbian has many resource classes, e.g. RFile, RSocket, which behave as value types, but require the Close() member function to be called to release the server side resource owned by the handle. This class can be used to give exception safety, for example when trying to add a resource class to a container std::bad_alloc could be thrown. By assigning the resource to QScopedResource when it is opened, and calling take() after it is added to the container, it is ensured that the resource will be closed if an exception is thrown. Equivalent to the symbian pattern: CleanupClosePushL(file); container.AppendL(file); //transfers ownership, may leave CleanupStack::Pop(file); With STL exceptions we can do: QScopedResource ptr(file); container.append(file); //transfers ownership, may throw ptr.take; Reviewed-By: mread --- src/corelib/kernel/qcore_symbian_p.h | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/src/corelib/kernel/qcore_symbian_p.h b/src/corelib/kernel/qcore_symbian_p.h index 3019e05..a8f576d 100644 --- a/src/corelib/kernel/qcore_symbian_p.h +++ b/src/corelib/kernel/qcore_symbian_p.h @@ -59,6 +59,7 @@ #include #include #include +#include #include #include @@ -262,6 +263,29 @@ private: RConnection *iDefaultConnection; }; +template class QScopedPointerResourceCloser +{ +public: + static inline void cleanup(T* pointer) + { + if (pointer) + pointer->Close(); + } +}; + +/*typical use: + RFile file; + file.Open(...); + QScopedResource ptr(file); + container.append(file); //this may throw std::bad_alloc, in which case file.Close() is called by destructor + ptr.take(); //if we reach this line, ownership is transferred to the container + */ +template class QScopedResource : public QScopedPointer > +{ +public: + inline QScopedResource(T& resource) : QScopedPointer >(&resource) {} +}; + QT_END_NAMESPACE QT_END_HEADER -- cgit v0.12 From 3b4a7777829a75d1587efbcaf297566d7c710d80 Mon Sep 17 00:00:00 2001 From: Shane Kearns Date: Mon, 27 Jun 2011 15:23:35 +0100 Subject: Fix compiler warning Reviewed-by: Trust Me --- src/corelib/io/qfsfileengine_unix.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/corelib/io/qfsfileengine_unix.cpp b/src/corelib/io/qfsfileengine_unix.cpp index 681e55d..0e4b33a 100644 --- a/src/corelib/io/qfsfileengine_unix.cpp +++ b/src/corelib/io/qfsfileengine_unix.cpp @@ -925,6 +925,7 @@ QString QFSFileEngine::owner(FileOwner own) const return QFileSystemEngine::resolveUserName(ownerId(own)); return QFileSystemEngine::resolveGroupName(ownerId(own)); #else + Q_UNUSED(own) return QString(); #endif } -- cgit v0.12 From efde1f9521962398c156efd0b6670a358537ba51 Mon Sep 17 00:00:00 2001 From: Shane Kearns Date: Tue, 21 Jun 2011 16:27:20 +0100 Subject: Native memory mapped file support Task-number: QT-5026 Reviewed-by: mread --- src/corelib/io/qfsfileengine.cpp | 6 ++-- src/corelib/io/qfsfileengine_p.h | 10 +++++++ src/corelib/io/qfsfileengine_unix.cpp | 55 +++++++++++++++++++++++++++++++++-- 3 files changed, 67 insertions(+), 4 deletions(-) diff --git a/src/corelib/io/qfsfileengine.cpp b/src/corelib/io/qfsfileengine.cpp index 0d23a27..548f9cf 100644 --- a/src/corelib/io/qfsfileengine.cpp +++ b/src/corelib/io/qfsfileengine.cpp @@ -120,7 +120,7 @@ void QFSFileEnginePrivate::init() openMode = QIODevice::NotOpen; fd = -1; fh = 0; -#ifdef Q_OS_SYMBIAN +#if defined (Q_OS_SYMBIAN) && !defined(QT_SYMBIAN_USE_NATIVE_FILEMAP) fileHandleForMaps = -1; #endif lastIOCommand = IOFlushCommand; @@ -368,8 +368,10 @@ bool QFSFileEnginePrivate::closeFdFh() if (fd == -1 && !fh #ifdef Q_OS_SYMBIAN && !symbianFile.SubSessionHandle() +#ifndef QT_SYMBIAN_USE_NATIVE_FILEMAP && fileHandleForMaps == -1 #endif +#endif ) return false; @@ -378,7 +380,7 @@ bool QFSFileEnginePrivate::closeFdFh() bool closed = true; tried_stat = 0; -#ifdef Q_OS_SYMBIAN +#if defined(Q_OS_SYMBIAN) && !defined(QT_SYMBIAN_USE_NATIVE_FILEMAP) // Map handle is always owned by us so always close it if (fileHandleForMaps >= 0) { QT_CLOSE(fileHandleForMaps); diff --git a/src/corelib/io/qfsfileengine_p.h b/src/corelib/io/qfsfileengine_p.h index 79dda1b..f93250e 100644 --- a/src/corelib/io/qfsfileengine_p.h +++ b/src/corelib/io/qfsfileengine_p.h @@ -62,6 +62,12 @@ #ifdef Q_OS_SYMBIAN #include +//This macro will be defined if the OS supports memory mapped files +#if defined (SYMBIAN_FILE_MAPPING_SUPPORTED) && !defined (WINS) +//simpler define to check in sources +#define QT_SYMBIAN_USE_NATIVE_FILEMAP +#include +#endif #endif #ifndef QT_NO_FSFILEENGINE @@ -139,9 +145,11 @@ public: */ TInt symbianFilePos; #endif +#ifndef QT_SYMBIAN_USE_NATIVE_FILEMAP mutable int fileHandleForMaps; int getMapHandle(); #endif +#endif #ifdef Q_WS_WIN HANDLE fileHandle; @@ -153,6 +161,8 @@ public: #endif mutable DWORD fileAttrib; +#elif defined (QT_SYMBIAN_USE_NATIVE_FILEMAP) + QHash maps; #else QHash > maps; #endif diff --git a/src/corelib/io/qfsfileengine_unix.cpp b/src/corelib/io/qfsfileengine_unix.cpp index 0e4b33a..9de282a 100644 --- a/src/corelib/io/qfsfileengine_unix.cpp +++ b/src/corelib/io/qfsfileengine_unix.cpp @@ -602,7 +602,7 @@ int QFSFileEnginePrivate::nativeHandle() const return fh ? fileno(fh) : fd; } -#ifdef Q_OS_SYMBIAN +#if defined(Q_OS_SYMBIAN) && !defined(QT_SYMBIAN_USE_NATIVE_FILEMAP) int QFSFileEnginePrivate::getMapHandle() { if (symbianFile.SubSessionHandle()) { @@ -1046,9 +1046,47 @@ uchar *QFSFileEnginePrivate::map(qint64 offset, qint64 size, QFile::MemoryMapFla QT_OFF_T realOffset = QT_OFF_T(offset); realOffset &= ~(QT_OFF_T(pageSize - 1)); +#ifdef QT_SYMBIAN_USE_NATIVE_FILEMAP + TInt nativeMapError = KErrNone; + RFileMap mapping; + TUint mode(EFileMapRemovableMedia); + //If the file was opened for write or read/write, then open the map for read/write + if (openMode & QIODevice::WriteOnly) + mode |= EFileMapWrite; + if (symbianFile.SubSessionHandle()) { + nativeMapError = mapping.Open(symbianFile, offset, size, mode); + } else { + //map file by name if we don't have a native handle + QString fn = QFileSystemEngine::absoluteName(fileEntry).nativeFilePath(); + TUint filemode = EFileShareReadersOrWriters | EFileRead; + if (openMode & QIODevice::WriteOnly) + filemode |= EFileWrite; + nativeMapError = mapping.Open(qt_s60GetRFs(), qt_QString2TPtrC(fn), filemode, offset, size, mode); + } + if (nativeMapError == KErrNone) { + QScopedResource ptr(mapping); //will call Close if adding to mapping throws an exception + uchar *address = mapping.Base(); + maps[address] = mapping; + ptr.take(); + return address; + } + QFile::FileError reportedError = QFile::UnspecifiedError; + switch (nativeMapError) { + case KErrAccessDenied: + case KErrPermissionDenied: + reportedError = QFile::PermissionsError; + break; + case KErrNoMemory: + reportedError = QFile::ResourceError; + break; + } + q->setError(reportedError, QSystemError(nativeMapError, QSystemError::NativeError).toString()); + return 0; +#else #ifdef Q_OS_SYMBIAN + //older phones & emulator don't support native mapping, so need to keep the open C way around for those. void *mapAddress; - TRAPD(err, mapAddress = QT_MMAP((void*)0, realSize, + TRAPD(err, mapAddress = QT_MMAP((void*)0, realSize, access, MAP_SHARED, getMapHandle(), realOffset)); if (err != KErrNone) { qWarning("OpenC bug: leave from mmap %d", err); @@ -1080,6 +1118,7 @@ uchar *QFSFileEnginePrivate::map(qint64 offset, qint64 size, QFile::MemoryMapFla break; } return 0; +#endif } bool QFSFileEnginePrivate::unmap(uchar *ptr) @@ -1091,6 +1130,17 @@ bool QFSFileEnginePrivate::unmap(uchar *ptr) return false; } +#ifdef QT_SYMBIAN_USE_NATIVE_FILEMAP + RFileMap mapping = maps.value(ptr); + TInt err = mapping.Flush(); + mapping.Close(); + maps.remove(ptr); + if (err) { + q->setError(QFile::WriteError, QSystemError(err, QSystemError::NativeError).toString()); + return false; + } + return true; +#else uchar *start = ptr - maps[ptr].first; size_t len = maps[ptr].second; if (-1 == munmap(start, len)) { @@ -1099,6 +1149,7 @@ bool QFSFileEnginePrivate::unmap(uchar *ptr) } maps.remove(ptr); return true; +#endif #else return false; #endif -- cgit v0.12 From 4082ed92ed80c57cb499de569631a664107ef05b Mon Sep 17 00:00:00 2001 From: Martin Petersson Date: Tue, 19 Jul 2011 12:42:40 +0200 Subject: QNetworkAccessFileBackend: Add warning for file url without scheme. When the scheme is not set for a file we should accept the url but add a warning. The behaviour will change for Qt5 in which we should no longer accept the url if the scheme is not set. Task-number: QTBUG-17731 Reviewed-by: Markus Goetz --- src/network/access/qnetworkaccessfilebackend.cpp | 5 +++-- tests/auto/qnetworkreply/tst_qnetworkreply.cpp | 7 ++----- 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/src/network/access/qnetworkaccessfilebackend.cpp b/src/network/access/qnetworkaccessfilebackend.cpp index 42cc2c2..7c4adca 100644 --- a/src/network/access/qnetworkaccessfilebackend.cpp +++ b/src/network/access/qnetworkaccessfilebackend.cpp @@ -67,7 +67,7 @@ QNetworkAccessFileBackendFactory::create(QNetworkAccessManager::Operation op, QUrl url = request.url(); if (url.scheme().compare(QLatin1String("qrc"), Qt::CaseInsensitive) == 0 || url.isLocalFile()) { return new QNetworkAccessFileBackend; - } else if (!url.scheme().isEmpty() && url.authority().isEmpty()) { + } else if (!url.isEmpty() && url.authority().isEmpty()) { // check if QFile could, in theory, open this URL via the file engines // it has to be in the format: // prefix:path/to/file @@ -75,7 +75,8 @@ QNetworkAccessFileBackendFactory::create(QNetworkAccessManager::Operation op, // // this construct here must match the one below in open() QFileInfo fi(url.toString(QUrl::RemoveAuthority | QUrl::RemoveFragment | QUrl::RemoveQuery)); - if ((url.scheme().length()==1) && fi.exists()) + // On Windows and Symbian the drive letter is detected as the scheme. + if (fi.exists() && (url.scheme().isEmpty() || (url.scheme().length() == 1))) qWarning("QNetworkAccessFileBackendFactory: URL has no schema set, use file:// for files"); if (fi.exists() || (op == QNetworkAccessManager::PutOperation && fi.dir().exists())) return new QNetworkAccessFileBackend; diff --git a/tests/auto/qnetworkreply/tst_qnetworkreply.cpp b/tests/auto/qnetworkreply/tst_qnetworkreply.cpp index 45f501c..34b0375 100644 --- a/tests/auto/qnetworkreply/tst_qnetworkreply.cpp +++ b/tests/auto/qnetworkreply/tst_qnetworkreply.cpp @@ -1672,10 +1672,8 @@ void tst_QNetworkReply::getErrors() QFETCH(QString, url); QNetworkRequest request(url); -#if defined(Q_OS_WIN) || defined (Q_OS_SYMBIAN) if (qstrcmp(QTest::currentDataTag(), "empty-scheme-host") == 0 && QFileInfo(url).isAbsolute()) QTest::ignoreMessage(QtWarningMsg, "QNetworkAccessFileBackendFactory: URL has no schema set, use file:// for files"); -#endif QNetworkReplyPtr reply = manager.get(request); reply->setParent(this); // we have expect-fails @@ -1691,10 +1689,9 @@ void tst_QNetworkReply::getErrors() //qDebug() << reply->errorString(); QFETCH(int, error); -#if defined(Q_OS_WIN) || defined (Q_OS_SYMBIAN) if (QFileInfo(url).isAbsolute()) - QEXPECT_FAIL("empty-scheme-host", "this is expected to fail on Windows and Symbian, QTBUG-17731", Abort); -#endif + QEXPECT_FAIL("empty-scheme-host", "this is expected to fail, QTBUG-17731", Abort); + QEXPECT_FAIL("ftp-is-dir", "QFtp cannot provide enough detail", Abort); // the line below is not necessary QEXPECT_FAIL("ftp-dir-not-readable", "QFtp cannot provide enough detail", Abort); -- cgit v0.12 From f6735134a3637ae09442ad592f74a551830577fc Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Thu, 21 Jul 2011 17:10:30 +0200 Subject: Fix the timeout calculation again. The commit 412ef92162f8874a1585221125c31ef5f8ccc9cb introduced a fix, but the fix was incomplete. Fix it for good. Change-Id: I3e7fbdb294f8e960fbbf2e830790750240ed813a Merge-request: 30 Reviewed-by: Olivier Goffart Reviewed-on: http://codereview.qt.nokia.com/1991 Reviewed-by: Qt Sanity Bot (cherry picked from commit 038d7c6c3b9815068e1f5b6df12625181f0313e1) --- src/corelib/thread/qmutex_unix.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/corelib/thread/qmutex_unix.cpp b/src/corelib/thread/qmutex_unix.cpp index e692e19..2a9d23c 100644 --- a/src/corelib/thread/qmutex_unix.cpp +++ b/src/corelib/thread/qmutex_unix.cpp @@ -161,8 +161,8 @@ bool QMutexPrivate::wait(int timeout) return false; } - ts.tv_sec = timeout / Q_INT64_C(1000) / 1000 / 1000; - ts.tv_nsec = timeout % (Q_INT64_C(1000) * 1000 * 1000); + ts.tv_sec = xtimeout / Q_INT64_C(1000) / 1000 / 1000; + ts.tv_nsec = xtimeout % (Q_INT64_C(1000) * 1000 * 1000); } } return true; -- cgit v0.12