From 1431679fb589cb5e652a40957a5d2868dc0a9080 Mon Sep 17 00:00:00 2001 From: Robin Burchell Date: Sat, 10 Dec 2011 16:00:15 +0100 Subject: Remove Symbian support from /src/corelib/kernel/. Change-Id: Ic4a1b4f074d2ffd4cdfcb44e47c9bfccc2378760 Reviewed-by: Lars Knoll Reviewed-by: Olivier Goffart Reviewed-by: Marius Storm-Olsen --- src/corelib/kernel/kernel.pri | 18 +- src/corelib/kernel/qcore_symbian_p.cpp | 317 ------ src/corelib/kernel/qcore_symbian_p.h | 282 ----- src/corelib/kernel/qeventdispatcher_symbian.cpp | 1316 ----------------------- src/corelib/kernel/qeventdispatcher_symbian_p.h | 327 ------ src/corelib/kernel/qsharedmemory_symbian.cpp | 173 --- src/corelib/kernel/qsystemsemaphore_symbian.cpp | 138 --- 7 files changed, 1 insertion(+), 2570 deletions(-) delete mode 100644 src/corelib/kernel/qcore_symbian_p.cpp delete mode 100644 src/corelib/kernel/qcore_symbian_p.h delete mode 100644 src/corelib/kernel/qeventdispatcher_symbian.cpp delete mode 100644 src/corelib/kernel/qeventdispatcher_symbian_p.h delete mode 100644 src/corelib/kernel/qsharedmemory_symbian.cpp delete mode 100644 src/corelib/kernel/qsystemsemaphore_symbian.cpp (limited to 'src/corelib') diff --git a/src/corelib/kernel/kernel.pri b/src/corelib/kernel/kernel.pri index 4dbb669ffd..147f20aaa3 100644 --- a/src/corelib/kernel/kernel.pri +++ b/src/corelib/kernel/kernel.pri @@ -99,7 +99,7 @@ nacl { kernel/qfunctions_nacl.h } -unix:!symbian { +unix { SOURCES += \ kernel/qcore_unix.cpp \ kernel/qcrashhandler.cpp \ @@ -126,22 +126,6 @@ unix:!symbian { contains(QT_CONFIG, clock-gettime):include($$QT_SOURCE_TREE/config.tests/unix/clock-gettime/clock-gettime.pri) } -symbian { - SOURCES += \ - kernel/qcore_unix.cpp \ - kernel/qcrashhandler.cpp \ - kernel/qeventdispatcher_symbian.cpp \ - kernel/qcore_symbian_p.cpp \ - kernel/qsharedmemory_symbian.cpp \ - kernel/qsystemsemaphore_symbian.cpp - - HEADERS += \ - kernel/qcore_unix_p.h \ - kernel/qcrashhandler_p.h \ - kernel/qeventdispatcher_symbian_p.h \ - kernel/qcore_symbian_p.h -} - vxworks { SOURCES += \ kernel/qfunctions_vxworks.cpp diff --git a/src/corelib/kernel/qcore_symbian_p.cpp b/src/corelib/kernel/qcore_symbian_p.cpp deleted file mode 100644 index 5b52ec22a1..0000000000 --- a/src/corelib/kernel/qcore_symbian_p.cpp +++ /dev/null @@ -1,317 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the QtCore module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include -#include -#include -#include "qcore_symbian_p.h" -#include -#include - -QT_BEGIN_NAMESPACE - -/* - Helper function for calling into Symbian classes that expect a TDes&. - This function converts a QString to a TDes by allocating memory that - must be deleted by the caller. -*/ - -Q_CORE_EXPORT HBufC* qt_QString2HBufC(const QString& aString) -{ - HBufC *buffer; -#ifdef QT_NO_UNICODE - TPtrC8 ptr(reinterpret_cast(aString.toLocal8Bit().constData())); -#else - TPtrC16 ptr(qt_QString2TPtrC(aString)); -#endif - buffer = HBufC::New(ptr.Length()); - Q_CHECK_PTR(buffer); - buffer->Des().Copy(ptr); - return buffer; -} - -Q_CORE_EXPORT QString qt_TDesC2QString(const TDesC& aDescriptor) -{ -#ifdef QT_NO_UNICODE - return QString::fromLocal8Bit(aDescriptor.Ptr(), aDescriptor.Length()); -#else - return QString(reinterpret_cast(aDescriptor.Ptr()), aDescriptor.Length()); -#endif -} - -QHBufC::QHBufC() - : m_hBufC(0) -{ -} - -QHBufC::QHBufC(const QHBufC &src) - : m_hBufC(src.m_hBufC->Alloc()) -{ - Q_CHECK_PTR(m_hBufC); -} - -/*! - \internal - Constructs a QHBufC from an HBufC. Note that the QHBufC instance takes - ownership of the HBufC. -*/ -QHBufC::QHBufC(HBufC *src) - : m_hBufC(src) -{ -} - -QHBufC::QHBufC(const QString &src) -{ - m_hBufC = qt_QString2HBufC(src); -} - -QHBufC::~QHBufC() -{ - if (m_hBufC) - delete m_hBufC; -} - -class QS60PluginResolver -{ -public: - QS60PluginResolver() - : initTried(false) {} - - ~QS60PluginResolver() { - lib.Close(); - } - - TLibraryFunction resolve(int ordinal) { - if (!initTried) { - init(); - initTried = true; - } - - if (lib.Handle()) - return lib.Lookup(ordinal); - else - return reinterpret_cast(NULL); - } - -private: - void init() - { - _LIT(KLibName_3_1, "qts60plugin_3_1" QT_LIBINFIX_UNICODE L".dll"); - _LIT(KLibName_3_2, "qts60plugin_3_2" QT_LIBINFIX_UNICODE L".dll"); - _LIT(KLibName_5_0, "qts60plugin_5_0" QT_LIBINFIX_UNICODE L".dll"); - - TPtrC libName; - TInt uidValue; - switch (QSysInfo::s60Version()) { - case QSysInfo::SV_S60_3_1: - libName.Set(KLibName_3_1); - uidValue = 0x2001E620; - break; - case QSysInfo::SV_S60_3_2: - libName.Set(KLibName_3_2); - uidValue = 0x2001E621; - break; - case QSysInfo::SV_S60_5_0: // Fall through to default - default: - // Default to 5.0 version, as any unknown platform is likely to be newer than that - libName.Set(KLibName_5_0); - uidValue = 0x2001E622; - break; - } - - TUidType libUid(KDynamicLibraryUid, KSharedLibraryUid, TUid::Uid(uidValue)); - lib.Load(libName, libUid); - - // Duplicate lib handle to enable process wide access to it. Since Duplicate overwrites - // existing handle without closing it, store original for subsequent closing. - RLibrary origHandleCloser = lib; - lib.Duplicate(RThread(), EOwnerProcess); - origHandleCloser.Close(); - } - - RLibrary lib; - bool initTried; -}; - -Q_GLOBAL_STATIC(QS60PluginResolver, qt_s60_plugin_resolver); - -/*! - \internal - Resolves a platform version specific function from S60 plugin. - If plugin is missing or resolving fails for another reason, NULL is returned. -*/ -Q_CORE_EXPORT TLibraryFunction qt_resolveS60PluginFunc(int ordinal) -{ - return qt_s60_plugin_resolver()->resolve(ordinal); -} - -class QS60RFsSession -{ -public: - QS60RFsSession() { - qt_symbian_throwIfError(iFs.Connect()); - qt_symbian_throwIfError(iFs.ShareProtected()); - } - - ~QS60RFsSession() { - iFs.Close(); - } - - RFs& GetRFs() { - return iFs; - } - -private: - - RFs iFs; -}; - -uint qHash(const RSubSessionBase& key) -{ - return qHash(key.SubSessionHandle()); -} - -Q_GLOBAL_STATIC(QS60RFsSession, qt_s60_RFsSession); - -Q_CORE_EXPORT RFs& qt_s60GetRFs() -{ - return qt_s60_RFsSession()->GetRFs(); -} - -QSymbianSocketManager::QSymbianSocketManager() : - iNextSocket(0), iDefaultConnection(0) -{ - TSessionPref preferences; - // ### In future this could be changed to KAfInet6 when that is more common than IPv4 - preferences.iAddrFamily = KAfInet; - preferences.iProtocol = KProtocolInetIp; - //use global message pool, as we do not know how many sockets app will use - //TODO: is this the right choice? - qt_symbian_throwIfError(iSocketServ.Connect(preferences, -1)); - qt_symbian_throwIfError(iSocketServ.ShareAuto()); -} - -QSymbianSocketManager::~QSymbianSocketManager() -{ - iSocketServ.Close(); - if(!socketMap.isEmpty()) { - qWarning("leaked %d sockets on exit", socketMap.count()); - } -} - -RSocketServ& QSymbianSocketManager::getSocketServer() { - return iSocketServ; -} - -int QSymbianSocketManager::addSocket(const RSocket& socket) { - QHashableSocket sock(static_cast(socket)); - QMutexLocker l(&iMutex); - Q_ASSERT(!socketMap.contains(sock)); - if(socketMap.contains(sock)) - return socketMap.value(sock); - // allocate socket number - int guard = 0; - while(reverseSocketMap.contains(iNextSocket)) { - iNextSocket++; - iNextSocket %= max_sockets; - guard++; - if(guard > max_sockets) - return -1; - } - int id = iNextSocket; - - socketMap[sock] = id; - reverseSocketMap[id] = sock; - return id + socket_offset; -} - -bool QSymbianSocketManager::removeSocket(const RSocket &socket) { - QHashableSocket sock(static_cast(socket)); - QMutexLocker l(&iMutex); - if(!socketMap.contains(sock)) - return false; - int id = socketMap.value(sock); - socketMap.remove(sock); - reverseSocketMap.remove(id); - return true; -} - -int QSymbianSocketManager::lookupSocket(const RSocket& socket) const { - QHashableSocket sock(static_cast(socket)); - QMutexLocker l(&iMutex); - if(!socketMap.contains(sock)) - return -1; - int id = socketMap.value(sock); - return id + socket_offset; -} - -bool QSymbianSocketManager::lookupSocket(int fd, RSocket& socket) const { - QMutexLocker l(&iMutex); - int id = fd - socket_offset; - if(!reverseSocketMap.contains(id)) - return false; - socket = reverseSocketMap.value(id); - return true; -} - -void QSymbianSocketManager::setDefaultConnection(RConnection* con) -{ - iDefaultConnection = con; -} - -RConnection* QSymbianSocketManager::defaultConnection() const -{ - return iDefaultConnection; -} - -Q_GLOBAL_STATIC(QSymbianSocketManager, qt_symbianSocketManager); - -QSymbianSocketManager& QSymbianSocketManager::instance() -{ - return *(qt_symbianSocketManager()); -} - -Q_CORE_EXPORT RSocketServ& qt_symbianGetSocketServer() -{ - return QSymbianSocketManager::instance().getSocketServer(); -} - -QT_END_NAMESPACE diff --git a/src/corelib/kernel/qcore_symbian_p.h b/src/corelib/kernel/qcore_symbian_p.h deleted file mode 100644 index 84c6fed4db..0000000000 --- a/src/corelib/kernel/qcore_symbian_p.h +++ /dev/null @@ -1,282 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the QtCore module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QCORE_SYMBIAN_P_H -#define QCORE_SYMBIAN_P_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists for the convenience -// of other Qt classes. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include -#include -#include -#include -#include -#include -#include -#include - -#define QT_LSTRING2(x) L##x -#define QT_LSTRING(x) QT_LSTRING2(x) - -#if defined(QT_LIBINFIX) -# define QT_LIBINFIX_UNICODE QT_LSTRING(QT_LIBINFIX) -#else -# define QT_LIBINFIX_UNICODE L"" -#endif - -QT_BEGIN_HEADER - -QT_BEGIN_NAMESPACE - -Q_CORE_EXPORT HBufC* qt_QString2HBufC(const QString& aString); - -Q_CORE_EXPORT QString qt_TDesC2QString(const TDesC& aDescriptor); -inline QString qt_TDes2QString(const TDes& aDescriptor) { return qt_TDesC2QString(aDescriptor); } - -static inline QSize qt_TSize2QSize(const TSize& ts) -{ - return QSize(ts.iWidth, ts.iHeight); -} - -static inline TSize qt_QSize2TSize(const QSize& qs) -{ - return TSize(qs.width(), qs.height()); -} - -static inline QRect qt_TRect2QRect(const TRect& tr) -{ - return QRect(tr.iTl.iX, tr.iTl.iY, tr.Width(), tr.Height()); -} - -static inline TRect qt_QRect2TRect(const QRect& qr) -{ - return TRect(TPoint(qr.left(), qr.top()), TSize(qr.width(), qr.height())); -} - -// Returned TPtrC is valid as long as the given parameter is valid and unmodified -static inline TPtrC qt_QString2TPtrC( const QString& string ) -{ - return TPtrC16(static_cast(string.utf16()), string.length()); -} - -/*! - \internal - This class is a wrapper around the Symbian HBufC descriptor class. - It makes sure that the heap allocated HBufC class is freed when it is - destroyed. -*/ -class Q_CORE_EXPORT QHBufC -{ -public: - QHBufC(); - QHBufC(const QHBufC &src); - QHBufC(HBufC *src); - QHBufC(const QString &src); - ~QHBufC(); - - inline operator HBufC *() { return m_hBufC; } - inline operator const HBufC *() const { return m_hBufC; } - inline HBufC *data() { return m_hBufC; } - inline const HBufC *data() const { return m_hBufC; } - inline HBufC & operator*() { return *m_hBufC; } - inline const HBufC & operator*() const { return *m_hBufC; } - inline HBufC * operator->() { return m_hBufC; } - inline const HBufC * operator->() const { return m_hBufC; } - - inline bool operator==(const QHBufC ¶m) const { return data() == param.data(); } - inline bool operator!=(const QHBufC ¶m) const { return data() != param.data(); } - -private: - HBufC *m_hBufC; -}; - -inline uint qHash(TUid uid) -{ - return qHash(uid.iUid); -} - -// S60 version specific function ordinals that can be resolved -enum S60PluginFuncOrdinals -{ - S60Plugin_TimeFormatL = 1, - S60Plugin_GetTimeFormatSpec = 2, - S60Plugin_GetLongDateFormatSpec = 3, - S60Plugin_GetShortDateFormatSpec = 4, - S60Plugin_LocalizedDirectoryName = 5, - S60Plugin_GetSystemDrive = 6 -}; - -Q_CORE_EXPORT TLibraryFunction qt_resolveS60PluginFunc(int ordinal); - -Q_CORE_EXPORT RFs& qt_s60GetRFs(); -Q_CORE_EXPORT RSocketServ& qt_symbianGetSocketServer(); - -// Defined in qlocale_symbian.cpp. -Q_CORE_EXPORT QByteArray qt_symbianLocaleName(int code); - -template -struct QScopedPointerRCloser -{ - static inline void cleanup(R *rPointer) - { - // Enforce a complete type. - // If you get a compile error here, read the section on forward declared - // classes in the QScopedPointer documentation. - typedef char IsIncompleteType[ sizeof(R) ? 1 : -1 ]; - (void) sizeof(IsIncompleteType); - - if (rPointer) - rPointer->Close(); - } -}; - -//Wrapper for RSocket so it can be used as a key in QHash or QMap -class QHashableSocket : public RSocket -{ -public: - bool operator==(const QHashableSocket &other) const - { - return SubSessionHandle() == other.SubSessionHandle() - && Session().Handle() == other.Session().Handle(); - } - bool operator<(const QHashableSocket &other) const - { - if (Session().Handle() == other.Session().Handle()) - return SubSessionHandle() < other.SubSessionHandle(); - return Session().Handle() < other.Session().Handle(); - } -}; - -uint qHash(const RSubSessionBase& key); - -/*! - \internal - This class exists in QtCore for the benefit of QSocketNotifier, which uses integer - file descriptors in its public API. - So we need a way to map between int and RSocket. - Additionally, it is used to host the global RSocketServ session -*/ -class Q_CORE_EXPORT QSymbianSocketManager -{ -public: - QSymbianSocketManager(); - ~QSymbianSocketManager(); - - /*! - \internal - \return handle to the socket server - */ - RSocketServ& getSocketServer(); - /*! - \internal - Adds a symbian socket to the global map - \param an open socket - \return pseudo file descriptor, -1 if out of resources - */ - int addSocket(const RSocket &sock); - /*! - \internal - Removes a symbian socket from the global map - \param an open socket - \return true if the socket was in the map - */ - bool removeSocket(const RSocket &sock); - /*! - \internal - Get pseudo file descriptor for a socket - \param an open socket - \return integer handle, or -1 if not in map - */ - int lookupSocket(const RSocket &sock) const; - /*! - \internal - Get socket for a pseudo file descriptor - \param an open socket fd - \param sock (out) socket handle - \return true on success or false if not in map - */ - bool lookupSocket(int fd, RSocket& sock) const; - - /*! - \internal - Set the default connection to use for new sockets - \param an open connection - */ - void setDefaultConnection(RConnection* con); - /*! - \internal - Get the default connection to use for new sockets - \return the connection, or null pointer if there is none set - */ - RConnection *defaultConnection() const; - - /*! - \internal - Gets a reference to the singleton socket manager - */ - static QSymbianSocketManager& instance(); -private: - int allocateSocket(); - - const static int max_sockets = 0x20000; //covers all TCP and UDP ports, probably run out of memory first - const static int socket_offset = 0x40000000; //hacky way of separating sockets from file descriptors - int iNextSocket; - QHash socketMap; - QHash reverseSocketMap; - mutable QMutex iMutex; - RSocketServ iSocketServ; - RConnection *iDefaultConnection; -}; - -QT_END_NAMESPACE - -QT_END_HEADER - -#endif //QCORE_SYMBIAN_P_H diff --git a/src/corelib/kernel/qeventdispatcher_symbian.cpp b/src/corelib/kernel/qeventdispatcher_symbian.cpp deleted file mode 100644 index 1d7ecce9ae..0000000000 --- a/src/corelib/kernel/qeventdispatcher_symbian.cpp +++ /dev/null @@ -1,1316 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the QtCore module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qeventdispatcher_symbian_p.h" -#include -#include -#include -#include - -#include -#include - -QT_BEGIN_NAMESPACE - -#ifdef SYMBIAN_GRAPHICS_WSERV_QT_EFFECTS -// when the system UI is Qt based, priority drop is not needed as CPU starved processes will not be killed. -#undef QT_SYMBIAN_PRIORITY_DROP -#else -#define QT_SYMBIAN_PRIORITY_DROP -#endif - -#define WAKE_UP_PRIORITY CActive::EPriorityStandard -#define TIMER_PRIORITY CActive::EPriorityHigh -#define NULLTIMER_PRIORITY CActive::EPriorityLow -#define COMPLETE_DEFERRED_ACTIVE_OBJECTS_PRIORITY CActive::EPriorityIdle - -static inline int qt_pipe_write(int socket, const char *data, qint64 len) -{ - return ::write(socket, data, len); -} -#if defined(write) -# undef write -#endif - -static inline int qt_pipe_close(int socket) -{ - return ::close(socket); -} -#if defined(close) -# undef close -#endif - -static inline int qt_pipe_fcntl(int socket, int command) -{ - return ::fcntl(socket, command); -} -static inline int qt_pipe2_fcntl(int socket, int command, int option) -{ - return ::fcntl(socket, command, option); -} -#if defined(fcntl) -# undef fcntl -#endif - -static inline int qt_socket_select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout) -{ - return ::select(nfds, readfds, writefds, exceptfds, timeout); -} - -// This simply interrupts the select and locks the mutex until destroyed. -class QSelectMutexGrabber -{ -public: - QSelectMutexGrabber(int writeFd, int readFd, QMutex *mutex) - : m_mutex(mutex) - { - if (m_mutex->tryLock()) - return; - - char dummy = 0; - qt_pipe_write(writeFd, &dummy, 1); - - m_mutex->lock(); - - char buffer; - while (::read(readFd, &buffer, 1) > 0) {} - } - - ~QSelectMutexGrabber() - { - m_mutex->unlock(); - } - -private: - QMutex *m_mutex; -}; - -/* - * This class is designed to aid in implementing event handling in a more round robin fashion. We - * cannot change active objects that we do not own, but the active objects that Qt owns will use - * this as a base class with convenience functions. - * - * Here is how it works: On every RunL, the deriving class should call maybeQueueForLater(). - * This will return whether the active object has been queued, or whether it should run immediately. - * Queued objects will run again after other events have been processed. - * - * The QCompleteDeferredAOs class is a special object that runs after all others, which will - * reactivate the objects that were previously not run. - */ -QActiveObject::QActiveObject(TInt priority, QEventDispatcherSymbian *dispatcher) - : CActive(priority), - m_dispatcher(dispatcher), - m_hasAlreadyRun(false), - m_hasRunAgain(false), - m_iterationCount(1) -{ -} - -QActiveObject::~QActiveObject() -{ - if (m_hasRunAgain) - m_dispatcher->removeDeferredActiveObject(this); -} - -bool QActiveObject::maybeQueueForLater() -{ - Q_ASSERT(!m_hasRunAgain); - - if (!m_hasAlreadyRun || m_dispatcher->iterationCount() != m_iterationCount) { - // First occurrence of this event in this iteration. - m_hasAlreadyRun = true; - m_iterationCount = m_dispatcher->iterationCount(); - return false; - } else { - // The event has already occurred. - m_dispatcher->addDeferredActiveObject(this); - m_hasRunAgain = true; - return true; - } -} - -bool QActiveObject::maybeDeferSocketEvent() -{ - Q_ASSERT(!m_hasRunAgain); - Q_ASSERT(m_dispatcher); - if (!m_dispatcher->areSocketEventsBlocked()) { - return false; - } - m_hasRunAgain = true; - m_dispatcher->addDeferredSocketActiveObject(this); - return true; -} - -void QActiveObject::reactivateAndComplete() -{ - TInt error = iStatus.Int(); - iStatus = KRequestPending; - SetActive(); - TRequestStatus *status = &iStatus; - QEventDispatcherSymbian::RequestComplete(status, error); - - m_hasRunAgain = false; - m_hasAlreadyRun = false; -} - -QWakeUpActiveObject::QWakeUpActiveObject(QEventDispatcherSymbian *dispatcher) - : QActiveObject(WAKE_UP_PRIORITY, dispatcher) -{ - m_hostThreadId = RThread().Id(); - CActiveScheduler::Add(this); - iStatus = KRequestPending; - SetActive(); -} - -QWakeUpActiveObject::~QWakeUpActiveObject() -{ - Cancel(); -} - -void QWakeUpActiveObject::DoCancel() -{ - if (iStatus.Int() == KRequestPending) { - TRequestStatus *status = &iStatus; - QEventDispatcherSymbian::RequestComplete(status, KErrNone); - } else if (IsActive() && m_hostThreadId != RThread().Id()) { - // This is being cancelled in the adopted monitor thread, which can happen if an adopted thread with - // an event loop has exited. The event loop creates an event dispatcher with this active object, which may be complete but not run on exit. - // We force a cancellation in this thread, because a) the object cannot be deleted while active and b) without a cancellation - // the thread semaphore will be one count down. - // It is possible for this problem to affect other active objects. They symptom would be that finished signals - // from adopted threads are not sent, or they arrive much later than they should. - TRequestStatus *status = &iStatus; - User::RequestComplete(status, KErrNone); - } -} - -void QWakeUpActiveObject::RunL() -{ - if (maybeQueueForLater()) - return; - - iStatus = KRequestPending; - SetActive(); - QT_TRYCATCH_LEAVING(m_dispatcher->wakeUpWasCalled()); -} - -QTimerActiveObject::QTimerActiveObject(QEventDispatcherSymbian *dispatcher, SymbianTimerInfo *timerInfo) - : QActiveObject((timerInfo->interval) ? TIMER_PRIORITY : NULLTIMER_PRIORITY , dispatcher), - m_timerInfo(timerInfo), m_expectedTimeSinceLastEvent(0) -{ - // start the timeout timer to ensure initialisation - m_timeoutTimer.start(); -} - -QTimerActiveObject::~QTimerActiveObject() -{ - Cancel(); - m_rTimer.Close(); //close of null handle is safe -} - -void QTimerActiveObject::DoCancel() -{ - if (m_timerInfo->interval > 0) { - m_rTimer.Cancel(); - } else { - if (iStatus.Int() == KRequestPending) { - TRequestStatus *status = &iStatus; - QEventDispatcherSymbian::RequestComplete(status, KErrNone); - } - } -} - -void QTimerActiveObject::RunL() -{ - int error = KErrNone; - if (iStatus == KErrNone) { - QT_TRYCATCH_ERROR(error, Run()); - } else { - error = iStatus.Int(); - } - // All Symbian error codes are negative. - if (error < 0) { - CActiveScheduler::Current()->Error(error); // stop and report here, as this timer will be deleted on scope exit - } -} - -#define MAX_SYMBIAN_TIMEOUT_MS 2000000 -void QTimerActiveObject::StartTimer() -{ - if (m_timerInfo->msLeft > MAX_SYMBIAN_TIMEOUT_MS) { - //There is loss of accuracy anyway due to needing to restart the timer every 33 minutes, - //so the 1/64s res of After() is acceptable for these very long timers. - m_rTimer.After(iStatus, MAX_SYMBIAN_TIMEOUT_MS * 1000); - m_timerInfo->msLeft -= MAX_SYMBIAN_TIMEOUT_MS; - } else { - // this algorithm implements drift correction for repeating timers - // calculate how late we are for this event - int timeSinceLastEvent = m_timeoutTimer.restart(); - int overshoot = timeSinceLastEvent - m_expectedTimeSinceLastEvent; - if (overshoot > m_timerInfo->msLeft) { - // we skipped a whole timeout, restart from here - overshoot = 0; - } - // calculate when the next event should happen - int waitTime = m_timerInfo->msLeft - overshoot; - m_expectedTimeSinceLastEvent = waitTime; - // limit the actual ms wait time to avoid wild corrections - // this will cause the real event time to slowly drift back to the expected event time - // measurements show that Symbian timers always fire 1 or 2 ms late - const int limit = 4; - waitTime = qMax(m_timerInfo->msLeft - limit, waitTime); - m_rTimer.HighRes(iStatus, waitTime * 1000); - m_timerInfo->msLeft = 0; - } - SetActive(); -} - -void QTimerActiveObject::Run() -{ - //restart timer immediately, if the timeout has been split because it overflows max for platform. - if (m_timerInfo->msLeft > 0) { - StartTimer(); - return; - } - - if (maybeQueueForLater()) - return; - - if (m_timerInfo->interval > 0) { - // Start a new timer immediately so that we don't lose time. - m_timerInfo->msLeft = m_timerInfo->interval; - StartTimer(); - - m_timerInfo->dispatcher->timerFired(m_timerInfo->timerId); - } else { - // However, we only complete zero timers after the event has finished, - // in order to prevent busy looping when doing nested loops. - - // Keep the refpointer around in order to avoid deletion until the end of this function. - SymbianTimerInfoPtr timerInfoPtr(m_timerInfo); - - m_timerInfo->dispatcher->timerFired(m_timerInfo->timerId); - - iStatus = KRequestPending; - SetActive(); - TRequestStatus *status = &iStatus; - QEventDispatcherSymbian::RequestComplete(status, KErrNone); - } -} - -void QTimerActiveObject::Start() -{ - CActiveScheduler::Add(this); - m_timerInfo->msLeft = m_timerInfo->interval; - if (m_timerInfo->interval > 0) { - if (!m_rTimer.Handle()) { - qt_symbian_throwIfError(m_rTimer.CreateLocal()); - } - m_timeoutTimer.start(); - m_expectedTimeSinceLastEvent = 0; - StartTimer(); - } else { - iStatus = KRequestPending; - SetActive(); - TRequestStatus *status = &iStatus; - QEventDispatcherSymbian::RequestComplete(status, KErrNone); - } -} - -SymbianTimerInfo::SymbianTimerInfo() - : timerAO(0) -{ -} - -SymbianTimerInfo::~SymbianTimerInfo() -{ - delete timerAO; -} - -QCompleteDeferredAOs::QCompleteDeferredAOs(QEventDispatcherSymbian *dispatcher) - : CActive(COMPLETE_DEFERRED_ACTIVE_OBJECTS_PRIORITY), - m_dispatcher(dispatcher) -{ - CActiveScheduler::Add(this); - iStatus = KRequestPending; - SetActive(); -} - -QCompleteDeferredAOs::~QCompleteDeferredAOs() -{ - Cancel(); -} - -void QCompleteDeferredAOs::complete() -{ - if (iStatus.Int() == KRequestPending) { - TRequestStatus *status = &iStatus; - QEventDispatcherSymbian::RequestComplete(status, KErrNone); - } -} - -void QCompleteDeferredAOs::DoCancel() -{ - if (iStatus.Int() == KRequestPending) { - TRequestStatus *status = &iStatus; - QEventDispatcherSymbian::RequestComplete(status, KErrNone); - } -} - -void QCompleteDeferredAOs::RunL() -{ - iStatus = KRequestPending; - SetActive(); - - QT_TRYCATCH_LEAVING(m_dispatcher->reactivateDeferredActiveObjects()); -} - -QSelectThread::QSelectThread() - : m_quit(false) -{ - if (::pipe(m_pipeEnds) != 0) { - qWarning("Select thread was unable to open a pipe, errno: %i", errno); - } else { - int flags0 = qt_pipe_fcntl(m_pipeEnds[0], F_GETFL); - int flags1 = qt_pipe_fcntl(m_pipeEnds[1], F_GETFL); - // We should check the error code here, but Open C has a bug that returns - // failure even though the operation was successful. - qt_pipe2_fcntl(m_pipeEnds[0], F_SETFL, flags0 | O_NONBLOCK); - qt_pipe2_fcntl(m_pipeEnds[1], F_SETFL, flags1 | O_NONBLOCK); - } -} - -QSelectThread::~QSelectThread() -{ - qt_pipe_close(m_pipeEnds[1]); - qt_pipe_close(m_pipeEnds[0]); -} - -void QSelectThread::run() -{ - Q_D(QThread); - - m_mutex.lock(); - - while (!m_quit) { - fd_set readfds; - fd_set writefds; - fd_set exceptionfds; - - FD_ZERO(&readfds); - FD_ZERO(&writefds); - FD_ZERO(&exceptionfds); - - int maxfd = 0; - maxfd = qMax(maxfd, updateSocketSet(QSocketNotifier::Read, &readfds)); - maxfd = qMax(maxfd, updateSocketSet(QSocketNotifier::Write, &writefds)); - maxfd = qMax(maxfd, updateSocketSet(QSocketNotifier::Exception, &exceptionfds)); - maxfd = qMax(maxfd, m_pipeEnds[0]); - maxfd++; - - FD_SET(m_pipeEnds[0], &readfds); - - int ret; - int savedSelectErrno; - ret = qt_socket_select(maxfd, &readfds, &writefds, &exceptionfds, 0); - savedSelectErrno = errno; - - if(ret == 0) { - // do nothing - } else if (ret < 0) { - switch (savedSelectErrno) { - case EBADF: - case EINVAL: - case ENOMEM: - case EFAULT: - qWarning("::select() returned an error: %i", savedSelectErrno); - break; - case ECONNREFUSED: - case EPIPE: - qWarning("::select() returned an error: %i (go through sockets)", savedSelectErrno); - // prepare to go through all sockets - // mark in fd sets both: - // good ones - // ones that return -1 in select - // after loop update notifiers for all of them - - // as we don't have "exception" notifier type - // we should force monitoring fd_set of this - // type as well - - // clean @ start - FD_ZERO(&readfds); - FD_ZERO(&writefds); - FD_ZERO(&exceptionfds); - for (QHash::const_iterator i = m_AOStatuses.begin(); - i != m_AOStatuses.end(); ++i) { - - fd_set onefds; - FD_ZERO(&onefds); - FD_SET(i.key()->socket(), &onefds); - - fd_set excfds; - FD_ZERO(&excfds); - FD_SET(i.key()->socket(), &excfds); - - maxfd = i.key()->socket() + 1; - - struct timeval timeout; - timeout.tv_sec = 0; - timeout.tv_usec = 0; - - ret = 0; - - if(i.key()->type() == QSocketNotifier::Read) { - ret = ::select(maxfd, &onefds, 0, &excfds, &timeout); - if(ret != 0) FD_SET(i.key()->socket(), &readfds); - } else if(i.key()->type() == QSocketNotifier::Write) { - ret = ::select(maxfd, 0, &onefds, &excfds, &timeout); - if(ret != 0) FD_SET(i.key()->socket(), &writefds); - } - - } // end for - - // traversed all, so update - updateActivatedNotifiers(QSocketNotifier::Exception, &exceptionfds); - updateActivatedNotifiers(QSocketNotifier::Read, &readfds); - updateActivatedNotifiers(QSocketNotifier::Write, &writefds); - - break; - case EINTR: // Should never occur on Symbian, but this is future proof! - default: - qWarning("::select() returned an unknown error: %i", savedSelectErrno); - - break; - } - } else { - updateActivatedNotifiers(QSocketNotifier::Exception, &exceptionfds); - updateActivatedNotifiers(QSocketNotifier::Read, &readfds); - updateActivatedNotifiers(QSocketNotifier::Write, &writefds); - } - - if (FD_ISSET(m_pipeEnds[0], &readfds)) - m_waitCond.wait(&m_mutex); - } - - m_mutex.unlock(); -} - -void QSelectThread::requestSocketEvents ( QSocketNotifier *notifier, TRequestStatus *status ) -{ - Q_D(QThread); - - if (!isRunning()) { - start(); - } - - Q_ASSERT(QThread::currentThread() == this->thread()); - - QSelectMutexGrabber lock(m_pipeEnds[1], m_pipeEnds[0], &m_mutex); - - Q_ASSERT(!m_AOStatuses.contains(notifier)); - - m_AOStatuses.insert(notifier, status); - - m_waitCond.wakeAll(); -} - -void QSelectThread::cancelSocketEvents ( QSocketNotifier *notifier ) -{ - Q_ASSERT(QThread::currentThread() == this->thread()); - - QSelectMutexGrabber lock(m_pipeEnds[1], m_pipeEnds[0], &m_mutex); - - m_AOStatuses.remove(notifier); - - m_waitCond.wakeAll(); -} - -void QSelectThread::restart() -{ - Q_ASSERT(QThread::currentThread() == this->thread()); - - QSelectMutexGrabber lock(m_pipeEnds[1], m_pipeEnds[0], &m_mutex); - - m_waitCond.wakeAll(); -} - -int QSelectThread::updateSocketSet(QSocketNotifier::Type type, fd_set *fds) -{ - int maxfd = 0; - if(m_AOStatuses.isEmpty()) { - /* - * Wonder if should return -1 - * to signal that no descriptors - * added to fds - */ - return maxfd; - } - for ( QHash::const_iterator i = m_AOStatuses.begin(); - i != m_AOStatuses.end(); ++i) { - if (i.key()->type() == type) { - FD_SET(i.key()->socket(), fds); - maxfd = qMax(maxfd, i.key()->socket()); - } else if(type == QSocketNotifier::Exception) { - /* - * We are registering existing sockets - * always to exception set - * - * Doing double FD_SET shouldn't - * matter - */ - FD_SET(i.key()->socket(), fds); - maxfd = qMax(maxfd, i.key()->socket()); - } - } - - return maxfd; -} - -void QSelectThread::updateActivatedNotifiers(QSocketNotifier::Type type, fd_set *fds) -{ - Q_D(QThread); - if(m_AOStatuses.isEmpty()) { - return; - } - QList toRemove; - for (QHash::const_iterator i = m_AOStatuses.begin(); - i != m_AOStatuses.end(); ++i) { - if (i.key()->type() == type && FD_ISSET(i.key()->socket(), fds)) { - toRemove.append(i.key()); - TRequestStatus *status = i.value(); - // Thread data is still owned by the main thread. - QEventDispatcherSymbian::RequestComplete(d->threadData->symbian_thread_handle, status, KErrNone); - } else if(type == QSocketNotifier::Exception && FD_ISSET(i.key()->socket(), fds)) { - /* - * check if socket is in exception set - * then signal RequestComplete for it - */ - qWarning("exception on %d [will close the socket handle - hack]", i.key()->socket()); - // quick fix; there is a bug - // when doing read on socket - // errors not preoperly mapped - // after offline-ing the device - // on some devices we do get exception - ::close(i.key()->socket()); - toRemove.append(i.key()); - TRequestStatus *status = i.value(); - QEventDispatcherSymbian::RequestComplete(d->threadData->symbian_thread_handle, status, KErrNone); - } - } - - for (int c = 0; c < toRemove.size(); ++c) { - m_AOStatuses.remove(toRemove[c]); - } -} - -void QSelectThread::stop() -{ - m_quit = true; - restart(); - wait(); -} - -QSocketActiveObject::QSocketActiveObject(QEventDispatcherSymbian *dispatcher, QSocketNotifier *notifier) - : QActiveObject(CActive::EPriorityStandard, dispatcher), - m_notifier(notifier), - m_inSocketEvent(false), - m_deleteLater(false) -{ - CActiveScheduler::Add(this); - iStatus = KRequestPending; - SetActive(); -} - -QSocketActiveObject::~QSocketActiveObject() -{ - Cancel(); -} - -void QSocketActiveObject::DoCancel() -{ - if (iStatus.Int() == KRequestPending) { - TRequestStatus *status = &iStatus; - QEventDispatcherSymbian::RequestComplete(status, KErrNone); - } -} - -void QSocketActiveObject::RunL() -{ - if (maybeDeferSocketEvent()) - return; - if (maybeQueueForLater()) - return; - - QT_TRYCATCH_LEAVING(run()); -} - -void QSocketActiveObject::run() -{ - QEvent e(QEvent::SockAct); - m_inSocketEvent = true; - QCoreApplication::sendEvent(m_notifier, &e); - m_inSocketEvent = false; - - if (m_deleteLater) { - delete this; - } else { - iStatus = KRequestPending; - SetActive(); - m_dispatcher->reactivateSocketNotifier(m_notifier); - } -} - -void QSocketActiveObject::deleteLater() -{ - if (m_inSocketEvent) { - m_deleteLater = true; - } else { - delete this; - } -} - -#ifdef QT_SYMBIAN_PRIORITY_DROP -class QIdleDetectorThread -{ -public: - QIdleDetectorThread() - : m_state(STATE_RUN), m_stop(false), m_running(false) - { - start(); - } - - ~QIdleDetectorThread() - { - stop(); - } - - void start() - { - QMutexLocker lock(&m_mutex); - if (m_running) - return; - m_stop = false; - m_state = STATE_RUN; - TInt err = m_idleDetectorThread.Create(KNullDesC(), &idleDetectorThreadFunc, 1024, &User::Allocator(), this); - if (err != KErrNone) - return; // Fail silently on error. Next kick will try again. Exception might stop the event being processed - m_idleDetectorThread.SetPriority(EPriorityAbsoluteBackgroundNormal); - m_idleDetectorThread.Resume(); - m_running = true; - // get a callback from QCoreApplication destruction to stop this thread - qAddPostRoutine(StopIdleDetectorThread); - } - - void stop() - { - QMutexLocker lock(&m_mutex); - if (!m_running) - return; - // close down the idle thread because if corelib is loaded temporarily, this would leak threads into the host process - m_stop = true; - m_kick.release(); - m_idleDetectorThread.SetPriority(EPriorityNormal); - TRequestStatus s; - m_idleDetectorThread.Logon(s); - User::WaitForRequest(s); - m_idleDetectorThread.Close(); - m_running = false; - } - - void kick() - { - start(); - m_state = STATE_KICKED; - m_kick.release(); - } - - bool hasRun() - { - return m_state == STATE_RUN; - } - -private: - static TInt idleDetectorThreadFunc(TAny* self) - { - User::RenameThread(_L("IdleDetectorThread")); - static_cast(self)->IdleLoop(); - return KErrNone; - } - - void IdleLoop() - { - while (!m_stop) { - m_kick.acquire(); - m_state = STATE_RUN; - } - } - - static void StopIdleDetectorThread(); - -private: - enum IdleStates {STATE_KICKED, STATE_RUN} m_state; - bool m_stop; - bool m_running; - RThread m_idleDetectorThread; - QSemaphore m_kick; - QMutex m_mutex; -}; - -Q_GLOBAL_STATIC(QIdleDetectorThread, idleDetectorThread); - -void QIdleDetectorThread::StopIdleDetectorThread() -{ - idleDetectorThread()->stop(); -} - -const int maxBusyTime = 2000; // maximum time we allow idle detector to be blocked before worrying, in milliseconds -const int baseDelay = 1000; // minimum delay time used when backing off to allow idling, in microseconds -#endif - -QEventDispatcherSymbian::QEventDispatcherSymbian(QObject *parent) - : QAbstractEventDispatcher(parent), - m_selectThread(0), - m_activeScheduler(0), - m_wakeUpAO(0), - m_completeDeferredAOs(0), - m_interrupt(false), - m_wakeUpDone(0), - m_iterationCount(0), - m_insideTimerEvent(false), - m_noSocketEvents(false) -{ -#ifdef QT_SYMBIAN_PRIORITY_DROP - m_delay = baseDelay; - m_avgEventTime = 0; - idleDetectorThread(); -#endif -} - -QEventDispatcherSymbian::~QEventDispatcherSymbian() -{ -} - -void QEventDispatcherSymbian::startingUp() -{ - if( !CActiveScheduler::Current() ) { - m_activeScheduler = q_check_ptr(new CQtActiveScheduler()); // CBase derived class needs to be checked on new - CActiveScheduler::Install(m_activeScheduler); - } - m_wakeUpAO = q_check_ptr(new QWakeUpActiveObject(this)); - m_completeDeferredAOs = q_check_ptr(new QCompleteDeferredAOs(this)); - // We already might have posted events, wakeup once to process them - wakeUp(); -} - -QSelectThread& QEventDispatcherSymbian::selectThread() { - if (!m_selectThread) - m_selectThread = new QSelectThread; - return *m_selectThread; -} - -void QEventDispatcherSymbian::closingDown() -{ - if (m_selectThread && m_selectThread->isRunning()) { - m_selectThread->stop(); - } - delete m_selectThread; - m_selectThread = 0; - - delete m_completeDeferredAOs; - delete m_wakeUpAO; - if (m_activeScheduler) { - delete m_activeScheduler; - } -} - -bool QEventDispatcherSymbian::processEvents ( QEventLoop::ProcessEventsFlags flags ) -{ - bool handledAnyEvent = false; - bool oldNoSocketEventsValue = m_noSocketEvents; - bool oldInsideTimerEventValue = m_insideTimerEvent; - - m_insideTimerEvent = false; - - QT_TRY { - Q_D(QAbstractEventDispatcher); - - // It is safe if this counter overflows. The main importance is that each - // iteration count is different from the last. - m_iterationCount++; - - RThread &thread = d->threadData->symbian_thread_handle; - - bool block; - if (flags & QEventLoop::WaitForMoreEvents) { - block = true; - emit aboutToBlock(); - } else { - block = false; - } - - if (flags & QEventLoop::ExcludeSocketNotifiers) { - m_noSocketEvents = true; - } else { - m_noSocketEvents = false; - handledAnyEvent = sendDeferredSocketEvents(); - } - - bool handledSymbianEvent = false; - m_interrupt = false; - -#ifdef QT_SYMBIAN_PRIORITY_DROP - QElapsedTimer eventTimer; -#endif - - while (1) { - if (block) { - // This is where Qt will spend most of its time. - CActiveScheduler::Current()->WaitForAnyRequest(); - } else { - if (thread.RequestCount() == 0) { -#ifdef QT_SYMBIAN_PRIORITY_DROP - if (idleDetectorThread()->hasRun()) { - m_lastIdleRequestTimer.start(); - idleDetectorThread()->kick(); - } else if (m_lastIdleRequestTimer.elapsed() > maxBusyTime) { - User::AfterHighRes(m_delay); - } -#endif - break; - } - // This one should return without delay. - CActiveScheduler::Current()->WaitForAnyRequest(); - } - -#ifdef QT_SYMBIAN_PRIORITY_DROP - if (idleDetectorThread()->hasRun()) { - if (m_delay > baseDelay) - m_delay -= baseDelay; - m_lastIdleRequestTimer.start(); - idleDetectorThread()->kick(); - } else if (m_lastIdleRequestTimer.elapsed() > maxBusyTime) { - User::AfterHighRes(m_delay); - // allow delay to be up to 1/4 of execution time - if (!idleDetectorThread()->hasRun() && m_delay*3 < m_avgEventTime) - m_delay += baseDelay; - } - eventTimer.start(); -#endif - - TInt error; - handledSymbianEvent = CActiveScheduler::RunIfReady(error, KMinTInt); - if (error) { - qWarning("CActiveScheduler::RunIfReady() returned error: %i\n", error); - CActiveScheduler::Current()->Error(error); - } - -#ifdef QT_SYMBIAN_PRIORITY_DROP - int eventDur = eventTimer.elapsed()*1000; - // average is calcualted as a 5% decaying exponential average - m_avgEventTime = (m_avgEventTime * 95 + eventDur * 5) / 100; -#endif - - if (!handledSymbianEvent) { - qFatal("QEventDispatcherSymbian::processEvents(): Caught Symbian stray signal"); - } - handledAnyEvent = true; - if (m_interrupt) { - break; - } - block = false; - }; - - emit awake(); - } QT_CATCH (const std::exception& ex) { -#ifndef QT_NO_EXCEPTIONS - CActiveScheduler::Current()->Error(qt_symbian_exception2Error(ex)); -#endif - } - - m_noSocketEvents = oldNoSocketEventsValue; - m_insideTimerEvent = oldInsideTimerEventValue; - - return handledAnyEvent; -} - -void QEventDispatcherSymbian::timerFired(int timerId) -{ - QHash::iterator i = m_timerList.find(timerId); - if (i == m_timerList.end()) { - // The timer has been deleted. Ignore this event. - return; - } - - SymbianTimerInfoPtr timerInfo = *i; - - // Prevent infinite timer recursion. - if (timerInfo->inTimerEvent) { - return; - } - - timerInfo->inTimerEvent = true; - bool oldInsideTimerEventValue = m_insideTimerEvent; - m_insideTimerEvent = true; - - QTimerEvent event(timerInfo->timerId); - QCoreApplication::sendEvent(timerInfo->receiver, &event); - - m_insideTimerEvent = oldInsideTimerEventValue; - timerInfo->inTimerEvent = false; - - return; -} - -void QEventDispatcherSymbian::wakeUpWasCalled() -{ - // The reactivation should happen in RunL, right before the call to this function. - // This is because m_wakeUpDone is the "signal" that the object can be completed - // once more. - // Also, by dispatching the posted events after resetting m_wakeUpDone, we guarantee - // that no posted event notification will be lost. If we did it the other way - // around, it would be possible for another thread to post an event right after - // the sendPostedEvents was done, but before the object was ready to be completed - // again. This could deadlock the application if there are no other posted events. - m_wakeUpDone.fetchAndStoreOrdered(0); - sendPostedEvents(); -} - -void QEventDispatcherSymbian::interrupt() -{ - m_interrupt = true; - wakeUp(); -} - -void QEventDispatcherSymbian::wakeUp() -{ - Q_D(QAbstractEventDispatcher); - - if (m_wakeUpAO && m_wakeUpDone.testAndSetAcquire(0, 1)) { - TRequestStatus *status = &m_wakeUpAO->iStatus; - QEventDispatcherSymbian::RequestComplete(d->threadData->symbian_thread_handle, status, KErrNone); - } -} - -bool QEventDispatcherSymbian::sendPostedEvents() -{ - Q_D(QAbstractEventDispatcher); - - // moveToThread calls this and canWait == true -> Events will never get processed - // if we check for d->threadData->canWait - // - // QCoreApplication::postEvent sets canWait = false, but after the object and events - // are moved to a new thread, the canWait in new thread is true i.e. not changed to reflect - // the flag on old thread. That's why events in a new thread will not get processed. - // This migth be actually bug in moveToThread functionality, but because other platforms - // do not check canWait in wakeUp (where we essentially are now) - decided to remove it from - // here as well. - - //if (!d->threadData->canWait) { - QCoreApplicationPrivate::sendPostedEvents(0, 0, d->threadData); - return true; - //} - //return false; -} - -inline void QEventDispatcherSymbian::addDeferredActiveObject(QActiveObject *object) -{ - queueDeferredActiveObjectsCompletion(); - m_deferredActiveObjects.append(object); -} - -inline void QEventDispatcherSymbian::removeDeferredActiveObject(QActiveObject *object) -{ - m_deferredActiveObjects.removeAll(object); - m_deferredSocketEvents.removeAll(object); -} - -inline void QEventDispatcherSymbian::addDeferredSocketActiveObject(QActiveObject *object) -{ - m_deferredSocketEvents.append(object); -} - -void QEventDispatcherSymbian::queueDeferredActiveObjectsCompletion() -{ - m_completeDeferredAOs->complete(); -} - -void QEventDispatcherSymbian::reactivateDeferredActiveObjects() -{ - while (!m_deferredActiveObjects.isEmpty()) { - QActiveObject *object = m_deferredActiveObjects.takeFirst(); - object->reactivateAndComplete(); - } - - // We do this because we want to return from processEvents. This is because - // each invocation of processEvents should only run each active object once. - // The active scheduler should run them continously, however. - m_interrupt = true; -} - -bool QEventDispatcherSymbian::sendDeferredSocketEvents() -{ - bool sentAnyEvents = false; - while (!m_deferredSocketEvents.isEmpty()) { - sentAnyEvents = true; - QActiveObject *object = m_deferredSocketEvents.takeFirst(); - object->reactivateAndComplete(); - } - - return sentAnyEvents; -} - -void QEventDispatcherSymbian::flush() -{ -} - -bool QEventDispatcherSymbian::hasPendingEvents() -{ - Q_D(QAbstractEventDispatcher); - return (d->threadData->symbian_thread_handle.RequestCount() != 0 - || !d->threadData->canWait || !m_deferredSocketEvents.isEmpty()); -} - -void QEventDispatcherSymbian::registerSocketNotifier ( QSocketNotifier * notifier ) -{ - //check socket descriptor is usable - if (notifier->socket() >= FD_SETSIZE || notifier->socket() < 0) { - //same warning message as the unix event dispatcher for easy testing - qWarning("QSocketNotifier: Internal error"); - return; - } - //note - this is only for "open C" file descriptors - //for native sockets, an active object in the symbian socket engine handles this - QSocketActiveObject *socketAO = new QSocketActiveObject(this, notifier); - Q_CHECK_PTR(socketAO); - m_notifiers.insert(notifier, socketAO); - selectThread().requestSocketEvents(notifier, &socketAO->iStatus); -} - -void QEventDispatcherSymbian::unregisterSocketNotifier ( QSocketNotifier * notifier ) -{ - //note - this is only for "open C" file descriptors - //for native sockets, an active object in the symbian socket engine handles this - if (m_selectThread) - m_selectThread->cancelSocketEvents(notifier); - if (m_notifiers.contains(notifier)) { - QSocketActiveObject *sockObj = *m_notifiers.find(notifier); - m_deferredSocketEvents.removeAll(sockObj); - sockObj->deleteLater(); - m_notifiers.remove(notifier); - } -} - -void QEventDispatcherSymbian::reactivateSocketNotifier(QSocketNotifier *notifier) -{ - selectThread().requestSocketEvents(notifier, &m_notifiers[notifier]->iStatus); -} - -void QEventDispatcherSymbian::registerTimer ( int timerId, int interval, QObject * object ) -{ - if (interval < 0) { - qWarning("Timer interval < 0"); - interval = 0; - } - - SymbianTimerInfoPtr timer(new SymbianTimerInfo); - timer->timerId = timerId; - timer->interval = interval; - timer->inTimerEvent = false; - timer->receiver = object; - timer->dispatcher = this; - timer->timerAO = q_check_ptr(new QTimerActiveObject(this, timer.data())); - m_timerList.insert(timerId, timer); - - timer->timerAO->Start(); - - if (m_insideTimerEvent) - // If we are inside a timer event, we need to prevent event starvation - // by preventing newly created timers from running in the same event processing - // iteration. Do this by calling the maybeQueueForLater() function to "fake" that we have - // already run once. This will cause the next run to be added to the deferred - // queue instead. - timer->timerAO->maybeQueueForLater(); -} - -bool QEventDispatcherSymbian::unregisterTimer ( int timerId ) -{ - if (!m_timerList.contains(timerId)) { - return false; - } - - SymbianTimerInfoPtr timerInfo = m_timerList.take(timerId); - - if (!QObjectPrivate::get(timerInfo->receiver)->inThreadChangeEvent) - QAbstractEventDispatcherPrivate::releaseTimerId(timerId); - - return true; -} - -bool QEventDispatcherSymbian::unregisterTimers ( QObject * object ) -{ - if (m_timerList.isEmpty()) - return false; - - bool unregistered = false; - for (QHash::iterator i = m_timerList.begin(); i != m_timerList.end(); ) { - if ((*i)->receiver == object) { - i = m_timerList.erase(i); - unregistered = true; - } else { - ++i; - } - } - - return unregistered; -} - -QList QEventDispatcherSymbian::registeredTimers ( QObject * object ) const -{ - QList list; - for (QHash::const_iterator i = m_timerList.begin(); i != m_timerList.end(); ++i) { - if ((*i)->receiver == object) { - list.push_back(TimerInfo((*i)->timerId, (*i)->interval)); - } - } - - return list; -} - -/* - * This active scheduler class implements a simple report and continue policy, for Symbian OS leaves - * or exceptions from Qt that fall back to the scheduler. - * It will be used in cases where there is no existing active scheduler installed. - * Apps which link to qts60main.lib will have the UI active scheduler installed in the main thread - * instead of this one. But this would be used in other threads in the UI. - * An app could replace this behaviour by installing an alternative active scheduler. - */ -void CQtActiveScheduler::Error(TInt aError) const -{ - QT_TRY { - qWarning("Error from active scheduler %d", aError); - } - QT_CATCH (const std::bad_alloc&) {} // ignore alloc fails, nothing more can be done -} - -bool QActiveObject::wait(CActive* ao, int ms) -{ - if (!ao->IsActive()) - return true; //request already complete - bool timedout = false; - if (ms > 0) { - TRequestStatus tstat; - RTimer t; - if (KErrNone != t.CreateLocal()) - return false; - t.HighRes(tstat, ms*1000); - User::WaitForRequest(tstat, ao->iStatus); - if (tstat != KRequestPending) { - timedout = true; - } else { - t.Cancel(); - //balance thread semaphore - User::WaitForRequest(tstat); - } - t.Close(); - } else { - User::WaitForRequest(ao->iStatus); - } - if (timedout) - return false; - - //evil cast to allow calling of protected virtual - ((QActiveObject*)ao)->RunL(); - - //clear active & pending flags - ao->iStatus = TRequestStatus(); - - return true; -} - -bool QActiveObject::wait(QList aos, int ms) -{ - QVector stati; - stati.reserve(aos.count() + 1); - foreach (CActive* ao, aos) { - if (!ao->IsActive()) - return true; //request already complete - stati.append(&(ao->iStatus)); - } - bool timedout = false; - TRequestStatus tstat; - RTimer t; - if (ms > 0) { - if (KErrNone != t.CreateLocal()) - return false; - t.HighRes(tstat, ms*1000); - stati.append(&tstat); - } - User::WaitForNRequest(stati.data(), stati.count()); - if (ms > 0) { - if (tstat != KRequestPending) { - timedout = true; - } else { - t.Cancel(); - //balance thread semaphore - User::WaitForRequest(tstat); - } - t.Close(); - } - if (timedout) - return false; - - foreach (CActive* ao, aos) { - if (ao->iStatus != KRequestPending) { - //evil cast to allow calling of protected virtual - ((QActiveObject*)ao)->RunL(); - - //clear active & pending flags - ao->iStatus = TRequestStatus(); - break; //only call one - } - } - return true; -} - -QT_END_NAMESPACE - -#include "moc_qeventdispatcher_symbian_p.cpp" diff --git a/src/corelib/kernel/qeventdispatcher_symbian_p.h b/src/corelib/kernel/qeventdispatcher_symbian_p.h deleted file mode 100644 index e327a9cdc5..0000000000 --- a/src/corelib/kernel/qeventdispatcher_symbian_p.h +++ /dev/null @@ -1,327 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the QtCore module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QEVENTDISPATCHER_SYMBIAN_P_H -#define QEVENTDISPATCHER_SYMBIAN_P_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists purely as an -// implementation detail. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include -#include -#include - -QT_BEGIN_NAMESPACE - - -class QEventDispatcherSymbian; -class QTimerActiveObject; - -class Q_CORE_EXPORT QActiveObject : public CActive -{ -public: - QActiveObject(TInt priority, QEventDispatcherSymbian *dispatcher); - ~QActiveObject(); - - bool maybeQueueForLater(); - bool maybeDeferSocketEvent(); - - void reactivateAndComplete(); - - static bool wait(CActive* ao, int ms); - static bool wait(QList aos, int ms); -protected: - QEventDispatcherSymbian *m_dispatcher; - -private: - bool m_hasAlreadyRun : 1; - bool m_hasRunAgain : 1; - int m_iterationCount; -}; - -class QWakeUpActiveObject : public QActiveObject -{ -public: - QWakeUpActiveObject(QEventDispatcherSymbian *dispatcher); - ~QWakeUpActiveObject(); - - void Complete(); - -protected: - void DoCancel(); - void RunL(); - -private: - TThreadId m_hostThreadId; -}; - -struct SymbianTimerInfo : public QSharedData -{ - SymbianTimerInfo(); - ~SymbianTimerInfo(); - - int timerId; - int interval; - int msLeft; - bool inTimerEvent; - QObject *receiver; - QTimerActiveObject *timerAO; - QEventDispatcherSymbian *dispatcher; -}; - -typedef QExplicitlySharedDataPointer SymbianTimerInfoPtr; - -// This is a bit of a proxy class. See comments in SetActive and Start for details. -class QTimerActiveObject : public QActiveObject -{ -public: - QTimerActiveObject(QEventDispatcherSymbian *dispatcher, SymbianTimerInfo *timerInfo); - ~QTimerActiveObject(); - - void Start(); - -protected: - void DoCancel(); - void RunL(); - -private: - void Run(); - void StartTimer(); - -private: - SymbianTimerInfo *m_timerInfo; - QElapsedTimer m_timeoutTimer; - int m_expectedTimeSinceLastEvent; - RTimer m_rTimer; -}; - -class QCompleteDeferredAOs : public CActive -{ -public: - QCompleteDeferredAOs(QEventDispatcherSymbian *dispatcher); - ~QCompleteDeferredAOs(); - - void complete(); - -protected: - void DoCancel(); - void RunL(); - -private: - QEventDispatcherSymbian *m_dispatcher; -}; - -class QSocketActiveObject : public QActiveObject -{ -public: - QSocketActiveObject(QEventDispatcherSymbian *dispatcher, QSocketNotifier *notifier); - ~QSocketActiveObject(); - - void deleteLater(); - -protected: - void DoCancel(); - void RunL(); - void run(); - -private: - QSocketNotifier *m_notifier; - bool m_inSocketEvent; - bool m_deleteLater; - - friend class QEventDispatcherSymbian; -}; - -class QSelectThread : public QThread -{ - Q_DECLARE_PRIVATE(QThread) - -public: - QSelectThread(); - ~QSelectThread(); - - void requestSocketEvents ( QSocketNotifier *notifier, TRequestStatus *status ); - void cancelSocketEvents ( QSocketNotifier *notifier ); - void restart(); - void stop(); - -protected: - void run(); - -private: - int updateSocketSet(QSocketNotifier::Type type, fd_set *fds); - void updateActivatedNotifiers(QSocketNotifier::Type type, fd_set *fds); - -private: - int m_pipeEnds[2]; - QHash m_AOStatuses; - QMutex m_mutex; - QWaitCondition m_waitCond; - bool m_quit; -}; - -class Q_CORE_EXPORT CQtActiveScheduler : public CActiveScheduler -{ -public: // from CActiveScheduler - virtual void Error(TInt aError) const; -}; - -class Q_CORE_EXPORT QEventDispatcherSymbian : public QAbstractEventDispatcher -{ - Q_OBJECT - Q_DECLARE_PRIVATE(QAbstractEventDispatcher) - -public: - QEventDispatcherSymbian(QObject *parent = 0); - ~QEventDispatcherSymbian(); - - void flush(); - bool hasPendingEvents(); - void interrupt(); - bool processEvents ( QEventLoop::ProcessEventsFlags flags ); - void registerSocketNotifier ( QSocketNotifier * notifier ); - void registerTimer ( int timerId, int interval, QObject * object ); - QList registeredTimers ( QObject * object ) const; - void unregisterSocketNotifier ( QSocketNotifier * notifier ); - bool unregisterTimer ( int timerId ); - bool unregisterTimers ( QObject * object ); - void wakeUp(); - - void startingUp(); - void closingDown(); - - void timerFired(int timerId); - void wakeUpWasCalled(); - void reactivateSocketNotifier(QSocketNotifier *notifier); - - void addDeferredActiveObject(QActiveObject *object); - void removeDeferredActiveObject(QActiveObject *object); - void queueDeferredActiveObjectsCompletion(); - // Can be overridden to activate local active objects too, but do call baseclass! - virtual void reactivateDeferredActiveObjects(); - - inline int iterationCount() const { return m_iterationCount; } - - void addDeferredSocketActiveObject(QActiveObject *object); - inline bool areSocketEventsBlocked() const { return m_noSocketEvents; } - - static void RequestComplete(TRequestStatus *&status, TInt reason); - static void RequestComplete(RThread &threadHandle, TRequestStatus *&status, TInt reason); - -private: - bool sendPostedEvents(); - bool sendDeferredSocketEvents(); - - QSelectThread& selectThread(); -private: - QSelectThread *m_selectThread; - - CQtActiveScheduler *m_activeScheduler; - - QHash m_timerList; - QHash m_notifiers; - - QWakeUpActiveObject *m_wakeUpAO; - QCompleteDeferredAOs *m_completeDeferredAOs; - - volatile bool m_interrupt; - QAtomicInt m_wakeUpDone; - - unsigned char m_iterationCount; - bool m_insideTimerEvent; - bool m_noSocketEvents; - //deferred until socket events are enabled - QList m_deferredSocketEvents; - //deferred until idle - QList m_deferredActiveObjects; - - int m_delay; - int m_avgEventTime; - QElapsedTimer m_lastIdleRequestTimer; -}; - -#ifdef QT_DEBUG -# define VERIFY_PENDING_REQUEST_STATUS \ - Q_ASSERT(status->Int() == KRequestPending); -#else -# define VERIFY_PENDING_REQUEST_STATUS -#endif - -// Convenience functions for doing some sanity checking on our own complete code. -// Unless QT_DEBUG is defined, it is exactly equivalent to the Symbian version. -inline void QEventDispatcherSymbian::RequestComplete(TRequestStatus *&status, TInt reason) -{ - VERIFY_PENDING_REQUEST_STATUS - User::RequestComplete(status, reason); -} -inline void QEventDispatcherSymbian::RequestComplete(RThread &threadHandle, TRequestStatus *&status, TInt reason) -{ - VERIFY_PENDING_REQUEST_STATUS - threadHandle.RequestComplete(status, reason); -} - -#undef VERIFY_PENDING_REQUEST_STATUS - -QT_END_NAMESPACE - -#endif // QEVENTDISPATCHER_SYMBIAN_P_H diff --git a/src/corelib/kernel/qsharedmemory_symbian.cpp b/src/corelib/kernel/qsharedmemory_symbian.cpp deleted file mode 100644 index fdd513a475..0000000000 --- a/src/corelib/kernel/qsharedmemory_symbian.cpp +++ /dev/null @@ -1,173 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the QtCore module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qsharedmemory.h" -#include "qsharedmemory_p.h" -#include "qsystemsemaphore.h" -#include "qcore_symbian_p.h" -#include - -QT_BEGIN_NAMESPACE - -#ifndef QT_NO_SHAREDMEMORY - -#define QSHAREDMEMORY_DEBUG - -QSharedMemoryPrivate::QSharedMemoryPrivate() : QObjectPrivate(), - memory(0), size(0), error(QSharedMemory::NoError), - systemSemaphore(QString()), lockedByMe(false) -{ -} - -void QSharedMemoryPrivate::setErrorString(const QString &function, TInt errorCode) -{ - if (errorCode == KErrNone) - return; - switch (errorCode) { - case KErrAlreadyExists: - error = QSharedMemory::AlreadyExists; - errorString = QSharedMemory::tr("%1: already exists").arg(function); - break; - case KErrNotFound: - error = QSharedMemory::NotFound; - errorString = QSharedMemory::tr("%1: doesn't exists").arg(function); - break; - case KErrArgument: - error = QSharedMemory::InvalidSize; - errorString = QSharedMemory::tr("%1: invalid size").arg(function); - break; - case KErrNoMemory: - error = QSharedMemory::OutOfResources; - errorString = QSharedMemory::tr("%1: out of resources").arg(function); - break; - case KErrPermissionDenied: - error = QSharedMemory::PermissionDenied; - errorString = QSharedMemory::tr("%1: permission denied").arg(function); - break; - default: - errorString = QSharedMemory::tr("%1: unknown error %2").arg(function).arg(errorCode); - error = QSharedMemory::UnknownError; -#if defined QSHAREDMEMORY_DEBUG - qDebug() << errorString << "key" << key; -#endif - } -} - -key_t QSharedMemoryPrivate::handle() -{ - // Not really cost effective to check here if shared memory is attachable, as it requires - // exactly the same call as attaching, so always assume handle is valid and return failure - // from attach. - return 1; -} - -bool QSharedMemoryPrivate::cleanHandle() -{ - chunk.Close(); - return true; -} - -bool QSharedMemoryPrivate::create(int size) -{ - QString function = QLatin1String("QSharedMemory::create"); - if (nativeKey.isEmpty()) { - error = QSharedMemory::KeyError; - errorString = QSharedMemory::tr("%1: key error").arg(function); - return false; - } - - TPtrC ptr(qt_QString2TPtrC(nativeKey)); - - TInt err = chunk.CreateGlobal(ptr, size, size); - - setErrorString(function, err); - - if (err != KErrNone) - return false; - - // Zero out the created chunk - Mem::FillZ(chunk.Base(), chunk.Size()); - - return true; -} - -bool QSharedMemoryPrivate::attach(QSharedMemory::AccessMode /* mode */) -{ - // Grab a pointer to the memory block - if (!chunk.Handle()) { - QString function = QLatin1String("QSharedMemory::handle"); - if (nativeKey.isEmpty()) { - error = QSharedMemory::KeyError; - errorString = QSharedMemory::tr("%1: unable to make key").arg(function); - return false; - } - - TPtrC ptr(qt_QString2TPtrC(nativeKey)); - - TInt err = KErrNoMemory; - - err = chunk.OpenGlobal(ptr, false); - - if (err != KErrNone) { - setErrorString(function, err); - return false; - } - } - - size = chunk.Size(); - memory = chunk.Base(); - - return true; -} - -bool QSharedMemoryPrivate::detach() -{ - chunk.Close(); - - memory = 0; - size = 0; - - return true; -} - -#endif //QT_NO_SHAREDMEMORY - -QT_END_NAMESPACE diff --git a/src/corelib/kernel/qsystemsemaphore_symbian.cpp b/src/corelib/kernel/qsystemsemaphore_symbian.cpp deleted file mode 100644 index 96c19afcfc..0000000000 --- a/src/corelib/kernel/qsystemsemaphore_symbian.cpp +++ /dev/null @@ -1,138 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the QtCore module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qsystemsemaphore.h" -#include "qsystemsemaphore_p.h" -#include "qcoreapplication.h" -#include - -#include "qcore_symbian_p.h" -#include -QT_BEGIN_NAMESPACE - -#ifndef QT_NO_SYSTEMSEMAPHORE - -QSystemSemaphorePrivate::QSystemSemaphorePrivate() : - error(QSystemSemaphore::NoError) -{ -} - -void QSystemSemaphorePrivate::setErrorString(const QString &function, int err) -{ - if (err == KErrNone){ - return; - } - switch(err){ - case KErrAlreadyExists: - errorString = QCoreApplication::tr("%1: already exists", "QSystemSemaphore").arg(function); - error = QSystemSemaphore::AlreadyExists; - break; - case KErrNotFound: - errorString = QCoreApplication::tr("%1: does not exist", "QSystemSemaphore").arg(function); - error = QSystemSemaphore::NotFound; - break; - case KErrNoMemory: - case KErrInUse: - errorString = QCoreApplication::tr("%1: out of resources", "QSystemSemaphore").arg(function); - error = QSystemSemaphore::OutOfResources; - break; - case KErrPermissionDenied: - errorString = QCoreApplication::tr("%1: permission denied", "QSystemSemaphore").arg(function); - error = QSystemSemaphore::PermissionDenied; - break; -default: - errorString = QCoreApplication::tr("%1: unknown error %2", "QSystemSemaphore").arg(function).arg(err); - error = QSystemSemaphore::UnknownError; - } - -#if defined QSYSTEMSEMAPHORE_DEBUG - qDebug() << errorString << "key" << key; -#endif -} - -int QSystemSemaphorePrivate::handle(QSystemSemaphore::AccessMode) -{ - if (semaphore.Handle()) { - return semaphore.Handle(); - } - - // don't allow making handles on empty keys - if (key.isEmpty()) - return 0; - - TPtrC name(qt_QString2TPtrC(fileName)); - int err = KErrAlreadyExists; - int tryCount = 10; - // Sort out race conditions by retrying several times until existing handle is acquired. - // Sometimes opening can fail inexplicably with KErrPermissionDenied many times in a row. - while (err != KErrNoMemory && err != KErrNone && tryCount-- >= 0) { - err = semaphore.CreateGlobal(name, initialValue, EOwnerProcess); - if (err != KErrNoMemory && err != KErrNone) - err = semaphore.OpenGlobal(name,EOwnerProcess); - } - if (err){ - setErrorString(QLatin1String("QSystemSemaphore::handle"),err); - return 0; - } - return semaphore.Handle(); -} - -void QSystemSemaphorePrivate::cleanHandle() -{ - semaphore.Close(); -} - -bool QSystemSemaphorePrivate::modifySemaphore(int count) -{ - if (0 == handle()) - return false; - - if (count > 0) { - semaphore.Signal(count); - } else { - semaphore.Wait(); - } - return true; -} - -#endif //QT_NO_SYSTEMSEMAPHORE - -QT_END_NAMESPACE -- cgit v1.2.3