1
0
mirror of https://github.com/tomahawk-player/tomahawk.git synced 2025-08-08 07:07:05 +02:00

If a ControlConnection is not anymore responsible for a source, it should not touch it.

This commit is contained in:
Uwe L. Korn
2013-06-16 11:17:05 +02:00
parent fbe434a4d5
commit f9738dba16
3 changed files with 37 additions and 2 deletions

View File

@@ -100,6 +100,7 @@ bool
Source::setControlConnection( ControlConnection* cc ) Source::setControlConnection( ControlConnection* cc )
{ {
Q_D( Source ); Q_D( Source );
QMutexLocker locker( &d->setControlConnectionMutex ); QMutexLocker locker( &d->setControlConnectionMutex );
if ( !d->cc.isNull() && d->cc->isReady() && d->cc->isRunning() ) if ( !d->cc.isNull() && d->cc->isReady() && d->cc->isRunning() )
{ {
@@ -107,6 +108,8 @@ Source::setControlConnection( ControlConnection* cc )
peerInfoDebug( (*cc->peerInfos().begin()) ) << Q_FUNC_INFO << "Comparing" << cc->id() << "and" << nodeid << "to detect duplicate connection, outbound:" << cc->outbound(); peerInfoDebug( (*cc->peerInfos().begin()) ) << Q_FUNC_INFO << "Comparing" << cc->id() << "and" << nodeid << "to detect duplicate connection, outbound:" << cc->outbound();
if ( cc->id() < nodeid && d->cc->outbound() ) if ( cc->id() < nodeid && d->cc->outbound() )
{ {
// Tell the ControlConnection it is not anymore responsible for us.
d->cc->unbindFromSource();
// This ControlConnection is not needed anymore, get rid of it! // This ControlConnection is not needed anymore, get rid of it!
d->cc->deleteLater(); d->cc->deleteLater();
// Use new ControlConnection // Use new ControlConnection

View File

@@ -2,6 +2,7 @@
* *
* Copyright 2010-2011, Christian Muehlhaeuser <muesli@tomahawk-player.org> * Copyright 2010-2011, Christian Muehlhaeuser <muesli@tomahawk-player.org>
* Copyright 2010-2012, Jeff Mitchell <jeff@tomahawk-player.org> * Copyright 2010-2012, 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 * Tomahawk is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@@ -55,10 +56,13 @@ ControlConnection::ControlConnection( Servent* parent )
ControlConnection::~ControlConnection() ControlConnection::~ControlConnection()
{ {
QReadLocker locker( &m_sourceLock );
tDebug( LOGVERBOSE ) << Q_FUNC_INFO << id() << name(); tDebug( LOGVERBOSE ) << Q_FUNC_INFO << id() << name();
if ( !m_source.isNull() ) if ( !m_source.isNull() )
{
m_source->setOffline(); m_source->setOffline();
}
delete m_pingtimer; delete m_pingtimer;
m_servent->unregisterControlConnection( this ); m_servent->unregisterControlConnection( this );
@@ -70,9 +74,18 @@ ControlConnection::~ControlConnection()
source_ptr source_ptr
ControlConnection::source() const ControlConnection::source() const
{ {
// We return a copy of the shared pointer, no need for a longer lock
QReadLocker locker( &m_sourceLock );
return m_source; return m_source;
} }
void
ControlConnection::unbindFromSource()
{
QWriteLocker locker( &m_sourceLock );
m_source.clear();
}
Connection* Connection*
ControlConnection::clone() ControlConnection::clone()
@@ -88,6 +101,7 @@ void
ControlConnection::setup() ControlConnection::setup()
{ {
qDebug() << Q_FUNC_INFO << id() << name(); qDebug() << Q_FUNC_INFO << id() << name();
QWriteLocker sourceLocker( &m_sourceLock );
if ( !m_source.isNull() ) if ( !m_source.isNull() )
{ {
@@ -132,9 +146,10 @@ ControlConnection::setup()
void void
ControlConnection::registerSource() ControlConnection::registerSource()
{ {
QReadLocker sourceLocker( &m_sourceLock );
QSharedPointer<QMutexLocker> locker = m_source->acquireLock(); QSharedPointer<QMutexLocker> locker = m_source->acquireLock();
// Only continue if we are still the ControlConnection associated with this source. // Only continue if we are still the ControlConnection associated with this source.
if ( m_source->controlConnection() == this ) if ( !m_source.isNull() && m_source->controlConnection() == this )
{ {
qDebug() << Q_FUNC_INFO << m_source->id(); qDebug() << Q_FUNC_INFO << m_source->id();
Source* source = (Source*) sender(); Source* source = (Source*) sender();
@@ -150,6 +165,13 @@ ControlConnection::registerSource()
void void
ControlConnection::setupDbSyncConnection( bool ondemand ) ControlConnection::setupDbSyncConnection( bool ondemand )
{ {
QReadLocker locker( &m_sourceLock );
if ( m_source.isNull() )
{
// We were unbind from the Source, nothing to do here, just waiting to be deleted.
return;
}
qDebug() << Q_FUNC_INFO << ondemand << m_source->id() << m_dbconnkey << m_dbsyncconn << m_registered; qDebug() << Q_FUNC_INFO << ondemand << m_source->id() << m_dbconnkey << m_dbsyncconn << m_registered;
if ( m_dbsyncconn || !m_registered ) if ( m_dbsyncconn || !m_registered )
@@ -206,7 +228,6 @@ ControlConnection::dbSyncConnFinished( QObject* c )
DBSyncConnection* DBSyncConnection*
ControlConnection::dbSyncConnection() ControlConnection::dbSyncConnection()
{ {
qDebug() << Q_FUNC_INFO << m_source->id();
if ( !m_dbsyncconn ) if ( !m_dbsyncconn )
{ {
setupDbSyncConnection( true ); setupDbSyncConnection( true );
@@ -292,6 +313,7 @@ ControlConnection::onPingTimer()
{ {
if ( m_pingtimer_mark.elapsed() >= TCP_TIMEOUT * 1000 ) if ( m_pingtimer_mark.elapsed() >= TCP_TIMEOUT * 1000 )
{ {
QReadLocker locker( &m_sourceLock );
qDebug() << "Timeout reached! Shutting down connection to" << m_source->friendlyName(); qDebug() << "Timeout reached! Shutting down connection to" << m_source->friendlyName();
shutdown( true ); shutdown( true );
} }

View File

@@ -32,6 +32,7 @@
#include "DllMacro.h" #include "DllMacro.h"
#include <QReadWriteLock>
#include <QTime> #include <QTime>
#include <QTimer> #include <QTimer>
@@ -51,6 +52,11 @@ public:
Tomahawk::source_ptr source() const; Tomahawk::source_ptr source() const;
/**
* Tell this ControlConnection that is no longer controlling the source and should not do any actions on it.
*/
void unbindFromSource();
void addPeerInfo( const Tomahawk::peerinfo_ptr& peerInfo ); void addPeerInfo( const Tomahawk::peerinfo_ptr& peerInfo );
void removePeerInfo( const Tomahawk::peerinfo_ptr& peerInfo ); void removePeerInfo( const Tomahawk::peerinfo_ptr& peerInfo );
void setShutdownOnEmptyPeerInfos( bool shutdownOnEmptyPeerInfos ); void setShutdownOnEmptyPeerInfos( bool shutdownOnEmptyPeerInfos );
@@ -72,6 +78,10 @@ private:
void setupDbSyncConnection( bool ondemand = false ); void setupDbSyncConnection( bool ondemand = false );
Tomahawk::source_ptr m_source; Tomahawk::source_ptr m_source;
/**
* Lock acces to the source member. A "write" access is only if we change the value of source, not if doing a non-const call.
*/
mutable QReadWriteLock m_sourceLock;
DBSyncConnection* m_dbsyncconn; DBSyncConnection* m_dbsyncconn;
QString m_dbconnkey; QString m_dbconnkey;