summaryrefslogtreecommitdiffstats
path: root/src/corelib/kernel
diff options
context:
space:
mode:
authorShane Kearns <shane.kearns@accenture.com>2010-09-21 16:42:14 (GMT)
committerShane Kearns <shane.kearns@accenture.com>2010-12-01 15:44:49 (GMT)
commit5c7c12602f10be7625ee38efb31e1a8b5cb66c5b (patch)
tree1f2dd43b28203e061952f6e73010e41942d6a761 /src/corelib/kernel
parent3a5603966467a878e5b305517598589590cb8b10 (diff)
downloadQt-5c7c12602f10be7625ee38efb31e1a8b5cb66c5b.zip
Qt-5c7c12602f10be7625ee38efb31e1a8b5cb66c5b.tar.gz
Qt-5c7c12602f10be7625ee38efb31e1a8b5cb66c5b.tar.bz2
Prototype socket manager
To enable passing socket handles around as integers, need a two way mapping with RSocket. It's in corelib because of QSocketNotifier. This is also a convenient place to host the global RSocketServ session. Reviewed-By: Markus Goetz
Diffstat (limited to 'src/corelib/kernel')
-rw-r--r--src/corelib/kernel/qcore_symbian_p.cpp72
-rw-r--r--src/corelib/kernel/qcore_symbian_p.h67
2 files changed, 139 insertions, 0 deletions
diff --git a/src/corelib/kernel/qcore_symbian_p.cpp b/src/corelib/kernel/qcore_symbian_p.cpp
index df1c1ef..29996a4 100644
--- a/src/corelib/kernel/qcore_symbian_p.cpp
+++ b/src/corelib/kernel/qcore_symbian_p.cpp
@@ -210,4 +210,76 @@ Q_CORE_EXPORT RFs& qt_s60GetRFs()
return qt_s60_RFsSession()->GetRFs();
}
+QSymbianSocketManager::QSymbianSocketManager() :
+ iNextSocket(0)
+{
+ qt_symbian_throwIfError(iSocketServ.Connect());
+ 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(RSocket* sock) {
+ 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(RSocket* sock) {
+ 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(RSocket* sock) const {
+ QMutexLocker l(&iMutex);
+ if(!socketMap.contains(sock))
+ return -1;
+ int id = socketMap.value(sock);
+ return id + socket_offset;
+}
+
+RSocket* QSymbianSocketManager::lookupSocket(int fd) const {
+ QMutexLocker l(&iMutex);
+ int id = fd + socket_offset;
+ if(!reverseSocketMap.contains(id))
+ return 0;
+ return reverseSocketMap.value(id);
+}
+
+Q_GLOBAL_STATIC(QSymbianSocketManager, qt_symbianSocketManager);
+
+QSymbianSocketManager& QSymbianSocketManager::instance()
+{
+ return *(qt_symbianSocketManager());
+}
QT_END_NAMESPACE
diff --git a/src/corelib/kernel/qcore_symbian_p.h b/src/corelib/kernel/qcore_symbian_p.h
index 4a515ce..b6cba6e 100644
--- a/src/corelib/kernel/qcore_symbian_p.h
+++ b/src/corelib/kernel/qcore_symbian_p.h
@@ -55,10 +55,12 @@
#include <e32std.h>
#include <QtCore/qglobal.h>
+#include <QtCore/qmutex.h>
#include <qstring.h>
#include <qrect.h>
#include <qhash.h>
#include <f32file.h>
+#include <es_sock.h>
#define QT_LSTRING2(x) L##x
#define QT_LSTRING(x) QT_LSTRING2(x)
@@ -154,10 +156,75 @@ enum S60PluginFuncOrdinals
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);
+/*!
+ \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(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(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(RSocket *sock) const;
+ /*!
+ \internal
+ Get socket for a pseudo file descriptor
+ \param an open socket fd
+ \return socket handle or NULL if not in map
+ */
+ RSocket *lookupSocket(int fd) 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<RSocket *, int> socketMap;
+ QHash<int, RSocket *> reverseSocketMap;
+ mutable QMutex iMutex;
+ RSocketServ iSocketServ;
+};
+
QT_END_NAMESPACE
QT_END_HEADER