pingmanager.cpp 5.26 KB
/* ****************************************************************************
 * Copyright 2019 Open Systems Development BV                                 *
 *                                                                            *
 * Permission is hereby granted, free of charge, to any person obtaining a    *
 * copy of this software and associated documentation files (the "Software"), *
 * to deal in the Software without restriction, including without limitation  *
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,   *
 * and/or sell copies of the Software, and to permit persons to whom the      *
 * Software is furnished to do so, subject to the following conditions:       *
 *                                                                            *
 * The above copyright notice and this permission notice shall be included in *
 * all copies or substantial portions of the Software.                        *
 *                                                                            *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR *
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,   *
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL    *
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER *
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING    *
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER        *
 * DEALINGS IN THE SOFTWARE.                                                  *
 * ***************************************************************************/
#include "pingmanager.h"
#include "log.h"
#include "pingdata.h"

#include <QCoreApplication>

using namespace osdev::components;

PingManager::PingManager( int max_threads, QObject *parent )
    : QObject( parent )
    , m_qhThreads()
    , m_pSharedBuffer()
    , m_pHostBuffer()
    , m_max_threads( max_threads )
{
    m_pSharedBuffer = new PingDataQueue();
    if( nullptr != m_pSharedBuffer )
    {
        connect( m_pSharedBuffer, &PingDataQueue::signalNewDataReceived, this, &PingManager::slotNewData );
    }

    m_pHostBuffer = new HostBuffer();

    createThreads();
}

PingManager::~PingManager()
{
    // Cleanup the SharedBuffer
    if( nullptr != m_pSharedBuffer )
    {
        delete m_pSharedBuffer;
        m_pSharedBuffer = nullptr;
    }

    // Cleanup the HostBuffer
    if( nullptr != m_pHostBuffer )
    {
        delete m_pHostBuffer;
        m_pHostBuffer = nullptr;
    }
}

void PingManager::createThreads()
{
    // Create all threads
    for( int threadCounter = 0; threadCounter < m_max_threads; threadCounter++ )
    {
        PingThread *pThread = new PingThread( m_pHostBuffer, m_pSharedBuffer );
        if( nullptr != pThread )
        {
            connect( pThread, &PingThread::signalThreadFinished, this, &PingManager::slotThreadFinished );
            connect( this, &PingManager::signalStartThreads, pThread, &PingThread::slotStartThread );

            m_qhThreads.append( pThread );
        }
        else
        {
            LogError( "[PingManager::startPingTests]", QString( "Unable to start threadnumber : %1" ).arg( threadCounter ) );
        }
    }
    LogInfo( "[PingManager::createThreads]", QString( "%1 threads created and ready to run."  ).arg( m_qhThreads.count() ) );
}

bool PingManager::startPingTests()
{
    bool bResult = false;

    if( m_pHostBuffer->count() > 0 )
    {
        LogInfo( "[PingManager::startPingTests]", QString( "Signalling all threads to start checking hosts"  ) );
        emit signalStartThreads();
        QCoreApplication::processEvents();

        bResult &= true;
    }
    else
    {
        LogInfo( "[PingManager::startPingTests]",
                QString( "No hosts to check." ) );
    }

    return bResult;
}

int PingManager::addHosts( const QStringList &host_list )
{
    if( nullptr == m_pHostBuffer )
    {
        m_pHostBuffer = new HostBuffer();
    }

    m_pHostBuffer->addHosts( host_list );

    return m_pHostBuffer->count();
}

void PingManager::slotNewData( const QUuid &id )
{
    PingData* pData = m_pSharedBuffer->getData( id );
    if( nullptr != pData )
    {
        QCoreApplication::processEvents();
    }
}

void PingManager::slotThreadFinished( QThread *thread )
{
    LogInfo( "[PingManager::slotThreadFinished]", QString( "Thread signalled finished : %1" ).arg( m_qhThreads.indexOf( thread ) ) );

    bool running_threads = false;

    // Here we check if there are still running threads. If not, we signal the object
    foreach( const auto cur_thread, m_qhThreads )
    {
        running_threads &= cur_thread->isRunning();
    }

    if( !running_threads )
    {
        LogInfo( "[PingManager::slotThreadFinished]", QString( "Signalling all Threads finished -> signalAllThreadsFinished()" ) );
        emit signalAllThreadsFinished();
    }
    else
    {
        LogInfo( "[PingManager::slotThreadFinished]", QString( "Still running threads...()" ) );
    }
}

QStringList PingManager::getActiveIPs()
{
    QStringList l_result;

    for( const auto id : m_pSharedBuffer->getIds() )
    {
        if(  m_pSharedBuffer->getData( id )->available() )
        {
            l_result.append( m_pSharedBuffer->getData( id )->ipAddress() );
        }
    }

    return l_result;
}