Just Intonation  Version 1.3.0 (18)
Explore scale-independent dynamically adapting tuning in just intonation
threadworker.cpp
Go to the documentation of this file.
1 /*****************************************************************************
2  * Copyright 2016-2017 Karolin Stange, Christoph Wick, and Haye Hinrichsen
3  *
4  * This file is part of JustIntonation.
5  *
6  * JustIntonation is free software: you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by the
8  * Free Software Foundation, either version 3 of the License, or (at your
9  * option) any later version.
10  *
11  * JustIntonation is distributed in the hope that it will be useful, but
12  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13  * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14  * for more details.
15  *
16  * You should have received a copy of the GNU General Public License along
17  * with JustIntonation. If not, see http://www.gnu.org/licenses/.
18  *****************************************************************************/
19 
20 //=============================================================================
21 // Thread worker class
22 //=============================================================================
23 
24 #include "threadworker.h"
25 
26 #include <QDebug>
27 #include <QTimer>
28 
29 #include "threadbase.h"
30 
31 //-----------------------------------------------------------------------------
32 // Constructor
33 //-----------------------------------------------------------------------------
41 
43  : QThread()
44  , pThreadBase(threadbase)
45  , mThreadName("")
46  , mPriority(QThread::NormalPriority)
47  , mInterval(1000)
48  , mFirstInterval(0)
49 {
50 }
51 
52 
53 //-----------------------------------------------------------------------------
54 // Set priority
55 //-----------------------------------------------------------------------------
62 
63 void ThreadWorker::setPriority (const QThread::Priority priority)
64 {
65  mPriority = priority;
66  if (isRunning()) QThread::setPriority (mPriority);
67 }
68 
69 
70 //-----------------------------------------------------------------------------
71 // Set timer interval
72 //-----------------------------------------------------------------------------
81 
82 void ThreadWorker::setTimerInterval(const int msec, const int firstMsec)
83 {
84  mInterval = msec;
85  mFirstInterval = firstMsec;
86  if (isRunning())
87  LOGWARNING << "setTimerInterval(...) called while thread is running";
88 }
89 
90 
91 
92 //-----------------------------------------------------------------------------
93 // Set thread name
94 //-----------------------------------------------------------------------------
100 
101 void ThreadWorker::setThreadName(const QString name)
102 {
103  mThreadName = name;
104  if (mThreadName.size()>0 and isRunning())
106 }
107 
108 
109 //-----------------------------------------------------------------------------
110 // Start thread worker
111 //-----------------------------------------------------------------------------
120 
122 {
123  setModuleName(pThreadBase->getModuleName());
124  LOGMESSAGE << "Request to start thread, assigned name =" << mThreadName;
125  QThread::start(mPriority);
126 
127  // If it does not start immediately wait 1msec
128  if (not isRunning()) msleep(1);
129 
130  // If it does not start after 1 msec return error
131  if (not isRunning())
132  {
133  LOGERROR << "Could not start the thread with the assigned name" << mThreadName;
134  return false;
135  }
136  // All slots of the base class shall be executed in the new thread
137  // This is essential since otherwise the components would
138  // run in the original thread
139  pThreadBase->moveToThread(this);
140  return true;
141 }
142 
143 
144 //-----------------------------------------------------------------------------
145 // Request thread for termination
146 //-----------------------------------------------------------------------------
157 
159 {
160  LOGMESSAGE << "Request to terminate thread" << mThreadName;
161  QThread::quit(); // Request thread to terminate
162  return wait(2000); // Wait for termination up to 2 seconds
163 }
164 
165 
166 //-----------------------------------------------------------------------------
167 // Private thread worker function, starting execution loop
168 //-----------------------------------------------------------------------------
175 
177 {
179  LOGSTATUS << "Thread is now running:" << getThreadName();
180  QTimer timer, first;
181  connect(&timer, &QTimer::timeout, pThreadBase, &ThreadBase::timeout);
182  connect(&first, &QTimer::timeout, pThreadBase, &ThreadBase::timeout);
183  first.setSingleShot(true);
184  connect(this, SIGNAL(startTimer()),&timer,SLOT(start()));
185  connect(this, SIGNAL(stopTimer()),&timer,SLOT(stop()));
187  do
188  {
189  if (pThreadBase->mSuspended)
190  {
191  while (pThreadBase->mSuspended) msleep(100);
192  LOGSTATUS << "Resume execution loop of thread" << getThreadName();
193  }
194  else { LOGSTATUS << "Entering execution loop of thread" << getThreadName(); }
195 
196  timer.start(mInterval);
197  if (mFirstInterval>0) first.start(mFirstInterval);
198  exec();
199  LOGSTATUS << "Leaving execution loop of thread" << getThreadName();
200  timer.stop();
201  if (pThreadBase->mSuspended) LOGMESSAGE << "Thread suspended";
202  }
203  while (pThreadBase->mSuspended);
205  LOGSTATUS << "Shutting down thread" << getThreadName();
206 }
207 
208 
209 
210 //-----------------------------------------------------------------------------
211 // Specify the current thread name
212 //-----------------------------------------------------------------------------
219 
220 void ThreadWorker::setCurrentThreadName (QString threadname)
221 {
222 #if defined(Q_OS_LINUX) && !defined(Q_OS_ANDROID)
223  pthread_setname_np (pthread_self(), threadname.toStdString().c_str());
224  LOGMESSAGE << threadname.toStdString().c_str() << "thread started:"
225  << getThreadName().toStdString().c_str();
226 #else
227  (void)threadname;
228  LOGMESSAGE << "Thread names are not avialable on this platform";
229 #endif
230 }
231 
232 //-----------------------------------------------------------------------------
233 // Get thread name or id
234 //-----------------------------------------------------------------------------
243 
245 {
246  QString s;
247 #if defined(Q_OS_LINUX) && !defined(Q_OS_ANDROID)
248  unsigned int id = (unsigned int)pthread_self();
249  char buffer[100];
250  pthread_getname_np(pthread_self(),buffer,100);
251  s += "id = " + QString::number(id) + " (" + QString(buffer) + ")";
252 #else
253  s = QString("(Thread name not available on this platform)");
254 #endif
255  return s;
256 }
257 
258 
QThread::Priority mPriority
Assigned priority of the thread.
Definition: threadworker.h:79
QString mThreadName
Assigned thread name.
Definition: threadworker.h:78
Universal base class for threaded modules.
Definition: threadbase.h:60
QString getThreadName() const
Helper function for debugging: Get the current thread id and time.
void setModuleName(const QString &name)
Specify the name of the class-specific module.
Definition: log.cpp:82
bool start()
Start thread and move base class to the new thread.
virtual void finallyCalledWorker()
Virtual worker function called when the thread stops.
Definition: threadbase.h:87
void setTimerInterval(const int msec, const int firstMsec)
Set timer interval in milliseconds.
virtual void initiallyCalledWorker()
Virtual worker function called when the thread is starting.
Definition: threadbase.h:85
#define LOGMESSAGE
Definition: log.h:43
void setPriority(const QThread::Priority p)
Specify the priority of the thread.
int mFirstInterval
Assigned periodic waiting time in milliseconds.
Definition: threadworker.h:80
#define LOGERROR
Definition: log.h:45
virtual void timeout()
Private timeout slot called by the worker.
Definition: threadbase.cpp:169
virtual void run() override final
Private thread worker function, starting execution loop.
void setThreadName(const QString name)
Set thread name.
ThreadBase * pThreadBase
Pointer back to the instance of the ThreadBase.
Definition: threadworker.h:77
bool stop()
Send a request to the thread for termination.
#define LOGSTATUS
Definition: log.h:42
void stopTimer()
Helper signal for stopping the temporarily existing timer.
void setCurrentThreadName(QString threadname)
Helper function for debugging: set the current thread name.
bool mSuspended
Flag indicating suspended state.
Definition: threadbase.h:100
ThreadWorker(ThreadBase *threadbase)
Constructor.
#define LOGWARNING
Definition: log.h:44
void startTimer()
Helper signal for starting the temporarily existing timer.