Skip to content

Commit

Permalink
fix via mutext
Browse files Browse the repository at this point in the history
  • Loading branch information
benoitdm-oslandia committed Dec 6, 2024
1 parent d031943 commit 8a62b11
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 30 deletions.
51 changes: 26 additions & 25 deletions src/server/qgsfcgiserverresponse.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@
#include "qgslogger.h"

#include <unistd.h>
#include <mutex>
#include <chrono>

#if defined(Q_OS_UNIX) && !defined(Q_OS_ANDROID)
#include <sys/types.h>
Expand Down Expand Up @@ -56,6 +58,12 @@ typedef struct QgsFCGXStreamData
} QgsFCGXStreamData;
#endif

using namespace std::chrono_literals;


std::timed_mutex socketMonitoringMutex;


// QgsSocketMonitoringThread constructor
QgsSocketMonitoringThread::QgsSocketMonitoringThread( std::shared_ptr<QgsFeedback> feedback )
: mFeedback( feedback )
Expand Down Expand Up @@ -100,18 +108,9 @@ QgsSocketMonitoringThread::~QgsSocketMonitoringThread()
// Informs the thread to quit
void QgsSocketMonitoringThread::setResponseFinished( bool responseFinished )
{
mIsResponseFinished = responseFinished;
mIsResponseFinished.store( responseFinished );
qDebug() << QDateTime::currentDateTime().toString( Qt::ISODateWithMs ).toStdString().c_str()
<< "FCGIServer::setResponseFinished to:" << mIsResponseFinished;
}

// Keep shared ptr reference to avoid too early deletion
void QgsSocketMonitoringThread::setShared( std::shared_ptr<QgsSocketMonitoringThread> ptr )
{
mySelf = ptr;
qDebug() << QDateTime::currentDateTime().toString( Qt::ISODateWithMs ).toStdString().c_str()
<< "FCGIServer::setShared count:" << mySelf.use_count();

<< "FCGIServer::setResponseFinished to:" << mIsResponseFinished.load();
}

void QgsSocketMonitoringThread::run( )
Expand All @@ -127,11 +126,12 @@ void QgsSocketMonitoringThread::run( )
}

#if defined(Q_OS_UNIX) && !defined(Q_OS_ANDROID)
mIsResponseFinished.store( false );
char c;
qDebug() << QDateTime::currentDateTime().toString( Qt::ISODateWithMs ).toStdString().c_str()
<< "FCGIServer::run" << threadId
<< "run mIsResponseFinished:" << mIsResponseFinished;
while ( !mIsResponseFinished )
<< "run mIsResponseFinished:" << mIsResponseFinished.load();
while ( false == mIsResponseFinished.load() )
{
const ssize_t x = recv( mIpcFd, &c, 1, MSG_PEEK | MSG_DONTWAIT ); // see https://stackoverflow.com/a/12402596
if ( ( x != 0 ) ) // && errno == EAGAIN ) || ( x == 0 && errno == 0 ) )
Expand All @@ -145,10 +145,10 @@ void QgsSocketMonitoringThread::run( )
else
{
ssize_t x2 = 0;
for ( int i = 0; x2 == 0 && i < 10; i++ )
for ( int i = 0; false == mIsResponseFinished.load() && x2 == 0 && i < 10; i++ )
{
x2 = recv( mIpcFd, &c, 1, MSG_PEEK | MSG_DONTWAIT ); // see https://stackoverflow.com/a/12402596
QThread::msleep( 50L );
std::this_thread::sleep_for( 50ms );
}
if ( x2 == 0 )
{
Expand All @@ -167,10 +167,11 @@ void QgsSocketMonitoringThread::run( )
}

}
QThread::msleep( 333L );
if ( socketMonitoringMutex.try_lock_for( 333ms ) )
socketMonitoringMutex.unlock();
}

