kwave  18.07.70
Kwave::WorkerThread Class Reference

#include <WorkerThread.h>

Inheritance diagram for Kwave::WorkerThread:
Inheritance graph
Collaboration diagram for Kwave::WorkerThread:
Collaboration graph

Public Member Functions

 WorkerThread (Kwave::Runnable *runnable, QVariant params)
 
virtual ~WorkerThread () Q_DECL_OVERRIDE
 
virtual void start ()
 
virtual int stop (unsigned int timeout=10000)
 
virtual void run () Q_DECL_OVERRIDE
 
virtual void cancel ()
 
bool shouldStop ()
 

Private Attributes

Kwave::Runnablem_runnable
 
QVariant m_params
 
QMutex m_lock
 
QMutex m_lock_sighup
 
QAtomicInt m_should_stop
 
pthread_t m_tid
 
pthread_t m_owner_tid
 

Detailed Description

Definition at line 35 of file WorkerThread.h.

Constructor & Destructor Documentation

◆ WorkerThread()

Kwave::WorkerThread::WorkerThread ( Kwave::Runnable runnable,
QVariant  params 
)
explicit

Constructor

Definition at line 51 of file WorkerThread.cpp.

References _dummy_SIGHUP_handler(), and g_signal_handler_is_in_place.

52  :QThread(Q_NULLPTR),
53  m_runnable(runnable),
54  m_params(params),
55  m_lock(), m_lock_sighup(),
56  m_should_stop(0),
57  m_tid(pthread_self()),
58  m_owner_tid(pthread_self())
59 {
60  /* NOTE: we assume that this gets called from the GUI thread only */
61  Q_ASSERT(this->thread() == QThread::currentThread());
62  Q_ASSERT(this->thread() == qApp->thread());
63 
64  /* install handler for SIGHUP */
66  /*
67  * NOTE: the old signal handler is lost. But as long as we do not use
68  * SIGHUP in any other place of the application and we need to
69  * have a dummy handler only, that should not matter
70  */
71  signal(SIGHUP, _dummy_SIGHUP_handler);
73  }
74 }
static bool g_signal_handler_is_in_place
void _dummy_SIGHUP_handler(int)
QAtomicInt m_should_stop
Definition: WorkerThread.h:92
Kwave::Runnable * m_runnable
Definition: WorkerThread.h:80
Here is the call graph for this function:

◆ ~WorkerThread()

Kwave::WorkerThread::~WorkerThread ( )
virtual

Destructor, calls stop() if the thread is still running.

Definition at line 77 of file WorkerThread.cpp.

References stop().

78 {
79  if (isRunning()) {
80  qDebug("WorkerThread::~WorkerThread(): waiting for normal shutdown");
81  wait(2000);
82  qDebug("WorkerThread::~WorkerThread(): stopping");
83  stop(2000);
84  }
85  Q_ASSERT(!isRunning());
86 }
virtual int stop(unsigned int timeout=10000)
Here is the call graph for this function:

Member Function Documentation

◆ cancel()

void Kwave::WorkerThread::cancel ( )
virtual

Sets an internal flag that signals the worker thread to cancel, so that the next call to "shouldStop()" returns true.

Definition at line 176 of file WorkerThread.cpp.

References m_should_stop.

Referenced by Kwave::PlayBackPulseAudio::disconnectFromServer(), Kwave::RecordPulseAudio::disconnectFromServer(), Kwave::PlaybackController::run_wrapper(), and Kwave::PlaybackController::stopDevicePlayBack().

177 {
178  m_should_stop = 1;
179 }
QAtomicInt m_should_stop
Definition: WorkerThread.h:92
Here is the caller graph for this function:

◆ run()

void Kwave::WorkerThread::run ( )
virtual

A wrapper for the run() function, calls the run_wrapper(...) of m_runnable with the parameters passed in the constructor.

Reimplemented in Kwave::RecordThread.

Definition at line 154 of file WorkerThread.cpp.

References m_lock_sighup, m_owner_tid, m_params, m_runnable, m_tid, and Kwave::Runnable::run_wrapper().

155 {
156  Q_ASSERT(m_runnable);
157  if (!m_runnable) return;
158 
159  /* get the POSIX thread ID, needed for sending SIGHUP */
160  {
161  QMutexLocker _lock(&m_lock_sighup);
162  m_tid = pthread_self();
163  }
164 
165  /* call the run(...) function */
167 
168  /* avoid sending any SIGHUP by setting the m_tid to "invalid" */
169  {
170  QMutexLocker _lock(&m_lock_sighup);
171  m_tid = m_owner_tid;
172  }
173 }
virtual void run_wrapper(const QVariant &params)=0
Kwave::Runnable * m_runnable
Definition: WorkerThread.h:80
Here is the call graph for this function:

◆ shouldStop()

bool Kwave::WorkerThread::shouldStop ( )

Returns true if the thread should stop. Should be polled by the thread's run() function to wait for a termination signal.

Definition at line 182 of file WorkerThread.cpp.

References m_should_stop.

Referenced by Kwave::RecordThread::run(), and Kwave::PlaybackController::run_wrapper().

183 {
184  return (m_should_stop);
185 }
QAtomicInt m_should_stop
Definition: WorkerThread.h:92
Here is the caller graph for this function:

