Continues migration with DDS, Common
This commit is contained in:
1 parent
9b15cee841
commit
fa48db111e
668 files changed
+111841
-2
No files matched your search
Executable
+330
@@ -0,0 +1,330 @@
|
||||
#include "generic_ftc_threading.h"
|
||||
|
||||
#include <QAtomicInt>
|
||||
#include <QTimer>
|
||||
|
||||
#include <QRegularExpression>
|
||||
|
||||
#include <chrono>
|
||||
#include <future>
|
||||
|
||||
#ifdef Q_OS_LINUX
|
||||
#include <pthread.h>
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Threading::~Threading()
|
||||
{
|
||||
if (m_threadLifetime != nullptr)
|
||||
{
|
||||
m_threadLifetime->stop();
|
||||
m_threadLifetime.reset();
|
||||
}
|
||||
|
||||
setCleanupNeeded(false);
|
||||
|
||||
{
|
||||
std::lock_guard<std::mutex> l(m_conditionMutex);
|
||||
setRun(false);
|
||||
}
|
||||
|
||||
if (!m_used)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
if (m_thread.joinable())
|
||||
{
|
||||
|
||||
m_condition.notify_all();
|
||||
m_thread.join();
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Threading::preInit() const
|
||||
{
|
||||
m_partitionId = partitionId();
|
||||
m_partitionType = partitionType();
|
||||
|
||||
|
||||
|
||||
|
||||
const QString base(QStringLiteral("F%1%2").arg(m_partitionType.left(1)).arg(m_partitionId));
|
||||
|
||||
|
||||
const int baseLen = base.length();
|
||||
const int maxLen = 16 - 1 - baseLen;
|
||||
|
||||
|
||||
|
||||
|
||||
if (maxLen < 1)
|
||||
{
|
||||
Q_ASSERT(false);
|
||||
m_threadName = functionTopicName();
|
||||
return;
|
||||
}
|
||||
|
||||
const QString orgName(functionTopicName());
|
||||
QString name;
|
||||
|
||||
if (orgName.length() > maxLen)
|
||||
{
|
||||
QRegularExpression regexp(QStringLiteral("[A-Z][a-z]*"));
|
||||
auto matches = regexp.globalMatch(functionTopicName());
|
||||
|
||||
QStringList words;
|
||||
while (matches.hasNext())
|
||||
{
|
||||
const auto word = matches.next().capturedTexts().join(QString());
|
||||
|
||||
words += word;
|
||||
}
|
||||
|
||||
if (words.isEmpty())
|
||||
{
|
||||
Q_ASSERT(false);
|
||||
m_threadName = functionTopicName();
|
||||
return;
|
||||
}
|
||||
|
||||
int wordsLeft = words.count();
|
||||
|
||||
|
||||
if (wordsLeft < 1)
|
||||
{
|
||||
Q_ASSERT(false);
|
||||
m_threadName = functionTopicName();
|
||||
return;
|
||||
}
|
||||
|
||||
int bremse = 20;
|
||||
while (wordsLeft > 0)
|
||||
{
|
||||
if (bremse < 1)
|
||||
{
|
||||
Q_ASSERT(false);
|
||||
break;
|
||||
}
|
||||
bremse--;
|
||||
|
||||
const int lenRest = maxLen - name.count();
|
||||
if (lenRest < 1)
|
||||
{
|
||||
Q_ASSERT(false);
|
||||
m_threadName = functionTopicName();
|
||||
return;
|
||||
}
|
||||
|
||||
const int maxWordLen = lenRest / wordsLeft;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
if (words.isEmpty())
|
||||
{
|
||||
Q_ASSERT(false);
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
name += words.takeFirst().leftRef(maxWordLen);
|
||||
|
||||
wordsLeft--;
|
||||
}
|
||||
|
||||
|
||||
|
||||
const int finalLeft = maxLen - name.count();
|
||||
if (finalLeft < 0 || (finalLeft > 0 && functionTopicName().length() > maxLen))
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
name = orgName;
|
||||
}
|
||||
|
||||
m_threadName = QStringLiteral("%1%2[%3]").arg(base, name).arg(qrand(), 8, 16, QLatin1Char('0'));
|
||||
}
|
||||
|
||||
|
||||
const QString &Threading::threadName() const
|
||||
{
|
||||
if (m_threadName.isEmpty())
|
||||
{
|
||||
|
||||
Q_ASSERT(false);
|
||||
}
|
||||
|
||||
return m_threadName;
|
||||
}
|
||||
|
||||
|
||||
const char *Threading::posixThreadName() const
|
||||
{
|
||||
if (m_posixThreadName.empty())
|
||||
{
|
||||
m_posixThreadName = threadName().left(15).toStdString();
|
||||
}
|
||||
|
||||
return m_posixThreadName.c_str();
|
||||
}
|
||||
|
||||
|
||||
void Threading::createThread()
|
||||
{
|
||||
if (!isRun())
|
||||
{
|
||||
if (m_thread.joinable())
|
||||
{
|
||||
|
||||
m_condition.notify_all();
|
||||
m_thread.join();
|
||||
threadDone();
|
||||
|
||||
}
|
||||
|
||||
m_alreadyThreaded = 0;
|
||||
|
||||
|
||||
setRun(true);
|
||||
|
||||
m_thread = std::thread(&Threading::run, this, threadName());
|
||||
|
||||
#ifdef Q_OS_LINUX
|
||||
pthread_setname_np(m_thread.native_handle(), posixThreadName());
|
||||
#endif
|
||||
}
|
||||
|
||||
m_createThreadCalledBefore = true;
|
||||
}
|
||||
|
||||
|
||||
void Threading::runThread()
|
||||
{
|
||||
m_used = true;
|
||||
|
||||
Q_ASSERT(m_createThreadCalledBefore);
|
||||
m_createThreadCalledBefore = false;
|
||||
|
||||
{
|
||||
std::lock_guard<std::mutex> l(m_conditionMutex);
|
||||
setWorkAvailable(true);
|
||||
}
|
||||
m_condition.notify_all();
|
||||
|
||||
if (!m_threadLifetime)
|
||||
{
|
||||
m_threadLifetime.reset(new QTimer);
|
||||
m_threadLifetime->setSingleShot(true);
|
||||
m_threadLifetime->setInterval(11*1000);
|
||||
QObject::connect(m_threadLifetime.get(), &QTimer::timeout, m_threadLifetime.get(),
|
||||
[this]
|
||||
{
|
||||
bool workAvailable = false;
|
||||
bool run = false;
|
||||
bool working = false;
|
||||
{
|
||||
std::lock_guard<std::mutex> l(m_conditionMutex);
|
||||
workAvailable = isWorkAvailable();
|
||||
run = isRun();
|
||||
working = isWorking();
|
||||
}
|
||||
|
||||
if (workAvailable || working)
|
||||
{
|
||||
|
||||
m_threadLifetime->start();
|
||||
return;
|
||||
}
|
||||
|
||||
m_threadLifetime->deleteLater();
|
||||
m_threadLifetime = nullptr;
|
||||
|
||||
if (!run)
|
||||
{
|
||||
|
||||
Q_ASSERT(false);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
{
|
||||
std::lock_guard<std::mutex> l(m_conditionMutex);
|
||||
setRun(false);
|
||||
}
|
||||
m_condition.notify_all();
|
||||
});
|
||||
}
|
||||
|
||||
m_threadLifetime->start();
|
||||
}
|
||||
|
||||
|
||||
void Threading::run(const QString &threadName)
|
||||
{
|
||||
Q_ASSERT(m_alreadyThreaded == 0);
|
||||
m_alreadyThreaded = 1;
|
||||
|
||||
const std::string _tn = threadName.toStdString();
|
||||
const char *tn = _tn.c_str();
|
||||
|
||||
while (isRun())
|
||||
{
|
||||
try
|
||||
{
|
||||
{
|
||||
std::unique_lock<std::mutex> conditionLock(m_conditionMutex);
|
||||
|
||||
|
||||
m_condition.wait(conditionLock, [this]{ return (isWorkAvailable() || !isRun()); });
|
||||
|
||||
}
|
||||
|
||||
cancellationPoint();
|
||||
{
|
||||
std::lock_guard<std::mutex> l(m_conditionMutex);
|
||||
setWorking(true);
|
||||
}
|
||||
work();
|
||||
{
|
||||
std::lock_guard<std::mutex> l(m_conditionMutex);
|
||||
setWorking(false);
|
||||
}
|
||||
cancellationPoint();
|
||||
}
|
||||
catch (const CancelationPointReached &ex)
|
||||
{
|
||||
|
||||
break;
|
||||
}
|
||||
catch (const std::exception &ex)
|
||||
{
|
||||
fprintf(stderr, "[!] Threading::run: exception: %s (%s)\n", ex.what(), tn);
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
fprintf(stderr, "[!] Threading::run: unknown exception occured (%s) !!!\n", tn);
|
||||
}
|
||||
}
|
||||
|
||||
if (isCleanupNeeded())
|
||||
{
|
||||
|
||||
cleanupThread();
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user