if ( mIsResponseFinished )
if ( mIsResponseFinished.load() )
{
QgsDebugMsgLevel( QStringLiteral( "FCGIServer::run %1: socket monitoring quits normally." ).arg( threadId ), 1 );
}
Expand All @@ -183,8 +184,7 @@ void QgsSocketMonitoringThread::run( )
// decrease the own count to allow deletion.
qDebug() << QDateTime::currentDateTime().toString( Qt::ISODateWithMs ).toStdString().c_str()
<< "FCGIServer::run" << threadId
<< "shared count:" << mySelf.use_count();
mySelf = nullptr;
<< "thread quit";
}


Expand All @@ -196,6 +196,7 @@ QgsFcgiServerResponse::QgsFcgiServerResponse( QgsServerRequest::Method method )
: mMethod( method )
, mFeedback( new QgsFeedback )
{
socketMonitoringMutex.lock();
qDebug() << QDateTime::currentDateTime().toString( Qt::ISODateWithMs ).toStdString().c_str()
<< "===================================================================================================";
mBuffer.open( QIODevice::ReadWrite );
Expand All @@ -204,22 +205,22 @@ QgsFcgiServerResponse::QgsFcgiServerResponse( QgsServerRequest::Method method )
// This is not a unique_ptr because we want the response and the thread to not depend on eachother lifecycle.
// The shared ptr is passed to the thread to increase the owner count and avoid QgsSocketMonitoringThread deletion
// when the thread is still running in the background.
mSocketMonitoringThread = std::make_shared<QgsSocketMonitoringThread>( mFeedback );
mSocketMonitoringThread->setShared( mSocketMonitoringThread );
mSocketMonitoringThread = std::make_unique<QgsSocketMonitoringThread>( mFeedback );

// start and detach the monitoring thread
std::thread mThread = std::thread( &QgsSocketMonitoringThread::run, mSocketMonitoringThread );
mThread.detach();
mThread = std::thread( &QgsSocketMonitoringThread::run, mSocketMonitoringThread.get() );
//mThread.detach();
}

QgsFcgiServerResponse::~QgsFcgiServerResponse()
{
mFinished = true;
// Inform the thread to quit when it ends its while loop
mSocketMonitoringThread->setResponseFinished( mFinished );
socketMonitoringMutex.unlock(); // will release any try_lock in socket monitoring thread
qDebug() << QDateTime::currentDateTime().toString( Qt::ISODateWithMs ).toStdString().c_str()
<< "QgsFcgiServerResponse::destructor"
<< "count:" << mSocketMonitoringThread.use_count();
<< "QgsFcgiServerResponse::destructor";
mThread.join();
}

void QgsFcgiServerResponse::removeHeader( const QString &key )
Expand Down
9 changes: 4 additions & 5 deletions src/server/qgsfcgiserverresponse.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
#include "qgsserverresponse.h"

#include <QBuffer>
#include <QThread>
#include <thread>

/**
* \ingroup server
Expand All @@ -48,13 +48,11 @@ class QgsSocketMonitoringThread
void run( );

void setResponseFinished( bool responseFinished );
void setShared( std::shared_ptr<QgsSocketMonitoringThread> ptr );

private:
bool mIsResponseFinished = false;
std::atomic_bool mIsResponseFinished;
std::shared_ptr<QgsFeedback> mFeedback;
int mIpcFd = -1;
std::shared_ptr<QgsSocketMonitoringThread> mySelf;
};

/**
Expand Down Expand Up @@ -121,7 +119,8 @@ class SERVER_EXPORT QgsFcgiServerResponse: public QgsServerResponse
QgsServerRequest::Method mMethod;
int mStatusCode = 0;

std::shared_ptr<QgsSocketMonitoringThread> mSocketMonitoringThread;
std::unique_ptr<QgsSocketMonitoringThread> mSocketMonitoringThread;
std::thread mThread;
std::shared_ptr<QgsFeedback> mFeedback;
};

Expand Down

0 comments on commit 8a62b11

Please sign in to comment.