◆ start()

void Kwave::WorkerThread::start ( )
virtual

Starts the thread's execution.

Definition at line 89 of file WorkerThread.cpp.

References m_lock, and m_should_stop.

Referenced by Kwave::PlayBackPulseAudio::connectToServer(), Kwave::RecordPulseAudio::connectToServer(), Kwave::Plugin::execute(), Kwave::RecordPlugin::leaveInhibit(), and Kwave::PlaybackController::startDevicePlayBack().

90 {
91  QMutexLocker lock(&m_lock);
92 
93  // reset the "should stop" command flag
94  m_should_stop = 0;
95 
96  QThread::start();
97 }
QAtomicInt m_should_stop
Definition: WorkerThread.h:92
Here is the caller graph for this function:

◆ stop()

int Kwave::WorkerThread::stop ( unsigned int  timeout = 10000)
virtual

Stops the thread execution. Please note that you MUST call this function at the end if you derived a class from this one.

Parameters
timeoutthe timeout in milliseconds, default = 10s
Returns
zero if successful or an error code if failed
See also
errno.h

Definition at line 100 of file WorkerThread.cpp.

References m_lock, m_lock_sighup, m_owner_tid, m_should_stop, m_tid, and MAX_ATTEMPTS_TO_STOP.

Referenced by Kwave::PlayBackPulseAudio::disconnectFromServer(), Kwave::RecordPulseAudio::disconnectFromServer(), Kwave::RecordPlugin::enterInhibit(), Kwave::RecordPlugin::setup(), Kwave::RecordPlugin::setupRecordThread(), Kwave::Plugin::stop(), Kwave::Plugin::~Plugin(), Kwave::RecordThread::~RecordThread(), and ~WorkerThread().

101 {
102  QMutexLocker lock(&m_lock);
103  if (!isRunning()) return 0; // already down
104 
105  if (timeout < 1000) timeout = 1000;
106 
107  // set the "should stop" flag
108  m_should_stop = 1;
109 
110  // send one SIGHUP in advance
111  {
112  QMutexLocker _lock(&m_lock_sighup);
113  if (!pthread_equal(m_tid, m_owner_tid))
114  pthread_kill(m_tid, SIGHUP);
115  if (!isRunning()) return 0;
116  }
117 
118  // try to stop cooperatively
119  if (!isRunning()) return 0;
120  wait(timeout/10);
121  if (!isRunning()) return 0;
122 
123  // try to interrupt by HUP signal
124  qWarning("WorkerThread::stop(): sending SIGHUP");
125  for (unsigned int i = 0; i < MAX_ATTEMPTS_TO_STOP; i++) {
126  {
127  QMutexLocker _lock(&m_lock_sighup);
128  if (!isRunning()) return 0;
129  if (!pthread_equal(m_tid, m_owner_tid))
130  pthread_kill(m_tid, SIGHUP);
131  }
132  if (!isRunning()) return 0;
133  wait(timeout/10);
134  if (!isRunning()) return 0;
135  }
136 
137 #ifdef DEBUG_FIND_DEADLOCKS
138  if (running()) {
139  qDebug("WorkerThread::stop(): pthread_self()=%08X",
140  (unsigned int)pthread_self());
141  void *buf[256];
142  size_t n = backtrace(buf, 256);
143  backtrace_symbols_fd(buf, n, 2);
144  }
145 #endif
146 
147  qDebug("WorkerThread::stop(): canceling thread");
148  terminate();
149 
150  return -1;
151 }
#define MAX_ATTEMPTS_TO_STOP
QAtomicInt m_should_stop
Definition: WorkerThread.h:92
Here is the caller graph for this function:

Member Data Documentation

◆ m_lock

QMutex Kwave::WorkerThread::m_lock
private

Mutex to control access to the thread itself

Definition at line 86 of file WorkerThread.h.

Referenced by start(), and stop().

◆ m_lock_sighup

QMutex Kwave::WorkerThread::m_lock_sighup
private

Mutex for protecting SIGHUP <-> thread exit

Definition at line 89 of file WorkerThread.h.

Referenced by run(), and stop().

◆ m_owner_tid

pthread_t Kwave::WorkerThread::m_owner_tid
private

POSIX compatible thread ID of the owner thread.

Definition at line 102 of file WorkerThread.h.

Referenced by run(), and stop().

◆ m_params

QVariant Kwave::WorkerThread::m_params
private

parameter pointer passed to the run() function

Definition at line 83 of file WorkerThread.h.

Referenced by run().

◆ m_runnable

Kwave::Runnable* Kwave::WorkerThread::m_runnable
private

pointer to the object that has a run() function

Definition at line 80 of file WorkerThread.h.

Referenced by run().

◆ m_should_stop

QAtomicInt Kwave::WorkerThread::m_should_stop
private

set to 1 to signal the thread that it should stop

Definition at line 92 of file WorkerThread.h.

Referenced by cancel(), shouldStop(), start(), and stop().

◆ m_tid

pthread_t Kwave::WorkerThread::m_tid
private

POSIX compatible thread ID of the worker thread. only needed and only valid while the thread is running. (needs a POSIX 1003.1-2001 system libc)

Definition at line 99 of file WorkerThread.h.

Referenced by run(), and stop().


The documentation for this class was generated from the following files: