From b07317dca7056aaefaa2ac6321869848a182fed1 Mon Sep 17 00:00:00 2001 From: goldenhawking Date: Fri, 5 Sep 2014 13:01:17 +0800 Subject: [PATCH] Sloved a serious problem in heavily client login-logoff. add a rubbish can, hold sockets to be deleted later --- .../cluster/zp_clusternode.cpp | 2 +- .../cluster/zp_clusterterm.cpp | 6 +- .../database/databaseresource.cpp | 39 ++++-- ZoomPipeline_FuncSvr/logger/st_logger.cpp | 37 +++++- ZoomPipeline_FuncSvr/logger/st_logger.h | 2 + ZoomPipeline_FuncSvr/main.cpp | 3 + .../network/zp_net_threadpool.cpp | 5 +- .../network/zp_nettransthread.cpp | 113 ++++++++++++++---- .../network/zp_nettransthread.h | 11 +- 9 files changed, 177 insertions(+), 41 deletions(-) diff --git a/ZoomPipeline_FuncSvr/cluster/zp_clusternode.cpp b/ZoomPipeline_FuncSvr/cluster/zp_clusternode.cpp index 199ea4a..6a51092 100644 --- a/ZoomPipeline_FuncSvr/cluster/zp_clusternode.cpp +++ b/ZoomPipeline_FuncSvr/cluster/zp_clusternode.cpp @@ -54,7 +54,7 @@ namespace ZP_Cluster{ { if (bTermSet==true) { - //qDebug()<0) emit evt_NewSvrDisconnected(nameCurr); - //qDebug()<ref()); + //qDebug()<ref()); } m_hash_mutex.unlock(); @@ -348,13 +348,13 @@ namespace ZP_Cluster{ toBedel.push_back(pdelobj); else { - //qDebug()<ref()); + //qDebug()<ref()); } } foreach(zp_ClusterNode * pdelobj,toBedel) { m_nodeToBeDel.removeAll(pdelobj); - //qDebug()<ref()); + //qDebug()<ref()); pdelobj->deleteLater(); } } diff --git a/ZoomPipeline_FuncSvr/database/databaseresource.cpp b/ZoomPipeline_FuncSvr/database/databaseresource.cpp index ca4a962..665dc3d 100644 --- a/ZoomPipeline_FuncSvr/database/databaseresource.cpp +++ b/ZoomPipeline_FuncSvr/database/databaseresource.cpp @@ -3,6 +3,7 @@ #include #include #include +#include namespace ZPDatabase{ @@ -29,7 +30,8 @@ namespace ZPDatabase{ db.close(); QSqlDatabase::removeDatabase(threadName); QString msg = "Database:"+tr(" Connection removed ")+threadName+ tr(" ."); - emit evt_Message(this,msg); + qDebug()<pos()>=m_nMaxFileSize) m_bUseLogFile = CreateNewLogFile(QCoreApplication::instance()); + m_mutextLogger.unlock(); } } diff --git a/ZoomPipeline_FuncSvr/logger/st_logger.h b/ZoomPipeline_FuncSvr/logger/st_logger.h index ee23d56..a67e4bb 100644 --- a/ZoomPipeline_FuncSvr/logger/st_logger.h +++ b/ZoomPipeline_FuncSvr/logger/st_logger.h @@ -5,6 +5,7 @@ #include #include #include +#include #include namespace STMsgLogger{ class st_logger : public QObject @@ -22,6 +23,7 @@ namespace STMsgLogger{ QString m_currLogFileName; int m_nLogLevel; int m_nMaxFileSize; + QMutex m_mutextLogger; signals: public slots: diff --git a/ZoomPipeline_FuncSvr/main.cpp b/ZoomPipeline_FuncSvr/main.cpp index eb26ab2..9a8f906 100644 --- a/ZoomPipeline_FuncSvr/main.cpp +++ b/ZoomPipeline_FuncSvr/main.cpp @@ -30,6 +30,7 @@ int main(int argc, char *argv[]) appTranslator.load(strTransLocalFile ); app.installTranslator(&appTranslator); + ZPMainFrame w; w.setLogger(&g_logger); w.show(); @@ -59,6 +60,8 @@ int main(int argc, char *argv[]) } } } + + int pp = app.exec(); return pp; } diff --git a/ZoomPipeline_FuncSvr/network/zp_net_threadpool.cpp b/ZoomPipeline_FuncSvr/network/zp_net_threadpool.cpp index 27d430b..2883c43 100644 --- a/ZoomPipeline_FuncSvr/network/zp_net_threadpool.cpp +++ b/ZoomPipeline_FuncSvr/network/zp_net_threadpool.cpp @@ -158,7 +158,8 @@ namespace ZPNetwork{ return; } - emit evt_Message(this,"Info>" + QString(tr("Incomming client arriverd."))); + //emit evt_Message(this,"Info>" + QString(tr("Incomming client arriverd."))); + qDebug()<"+QString(tr("Need Trans Thread Object for clients."))); + qCritical()<quit(); m_vec_netInternalTransThreads[idx]->wait(); + m_vec_NetTransThreads[idx]->Empty_RabishCan(); m_vec_netInternalTransThreads[idx]->deleteLater(); m_vec_NetTransThreads[idx]->deleteLater(); m_vec_netInternalTransThreads.remove(idx); diff --git a/ZoomPipeline_FuncSvr/network/zp_nettransthread.cpp b/ZoomPipeline_FuncSvr/network/zp_nettransthread.cpp index ac05e27..d881250 100644 --- a/ZoomPipeline_FuncSvr/network/zp_nettransthread.cpp +++ b/ZoomPipeline_FuncSvr/network/zp_nettransthread.cpp @@ -14,7 +14,9 @@ quint64 g_bytesSent = 0; quint64 g_secRecieved = 0; quint64 g_secSent = 0; -namespace ZPNetwork{ +namespace ZPNetwork{ + int zp_netTransThread::RUBBISH_CAN_SIZE = 256; + zp_netTransThread::zp_netTransThread(zp_net_Engine *pThreadPool,int nPayLoad,QObject *parent) : QObject(parent) ,m_pThreadPool(pThreadPool) @@ -24,6 +26,14 @@ namespace ZPNetwork{ m_bSSLConnection = true; assert(m_nPayLoad>=256 && m_nPayLoad<=16*1024*1024); } + void zp_netTransThread::Empty_RabishCan() + { + m_mutex_rabish_can.lock(); + foreach (QObject * pDel,m_rabish_can) + pDel->deleteLater(); + m_rabish_can.clear(); + m_mutex_rabish_can.unlock(); + } bool zp_netTransThread::isActive() { @@ -94,6 +104,29 @@ namespace ZPNetwork{ m_nPayLoad = nPayload; assert(m_nPayLoad>=256 && m_nPayLoad<=16*1024*1024); } + /** + * @brief the multithread object life-cycle is very complex, we hold a rabish_can, + * to prevent the misuse of deleted object in different threads. + * @param deletedobj The object to be deleted later + */ + void zp_netTransThread::push_to_rabish_can(QObject * deletedobj) + { + m_mutex_rabish_can.lock(); + m_rabish_can.push_back(deletedobj); + if (RUBBISH_CAN_SIZE<16) + RUBBISH_CAN_SIZE = 16; + if (RUBBISH_CAN_SIZE > 65536) + RUBBISH_CAN_SIZE = 65536; + if (m_rabish_can.size()>=RUBBISH_CAN_SIZE) + qDebug()<<"Delete old objects from rubbish can."; + + while (m_rabish_can.size()>=RUBBISH_CAN_SIZE) + { + m_rabish_can.first()->deleteLater(); + m_rabish_can.pop_front(); + } + m_mutex_rabish_can.unlock(); + } /** * @brief This slot dealing with multi-thread client socket accept. @@ -136,11 +169,13 @@ namespace ZPNetwork{ connect(psslsock, &QSslSocket::encrypted,this, &zp_netTransThread::on_encrypted,Qt::QueuedConnection); psslsock->startServerEncryption(); } + qDebug()<peerAddress().toString()<< + sock_client->peerPort() <" + QString(tr("Client Accepted."))); + //emit evt_Message(sock_client,"Info>" + QString(tr("Client Accepted."))); } else - sock_client->deleteLater(); + push_to_rabish_can(sock_client); } } @@ -204,14 +239,18 @@ namespace ZPNetwork{ { QTcpSocket * pSock = qobject_cast(sender()); emit evt_NewClientConnected(pSock); - emit evt_Message(pSock,"Info>" + QString(tr("Client connected."))); + //emit evt_Message(pSock,"Info>" + QString(tr("Client connected."))); + qDebug()<peerAddress().toString()<< + pSock->peerPort() <(sender()); emit evt_ClientEncrypted(pSock); - emit evt_Message(pSock,"Info>" + QString(tr("Client Encrypted."))); + //emit evt_Message(pSock,"Info>" + QString(tr("Client Encrypted."))); + qDebug()<peerAddress().toString()<< + pSock->peerPort() <deleteLater(); + pSock->abort(); emit evt_ClientDisconnected(pSock); - emit evt_Message(pSock,"Info>" + QString(tr("Client Closed."))); + //emit evt_Message(pSock,"Info>" + QString(tr("Client Closed."))); + qDebug()<(sender()); if (pSock) { + qDebug()<peerAddress().toString()<< + pSock->peerPort() <errorString()); emit evt_SocketError(pSock,socketError); - emit evt_Message(pSock,"Debug:" + pSock->errorString()); + //emit evt_Message(pSock,"Debug:" + pSock->errorString()); if (m_bSSLConnection) { QSslSocket * psslsock = qobject_cast(pSock); @@ -317,10 +360,9 @@ namespace ZPNetwork{ m_clientList.remove(pSock); m_mutex_protect.unlock(); pSock->abort(); - pSock->deleteLater(); emit evt_ClientDisconnected(pSock); emit evt_Message(pSock,"Info>" + QString(tr("Client Closed."))); - + push_to_rabish_can(pSock); } } @@ -367,12 +409,25 @@ namespace ZPNetwork{ QTcpSocket * pSock = qobject_cast(obj); if (pSock) { - QSslSocket * pSSl = qobject_cast(pSock); - if (pSSl==NULL) - pSock->abort(); - else - pSock->disconnectFromHost(); - + if (m_bSSLConnection) + { + QSslSocket * psslsock = qobject_cast(pSock); + if (psslsock) + disconnect(psslsock, &QSslSocket::encrypted,this, &zp_netTransThread::on_encrypted); + } + disconnect(pSock, &QTcpSocket::readyRead,this, &zp_netTransThread::new_data_recieved); + disconnect(pSock, &QTcpSocket::disconnected,this,&zp_netTransThread::client_closed); + disconnect(pSock, SIGNAL(error(QAbstractSocket::SocketError)),this, SLOT(displayError(QAbstractSocket::SocketError))); + disconnect(pSock, &QTcpSocket::bytesWritten, this, &zp_netTransThread::some_data_sended); + disconnect(pSock, &QTcpSocket::connected,this, &zp_netTransThread::on_connected); + m_buffer_sending.erase(pSock); + m_buffer_sending_offset.erase(pSock); + m_clientList.remove(pSock); + pSock->abort(); + emit evt_ClientDisconnected(pSock); + //emit evt_Message(pSock,"Info>" + QString(tr("Client Closed."))); + qDebug()<(pSock); - if (pSSl==NULL) - pSock->abort(); - else - pSock->disconnectFromHost(); + if (m_bSSLConnection) + { + QSslSocket * psslsock = qobject_cast(pSock); + if (psslsock) + disconnect(psslsock, &QSslSocket::encrypted,this, &zp_netTransThread::on_encrypted); + } + disconnect(pSock, &QTcpSocket::readyRead,this, &zp_netTransThread::new_data_recieved); + disconnect(pSock, &QTcpSocket::disconnected,this,&zp_netTransThread::client_closed); + disconnect(pSock, SIGNAL(error(QAbstractSocket::SocketError)),this, SLOT(displayError(QAbstractSocket::SocketError))); + disconnect(pSock, &QTcpSocket::bytesWritten, this, &zp_netTransThread::some_data_sended); + disconnect(pSock, &QTcpSocket::connected,this, &zp_netTransThread::on_connected); + m_buffer_sending.erase(pSock); + m_buffer_sending_offset.erase(pSock); + m_mutex_protect.lock(); + m_clientList.remove(pSock); + m_mutex_protect.unlock(); + pSock->abort(); + emit evt_ClientDisconnected(pSock); + //emit evt_Message(pSock,"Info>" + QString(tr("Client Closed."))); + qDebug()< #include #include +#include namespace ZPNetwork{ class zp_net_Engine; /** @@ -22,7 +23,6 @@ namespace ZPNetwork{ Q_OBJECT public: explicit zp_netTransThread(zp_net_Engine * pThreadPool,int nPayLoad = 4096,QObject *parent = 0); - QList clientsList(); int CurrentClients(); void SetPayload(int nPayload); @@ -32,6 +32,11 @@ namespace ZPNetwork{ bool SSLConnection(); void SetSSLConnection(bool bssl); + //RubbishCan Functions + void Empty_RabishCan(); + //Size of the RubbishCan + static int RUBBISH_CAN_SIZE; + private: bool m_bActivated; bool m_bSSLConnection; @@ -44,6 +49,10 @@ namespace ZPNetwork{ int m_nPayLoad; QMutex m_mutex_protect; zp_net_Engine * m_pThreadPool; + //Rabish Can + QList m_rabish_can; + QMutex m_mutex_rabish_can; + void push_to_rabish_can(QObject * deletedobj); public slots: //This slot dealing with multi-thread client socket accept. void incomingConnection(QObject * threadid,qintptr socketDescriptor); -- GitLab