diff -r 885c2596c964 -r 5d007b20cfd0 qthighway/xqservice/src/xqservicethreaddata.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/qthighway/xqservice/src/xqservicethreaddata.cpp Tue Aug 31 16:02:37 2010 +0300 @@ -0,0 +1,227 @@ +/* +* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* +* This program is free software: you can redistribute it and/or modify +* it under the terms of the GNU Lesser General Public License as published by +* the Free Software Foundation, version 2.1 of the License. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public License +* along with this program. If not, +* see "http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html/". +* +* Description: +* +*/ + +#include "xqservicelog.h" + +#include "xqservicethreaddata.h" +#include "xqservicechannel.h" +#include "xqserviceipcclient.h" + +#include +#include + +#ifndef QT_NO_THREAD + +static QThreadStorage xqserviceThreadStorage; + +XQServiceThreadData *XQService::serviceThreadData() +{ + XQSERVICE_DEBUG_PRINT("XQService::serviceThreadData"); + if (!xqserviceThreadStorage.hasLocalData()) { + xqserviceThreadStorage.setLocalData(new XQServiceThreadData()); + } + return xqserviceThreadStorage.localData() ; +} + +#else + +Q_GLOBAL_STATIC(XQServiceThreadData, serviceThreadData); + +#endif + + +XQServiceThreadData *XQServiceThreadData::instance() +{ + XQSERVICE_DEBUG_PRINT("XQServiceThreadData::instance"); + return XQService::serviceThreadData(); +} + +XQServiceThreadData::~XQServiceThreadData() +{ + XQSERVICE_DEBUG_PRINT("XQServiceThreadData::~XQServiceThreadData"); + qDeleteAll(ipcConnMap); + ipcConnMap.clear(); +} + +QString XQServiceThreadData::getIpcConnectioName(const QString& channel) +{ + XQSERVICE_DEBUG_PRINT("XQServiceThreadData::getIpcConnectioName"); + XQSERVICE_DEBUG_PRINT("channel: %s", qPrintable(channel)); +/* + // name of the connection is the name of application without interface + int pos = channel.lastIndexOf('.'); + return pos != -1 ? channel.left(pos) : channel; +*/ + //TODO: this should avoid to have multiple connection in the same application if provide multiple interfaces + return channel; +} + +// Get the client connection object for this thread. +bool XQServiceThreadData::createClientConnection(const QString& channel, bool isServer, + bool isSync, XQServiceRequestCompletedAsync* rc, + const void *userData) +{ + XQSERVICE_DEBUG_PRINT("XQServiceThreadData::createClientConnection start"); + XQSERVICE_DEBUG_PRINT("channel: %s, isServer: %d, isSync: %d", qPrintable(channel), isServer, isSync); + XQSERVICE_DEBUG_PRINT("userdata: %x", (int)userData); + + QString ipcConName = getIpcConnectioName(channel); + XQSERVICE_DEBUG_PRINT("ipcConName: %s", qPrintable(ipcConName)); + XQServiceIpcClientMap::Iterator it = ipcConnMap.find(ipcConName); + if (it == ipcConnMap.end()) { + XQSERVICE_DEBUG_PRINT("Create new connection"); + // userData may be NULL ! + XQServiceIpcClient* conn = new XQServiceIpcClient(ipcConName,isServer,isSync,rc, userData); + if (conn) { + XQSERVICE_DEBUG_PRINT("conn created"); + bool ret=true; + if (isServer) { + XQSERVICE_DEBUG_PRINT("Listen server"); + ret=conn->listen(); + } + else { + XQSERVICE_DEBUG_PRINT("Connect to server"); + ret=conn->connectToServer(); + } + if (ret) { + XQSERVICE_DEBUG_PRINT("Add connection to mapping"); + it = ipcConnMap.insert(ipcConName, conn); + } + else { + XQSERVICE_DEBUG_PRINT("Couldn't connect"); + delete conn; + } + XQSERVICE_DEBUG_PRINT("\t ret: %d", ret); + XQSERVICE_DEBUG_PRINT("XQServiceThreadData::createClientConnection end (1)"); + return ret; + } + } + + XQSERVICE_DEBUG_PRINT("\t Connection already exists or creation failed"); + XQSERVICE_DEBUG_PRINT("XQServiceThreadData::createClientConnection end (2)"); + return false; +} + +// Get the client connection object for this thread. +XQServiceIpcClient *XQServiceThreadData::clientConnection(const QString& channel) +{ + XQSERVICE_DEBUG_PRINT("XQServiceThreadData::clientConnection"); + XQSERVICE_DEBUG_PRINT("channel: %s", qPrintable(channel)); + QString ipcConName = getIpcConnectioName(channel); + XQSERVICE_DEBUG_PRINT("ipcConName: %s", qPrintable(ipcConName)); + XQServiceIpcClientMap::Iterator it = ipcConnMap.find(ipcConName); + if (it == ipcConnMap.end()) { + XQSERVICE_DEBUG_PRINT("No client connection"); + return NULL; + } + return it.value(); +} + +void XQServiceThreadData::closeClientConnection(const QString& channel) +{ + XQSERVICE_DEBUG_PRINT("XQServiceThreadData::closeClientConnection"); + XQSERVICE_DEBUG_PRINT("channel: %s", qPrintable(channel)); + QString ipcConName = getIpcConnectioName(channel); + XQSERVICE_DEBUG_PRINT("ipcConName: %s", qPrintable(ipcConName)); + XQServiceIpcClientMap::Iterator it = ipcConnMap.find(ipcConName); + if (it != ipcConnMap.end()) { + XQSERVICE_DEBUG_PRINT("disconnect"); + it.value()->disconnected(); + ipcConnMap.erase(it); + } +} + +// Determine if we have a client connection object for this thread. +bool XQServiceThreadData::hasClientConnection(const QString& channel) +{ + XQSERVICE_DEBUG_PRINT("XQServiceThreadData::hasClientConnection"); + XQSERVICE_DEBUG_PRINT("channel: %s", qPrintable(channel)); + QString ipcConName = getIpcConnectioName(channel); + XQSERVICE_DEBUG_PRINT("ipcConName: %s", qPrintable(ipcConName)); + XQServiceIpcClientMap::Iterator it = ipcConnMap.find(ipcConName); + XQSERVICE_DEBUG_PRINT("hasClientConnection: %d", it != ipcConnMap.end()); + return it != ipcConnMap.end(); +} + +int XQServiceThreadData::latestError() +{ + XQSERVICE_DEBUG_PRINT("XQServiceThreadData::latestError"); + XQSERVICE_DEBUG_PRINT("m_latestError: %d", m_latestError); + return m_latestError; +} + +void XQServiceThreadData::setLatestError(int latestError) +{ + XQSERVICE_DEBUG_PRINT("XQServiceThreadData::setLatestError %d", latestError); + m_latestError = latestError; +} + +QByteArray XQServiceThreadData::serializeRetData(const QVariant &value, int error) +{ + XQSERVICE_DEBUG_PRINT("XQServiceThreadData::serializeRetData"); + XQSERVICE_DEBUG_PRINT("value type: %d, null?=%d, valid?=%d, error: %d", value.type(), value.isNull(), value.isValid(), error); + QByteArray array; + // if (!value.isNull() && (value.type() != QVariant::Invalid)) { maparnan + if (value.isValid()) { // + QDataStream stream(&array, QIODevice::WriteOnly | QIODevice::Append); + + stream << CmdRetData; + stream << value; + } + else { + if (error) + { + QVariant value(error); + QDataStream stream(&array, + QIODevice::WriteOnly | QIODevice::Append); + stream << CmdErrData; + stream << value; + } + } + return array; +} + +QVariant XQServiceThreadData::deserializeRetData(const QByteArray &retData) +{ + XQSERVICE_DEBUG_PRINT("XQServiceThreadData::deserializeRetData"); + XQSERVICE_DEBUG_PRINT("retData: %s", retData.constData()); + if (retData.length()) + { + QDataStream stream(retData); + int cmd ; + stream >> cmd ; + if (cmd == CmdRetData) + { + QVariant retServiceData(stream); + return retServiceData; + } + else + { + if (cmd == CmdErrData) + { + QVariant retServiceData(stream); + int error = retServiceData.toInt(); + XQService::serviceThreadData()->setLatestError(error); + } + } + } + return QVariant(); +}