Skip to content

Commit

Permalink
Merge branch 'symbian-socket-engine' of scm.dev.troll.no:qt/qt-symbia…
Browse files Browse the repository at this point in the history
…n-network

Conflicts:
	configure.exe
	src/s60installs/bwins/QtCoreu.def
	src/s60installs/bwins/QtGuiu.def
	src/s60installs/eabi/QtCoreu.def
  • Loading branch information
Shane Kearns committed Apr 12, 2011
2 parents f62e846 + d01f828 commit 04d1cbc
Show file tree
Hide file tree
Showing 124 changed files with 6,607 additions and 1,073 deletions.
8 changes: 2 additions & 6 deletions configure
Original file line number Diff line number Diff line change
Expand Up @@ -6533,13 +6533,9 @@ fi

# find if the platform supports IPv6
if [ "$CFG_IPV6" != "no" ]; then
#
# We accidently enabled IPv6 for Qt Symbian in 4.6.x. However the underlying OpenC does not fully support IPV6.
# Therefore for 4.7.1 and following we disable it until OpenC either supports it or we have the native Qt
# symbian socket engine.
#
if [ "$XPLATFORM_SYMBIAN" = "yes" ]; then
CFG_IPV6=no
#IPV6 should always be enabled for Symbian release
CFG_IPV6=yes
elif "$unixtests/compile.test" "$XQMAKESPEC" "$QMAKE_CONFIG" $OPT_VERBOSE "$relpath" "$outpath" config.tests/unix/ipv6 "IPv6" $L_FLAGS $I_FLAGS $l_FLAGS $MAC_CONFIG_TEST_COMMANDLINE; then
CFG_IPV6=yes
else
Expand Down
2 changes: 1 addition & 1 deletion src/corelib/io/io.pri
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ win32 {
SOURCES += io/qfilesystemwatcher_symbian.cpp
HEADERS += io/qfilesystemwatcher_symbian_p.h
INCLUDEPATH += $$MW_LAYER_SYSTEMINCLUDE
LIBS += -lplatformenv
LIBS += -lplatformenv -lesock
}
}
integrity {
Expand Down
2 changes: 0 additions & 2 deletions src/corelib/io/qfilesystemiterator_symbian.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -88,8 +88,6 @@ QFileSystemIterator::QFileSystemIterator(const QFileSystemEntry &path, QDir::Fil
else if (symbianMask == 0) {
if ((filters & QDir::PermissionMask) == QDir::Writable)
symbianMask = KEntryAttMatchExclude | KEntryAttReadOnly;
else if ((filters & QDir::PermissionMask) == QDir::Readable)
symbianMask = KEntryAttMatchExclusive | KEntryAttReadOnly;
}

lastError = dirHandle.Open(fs, qt_QString2TPtrC(absPath), symbianMask);
Expand Down
104 changes: 104 additions & 0 deletions src/corelib/kernel/qcore_symbian_p.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@
#include <e32uid.h>
#include "qcore_symbian_p.h"
#include <string>
#include <in_sock.h>

QT_BEGIN_NAMESPACE

Expand Down Expand Up @@ -203,11 +204,114 @@ class QS60RFsSession
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<const QHashableSocket &>(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<const QHashableSocket &>(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<const QHashableSocket &>(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
101 changes: 101 additions & 0 deletions src/corelib/kernel/qcore_symbian_p.h
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -154,6 +156,7 @@ 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);
Expand All @@ -174,6 +177,104 @@ struct QScopedPointerRCloser
}
};

//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<QHashableSocket, int> socketMap;
QHash<int, RSocket> reverseSocketMap;
mutable QMutex iMutex;
RSocketServ iSocketServ;
RConnection *iDefaultConnection;
};

QT_END_NAMESPACE

QT_END_HEADER
Expand Down
Loading

0 comments on commit 04d1cbc

Please sign in to comment.