1
0
mirror of https://github.com/tomahawk-player/tomahawk.git synced 2025-03-21 00:09:47 +01:00

Move private members of Connection into a Dpointer

This commit is contained in:
Uwe L. Korn 2013-06-15 13:56:37 +02:00
parent 2f570ef161
commit bd24819cbf
3 changed files with 252 additions and 90 deletions

View File

@ -18,7 +18,7 @@
* along with Tomahawk. If not, see <http://www.gnu.org/licenses/>.
*/
#include "Connection.h"
#include "Connection_p.h"
#include "QTcpSocketExtra.h"
#include "network/Servent.h"
@ -38,29 +38,18 @@ Connection::Connection( Servent* parent )
, m_servent( parent )
, m_ready( false )
, m_onceonly( true )
, m_do_shutdown( false )
, m_actually_shutting_down( false )
, m_peer_disconnected( false )
, m_tx_bytes( 0 )
, m_tx_bytes_requested( 0 )
, m_rx_bytes( 0 )
, m_id( "Connection()" )
, m_statstimer( 0 )
, m_stats_tx_bytes_per_sec( 0 )
, m_stats_rx_bytes_per_sec( 0 )
, m_rx_bytes_last( 0 )
, m_tx_bytes_last( 0 )
, d_ptr( new ConnectionPrivate( this ) )
{
moveToThread( m_servent->thread() );
tDebug( LOGVERBOSE ) << "CTOR Connection (super)" << thread();
connect( &m_msgprocessor_out, SIGNAL( ready( msg_ptr ) ),
connect( &d_func()->msgprocessor_out, SIGNAL( ready( msg_ptr ) ),
SLOT( sendMsg_now( msg_ptr ) ), Qt::QueuedConnection );
connect( &m_msgprocessor_in, SIGNAL( ready( msg_ptr ) ),
connect( &d_func()->msgprocessor_in, SIGNAL( ready( msg_ptr ) ),
SLOT( handleMsg( msg_ptr ) ), Qt::QueuedConnection );
connect( &m_msgprocessor_in, SIGNAL( empty() ),
connect( &d_func()->msgprocessor_in, SIGNAL( empty() ),
SLOT( handleIncomingQueueEmpty() ), Qt::QueuedConnection );
}
@ -73,7 +62,8 @@ Connection::~Connection()
m_sock->deleteLater();
}
delete m_statstimer;
delete d_func()->statstimer;
delete d_ptr;
}
@ -85,11 +75,11 @@ Connection::handleIncomingQueueEmpty()
// << "m_peer_disconnected" << m_peer_disconnected
// << "bytes rx" << bytesReceived();
if ( !m_sock.isNull() && m_sock->bytesAvailable() == 0 && m_peer_disconnected )
if ( !m_sock.isNull() && m_sock->bytesAvailable() == 0 && d_func()->peer_disconnected )
{
tDebug( LOGVERBOSE ) << "No more data to read, peer disconnected. shutting down connection."
<< "bytesavail" << m_sock->bytesAvailable()
<< "bytesrx" << m_rx_bytes;
<< "bytesrx" << d_func()->rx_bytes;
shutdown();
}
}
@ -114,18 +104,60 @@ Connection::setFirstMessage( msg_ptr m )
// << "msg len:" << m_firstmsg->length() ;
}
msg_ptr
Connection::firstMessage() const
{
return m_firstmsg;
}
const QPointer<QTcpSocket>&
Connection::socket()
{
return m_sock;
}
void
Connection::setOutbound(bool o)
{
m_outbound = o;
}
bool
Connection::outbound() const
{
return m_outbound;
}
Servent*
Connection::servent() const
{
return m_servent;
}
int
Connection::peerPort() const
{
return m_peerport;
}
void
Connection::setPeerPort(int p)
{
m_peerport = p;
}
void
Connection::shutdown( bool waitUntilSentAll )
{
tDebug( LOGVERBOSE ) << Q_FUNC_INFO << waitUntilSentAll << id();
if ( m_do_shutdown )
if ( d_func()->do_shutdown )
{
//qDebug() << id() << " already shutting down";
return;
}
m_do_shutdown = true;
d_func()->do_shutdown = true;
if ( !waitUntilSentAll )
{
// qDebug() << "Shutting down immediately " << id();
@ -134,7 +166,7 @@ Connection::shutdown( bool waitUntilSentAll )
else
{
tDebug( LOGVERBOSE ) << "Shutting down after transfer complete " << id()
<< "Actual/Desired" << m_tx_bytes << m_tx_bytes_requested;
<< "Actual/Desired" << d_func()->tx_bytes << d_func()->tx_bytes_requested;
bytesWritten( 0 ); // trigger shutdown if we've already sent everything
// otherwise the bytesWritten slot will call actualShutdown()
@ -146,12 +178,12 @@ Connection::shutdown( bool waitUntilSentAll )
void
Connection::actualShutdown()
{
tDebug( LOGVERBOSE ) << Q_FUNC_INFO << m_actually_shutting_down << id();
if ( m_actually_shutting_down )
tDebug( LOGVERBOSE ) << Q_FUNC_INFO << d_func()->actually_shutting_down << id();
if ( d_func()->actually_shutting_down )
{
return;
}
m_actually_shutting_down = true;
d_func()->actually_shutting_down = true;
if ( !m_sock.isNull() && m_sock->isOpen() )
{
@ -171,6 +203,72 @@ Connection::markAsFailed()
shutdown();
}
void
Connection::setName( const QString& n )
{
m_name = n;
}
QString
Connection::name() const
{
return m_name;
}
void
Connection::setOnceOnly( bool b )
{
m_onceonly = b;
}
bool
Connection::onceOnly() const
{
return m_onceonly;
}
bool
Connection::isReady() const
{
return m_ready;
}
bool
Connection::isRunning() const
{
return m_sock != 0;
}
qint64
Connection::bytesSent() const
{
return d_func()->tx_bytes;
}
qint64
Connection::bytesReceived() const
{
return d_func()->rx_bytes;
}
void
Connection::setMsgProcessorModeOut(quint32 m)
{
d_func()->msgprocessor_out.setMode( m );
}
void
Connection::setMsgProcessorModeIn(quint32 m)
{
d_func()->msgprocessor_in.setMode( m );
}
const QHostAddress
Connection::peerIpAddress() const
{
return d_func()->peerIpAddress;
}
void
Connection::start( QTcpSocket* sock )
@ -193,14 +291,14 @@ Connection::start( QTcpSocket* sock )
void
Connection::checkACL()
{
if ( m_nodeid.isEmpty() )
if ( d_func()->nodeid.isEmpty() )
{
tDebug( LOGVERBOSE ) << Q_FUNC_INFO << "Not checking ACL, nodeid is empty";
QTimer::singleShot( 0, this, SLOT( doSetup() ) );
return;
}
if ( Servent::isIPWhitelisted( m_peerIpAddress ) )
if ( Servent::isIPWhitelisted( d_func()->peerIpAddress ) )
{
QTimer::singleShot( 0, this, SLOT( doSetup() ) );
return;
@ -208,7 +306,7 @@ Connection::checkACL()
tDebug( LOGVERBOSE ) << Q_FUNC_INFO << "Checking ACL for" << name();
connect( ACLRegistry::instance(), SIGNAL( aclResult( QString, QString, ACLRegistry::ACL ) ), this, SLOT( checkACLResult( QString, QString, ACLRegistry::ACL ) ), Qt::QueuedConnection );
QMetaObject::invokeMethod( ACLRegistry::instance(), "isAuthorizedUser", Qt::QueuedConnection, Q_ARG( QString, m_nodeid ), Q_ARG( QString, bareName() ), Q_ARG( ACLRegistry::ACL, ACLRegistry::NotFound ) );
QMetaObject::invokeMethod( ACLRegistry::instance(), "isAuthorizedUser", Qt::QueuedConnection, Q_ARG( QString, d_func()->nodeid ), Q_ARG( QString, bareName() ), Q_ARG( ACLRegistry::ACL, ACLRegistry::NotFound ) );
}
@ -221,9 +319,9 @@ Connection::bareName() const
void
Connection::checkACLResult( const QString &nodeid, const QString &username, ACLRegistry::ACL peerStatus )
{
if ( nodeid != m_nodeid )
if ( nodeid != d_func()->nodeid )
{
tDebug( LOGVERBOSE ) << Q_FUNC_INFO << QString( "nodeid (%1) not ours (%2) for user %3" ).arg( nodeid ).arg( m_nodeid ).arg( username );
tDebug( LOGVERBOSE ) << Q_FUNC_INFO << QString( "nodeid (%1) not ours (%2) for user %3" ).arg( nodeid ).arg( d_func()->nodeid ).arg( username );
return;
}
if ( username != bareName() )
@ -273,12 +371,12 @@ Connection::doSetup()
}
//stats timer calculates BW used by this connection
m_statstimer = new QTimer;
m_statstimer->moveToThread( this->thread() );
m_statstimer->setInterval( 1000 );
connect( m_statstimer, SIGNAL( timeout() ), SLOT( calcStats() ) );
m_statstimer->start();
m_statstimer_mark.start();
d_func()->statstimer = new QTimer;
d_func()->statstimer->moveToThread( this->thread() );
d_func()->statstimer->setInterval( 1000 );
connect( d_func()->statstimer, SIGNAL( timeout() ), SLOT( calcStats() ) );
d_func()->statstimer->start();
d_func()->statstimer_mark.start();
m_sock->moveToThread( thread() );
@ -326,10 +424,10 @@ Connection::socketDisconnected()
<< "bytesavail:" << bytesAvailable
<< "bytesRecvd" << bytesReceived();
m_peer_disconnected = true;
d_func()->peer_disconnected = true;
emit socketClosed();
if ( m_msgprocessor_in.length() == 0 && bytesAvailable == 0 )
if ( d_func()->msgprocessor_in.length() == 0 && bytesAvailable == 0 )
{
handleIncomingQueueEmpty();
actualShutdown();
@ -345,7 +443,7 @@ Connection::socketDisconnectedError( QAbstractSocket::SocketError e )
if ( e == QAbstractSocket::RemoteHostClosedError )
return;
m_peer_disconnected = true;
d_func()->peer_disconnected = true;
emit socketErrored(e);
emit socketClosed();
@ -357,26 +455,26 @@ Connection::socketDisconnectedError( QAbstractSocket::SocketError e )
QString
Connection::id() const
{
return m_id;
return d_func()->id;
}
void
Connection::setId( const QString& id )
{
m_id = id;
d_func()->id = id;
}
QString
Connection::nodeId() const
{
return m_nodeid;
return d_func()->nodeid;
}
void
Connection::setNodeId( const QString& nodeid )
{
m_nodeid = nodeid;
d_func()->nodeid = nodeid;
}
@ -399,7 +497,7 @@ Connection::readyRead()
}
m_msg = Msg::begin( (char*) &msgheader );
m_rx_bytes += Msg::headerSize();
d_func()->rx_bytes += Msg::headerSize();
}
if ( m_sock->bytesAvailable() < m_msg->length() )
@ -413,7 +511,7 @@ Connection::readyRead()
return;
}
m_msg->fill( ba );
m_rx_bytes += ba.length();
d_func()->rx_bytes += ba.length();
handleReadMsg(); // process m_msg and clear() it
@ -457,7 +555,7 @@ Connection::handleReadMsg()
}
else
{
m_msgprocessor_in.append( m_msg );
d_func()->msgprocessor_in.append( m_msg );
}
m_msg.clear();
@ -467,7 +565,7 @@ Connection::handleReadMsg()
void
Connection::sendMsg( QVariant j )
{
if ( m_do_shutdown )
if ( d_func()->do_shutdown )
return;
QJson::Serializer serializer;
@ -480,15 +578,15 @@ Connection::sendMsg( QVariant j )
void
Connection::sendMsg( msg_ptr msg )
{
if ( m_do_shutdown )
if ( d_func()->do_shutdown )
{
tDebug( LOGVERBOSE ) << Q_FUNC_INFO << "SHUTTING DOWN, NOT SENDING msg flags:"
<< (int)msg->flags() << "length:" << msg->length() << id();
return;
}
m_tx_bytes_requested += msg->length() + Msg::headerSize();
m_msgprocessor_out.append( msg );
d_func()->tx_bytes_requested += msg->length() + Msg::headerSize();
d_func()->msgprocessor_out.append( msg );
}
@ -517,9 +615,9 @@ Connection::sendMsg_now( msg_ptr msg )
void
Connection::bytesWritten( qint64 i )
{
m_tx_bytes += i;
d_func()->tx_bytes += i;
// if we are waiting to shutdown, and have sent all queued data, do actual shutdown:
if ( m_do_shutdown && m_tx_bytes == m_tx_bytes_requested )
if ( d_func()->do_shutdown && d_func()->tx_bytes == d_func()->tx_bytes_requested )
actualShutdown();
}
@ -527,13 +625,13 @@ Connection::bytesWritten( qint64 i )
void
Connection::calcStats()
{
int elapsed = m_statstimer_mark.restart(); // ms since last calc
int elapsed = d_func()->statstimer_mark.restart(); // ms since last calc
m_stats_tx_bytes_per_sec = (float)1000 * ( (m_tx_bytes - m_tx_bytes_last) / (float)elapsed );
m_stats_rx_bytes_per_sec = (float)1000 * ( (m_rx_bytes - m_rx_bytes_last) / (float)elapsed );
d_func()->stats_tx_bytes_per_sec = (float)1000 * ( (d_func()->tx_bytes - d_func()->tx_bytes_last) / (float)elapsed );
d_func()->stats_rx_bytes_per_sec = (float)1000 * ( (d_func()->rx_bytes - d_func()->rx_bytes_last) / (float)elapsed );
m_rx_bytes_last = m_rx_bytes;
m_tx_bytes_last = m_tx_bytes;
d_func()->rx_bytes_last = d_func()->rx_bytes;
d_func()->tx_bytes_last = d_func()->tx_bytes;
emit statsTick( m_stats_tx_bytes_per_sec, m_stats_rx_bytes_per_sec );
emit statsTick( d_func()->stats_tx_bytes_per_sec, d_func()->stats_rx_bytes_per_sec );
}

View File

@ -2,6 +2,7 @@
*
* Copyright 2010-2011, Christian Muehlhaeuser <muesli@tomahawk-player.org>
* Copyright 2010-2011, Jeff Mitchell <jeff@tomahawk-player.org>
* Copyright 2013, Uwe L. Korn <uwelk@xhochy.com>
*
* Tomahawk is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -42,7 +43,7 @@
#include <QTime>
#include <QPointer>
class ConnectionPrivate;
class Servent;
class DLLEXPORT Connection : public QObject
@ -63,37 +64,37 @@ public:
void setFirstMessage( const QVariant& m );
void setFirstMessage( msg_ptr m );
msg_ptr firstMessage() const { return m_firstmsg; }
msg_ptr firstMessage() const;
const QPointer<QTcpSocket>& socket() { return m_sock; }
const QPointer<QTcpSocket>& socket();
void setOutbound( bool o ) { m_outbound = o; }
bool outbound() const { return m_outbound; }
void setOutbound( bool o );
bool outbound() const;
Servent* servent() { return m_servent; }
Servent* servent() const;
// get public port of remote peer:
int peerPort() { return m_peerport; }
void setPeerPort( int p ) { m_peerport = p; }
int peerPort() const;
void setPeerPort( int p );
void markAsFailed();
void setName( const QString& n ) { m_name = n; }
QString name() const { return m_name; }
void setName( const QString& n );
QString name() const;
void setOnceOnly( bool b ) { m_onceonly = b; }
bool onceOnly() const { return m_onceonly; }
void setOnceOnly( bool b );
bool onceOnly() const;
bool isReady() const { return m_ready; }
bool isRunning() const { return m_sock != 0; }
bool isReady() const;
bool isRunning() const;
qint64 bytesSent() const { return m_tx_bytes; }
qint64 bytesReceived() const { return m_rx_bytes; }
qint64 bytesSent() const;
qint64 bytesReceived() const;
void setMsgProcessorModeOut( quint32 m ) { m_msgprocessor_out.setMode( m ); }
void setMsgProcessorModeIn( quint32 m ) { m_msgprocessor_in.setMode( m ); }
void setMsgProcessorModeOut( quint32 m );
void setMsgProcessorModeIn( quint32 m );
const QHostAddress peerIpAddress() const { return m_peerIpAddress; }
const QHostAddress peerIpAddress() const;
QString bareName() const;
signals:
@ -139,23 +140,13 @@ protected:
bool m_outbound, m_ready, m_onceonly;
msg_ptr m_firstmsg;
QString m_name;
QHostAddress m_peerIpAddress;
private:
Q_DECLARE_PRIVATE( Connection )
ConnectionPrivate* d_ptr;
void handleReadMsg();
void actualShutdown();
bool m_do_shutdown, m_actually_shutting_down, m_peer_disconnected;
qint64 m_tx_bytes, m_tx_bytes_requested;
qint64 m_rx_bytes;
QString m_id;
QString m_nodeid;
QTimer* m_statstimer;
QTime m_statstimer_mark;
qint64 m_stats_tx_bytes_per_sec, m_stats_rx_bytes_per_sec;
qint64 m_rx_bytes_last, m_tx_bytes_last;
MsgProcessor m_msgprocessor_in, m_msgprocessor_out;
};
#endif // CONNECTION_H

View File

@ -0,0 +1,73 @@
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
*
* Copyright 2010-2011, Christian Muehlhaeuser <muesli@tomahawk-player.org>
* Copyright 2010-2011, Jeff Mitchell <jeff@tomahawk-player.org>
* Copyright 2013, Uwe L. Korn <uwelk@xhochy.com>
*
* Tomahawk is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Tomahawk 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Tomahawk. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef CONNECTION_P_H
#define CONNECTION_P_H
#include "Connection.h"
class ConnectionPrivate : public QObject
{
Q_OBJECT
public:
ConnectionPrivate( Connection* q )
: q_ptr ( q )
, do_shutdown( false )
, actually_shutting_down( false )
, peer_disconnected( false )
, tx_bytes( 0 )
, tx_bytes_requested( 0 )
, rx_bytes( 0 )
, id( "Connection()" )
, statstimer( 0 )
, stats_tx_bytes_per_sec( 0 )
, stats_rx_bytes_per_sec( 0 )
, rx_bytes_last( 0 )
, tx_bytes_last( 0 )
{
}
Connection* q_ptr;
Q_DECLARE_PUBLIC ( Connection )
private:
QHostAddress peerIpAddress;
bool do_shutdown;
bool actually_shutting_down;
bool peer_disconnected;
qint64 tx_bytes;
qint64 tx_bytes_requested;
qint64 rx_bytes;
QString id;
QString nodeid;
QTimer* statstimer;
QTime statstimer_mark;
qint64 stats_tx_bytes_per_sec;
qint64 stats_rx_bytes_per_sec;
qint64 rx_bytes_last;
qint64 tx_bytes_last;
MsgProcessor msgprocessor_in;
MsgProcessor msgprocessor_out;
};
#endif // CONNECTION_P_H