From f2bdad6dc02998c6c2e739d6fa9bf413dc562e12 Mon Sep 17 00:00:00 2001
From: Lawrence Rust <lvr@softsystem.co.uk>
Date: Fri, 24 Jun 2011 18:35:08 +0200
Subject: [PATCH 46/47] mheg: Use a shared mutex to control access to QWaitCondition
This prevents spurious hangs in the mheg code when waiting for an absent file
to arrive.
Signed-off-by: Lawrence Rust <lvr@softsystem.co.uk>
---
mythtv/libs/libmythtv/mhi.cpp | 29 ++++++++++++++---------------
mythtv/libs/libmythtv/mhi.h | 1 +
2 files changed, 15 insertions(+), 15 deletions(-)
diff --git a/mythtv/libs/libmythtv/mhi.cpp b/mythtv/libs/libmythtv/mhi.cpp
index 81163ae..82c6608 100644
a
|
b
|
void MHIContext::StopEngine() |
146 | 146 | while (!m_stopped) |
147 | 147 | { |
148 | 148 | m_stop = true; |
149 | | m_engine_wait.wakeAll(); |
| 149 | {QMutexLocker locker(&m_engineLock); |
| 150 | m_engine_wait.wakeAll();} |
150 | 151 | usleep(1000); |
151 | 152 | } |
152 | 153 | pthread_join(m_engineThread, NULL); |
… |
… |
void *MHIContext::StartMHEGEngine(void *param) |
234 | 235 | |
235 | 236 | void MHIContext::RunMHEGEngine(void) |
236 | 237 | { |
237 | | // Qt4 requires a QMutex as a parameter... |
238 | | // not sure if this is the best solution. Mutex Must be locked before wait. |
239 | | QMutex mutex; |
240 | | mutex.lock(); |
241 | | |
242 | 238 | while (!m_stop) |
243 | 239 | { |
244 | 240 | int toWait; |
… |
… |
void MHIContext::RunMHEGEngine(void) |
268 | 264 | if (toWait > 1000 || toWait <= 0) |
269 | 265 | toWait = 1000; |
270 | 266 | |
271 | | m_engine_wait.wait(&mutex, toWait); |
| 267 | QMutexLocker locker(&m_engineLock); |
| 268 | m_engine_wait.wait(&m_engineLock, toWait); |
272 | 269 | } |
273 | 270 | } |
274 | 271 | |
… |
… |
void MHIContext::QueueDSMCCPacket( |
309 | 306 | return; |
310 | 307 | |
311 | 308 | memcpy(dataCopy, data, length*sizeof(unsigned char)); |
312 | | QMutexLocker locker(&m_dsmccLock); |
| 309 | {QMutexLocker locker(&m_dsmccLock); |
313 | 310 | m_dsmccQueue.enqueue(new DSMCCPacket(dataCopy, length, |
314 | 311 | componentTag, carouselId, |
315 | | dataBroadcastId)); |
| 312 | dataBroadcastId));} |
| 313 | QMutexLocker locker(&m_engineLock); |
316 | 314 | m_engine_wait.wakeAll(); |
317 | 315 | } |
318 | 316 | |
… |
… |
void MHIContext::SetNetBootInfo(const unsigned char *data, uint length) |
333 | 331 | if (m_lastNbiVersion == NBI_VERSION_UNSET) |
334 | 332 | m_lastNbiVersion = data[0]; |
335 | 333 | else |
| 334 | { |
| 335 | QMutexLocker locker(&m_engineLock); |
336 | 336 | m_engine_wait.wakeAll(); |
| 337 | } |
337 | 338 | } |
338 | 339 | |
339 | 340 | void MHIContext::NetworkBootRequested(void) |
… |
… |
bool MHIContext::GetCarouselData(QString objectPath, QByteArray &result) |
380 | 381 | // same thread this is safe. Otherwise we need to make a deep copy of |
381 | 382 | // the result. |
382 | 383 | |
383 | | // Qt4 requires a QMutex as a parameter... |
384 | | // not sure if this is the best solution. Mutex Must be locked before wait. |
385 | | QMutex mutex; |
386 | | mutex.lock(); |
387 | | |
388 | 384 | while (!m_stop) |
389 | 385 | { |
390 | 386 | int res = m_dsmcc->GetDSMCCObject(path, result); |
… |
… |
bool MHIContext::GetCarouselData(QString objectPath, QByteArray &result) |
397 | 393 | // some more packets. We should eventually find out if this item is |
398 | 394 | // present. |
399 | 395 | ProcessDSMCCQueue(); |
400 | | m_engine_wait.wait(&mutex, 1000); |
| 396 | QMutexLocker locker(&m_engineLock); |
| 397 | m_engine_wait.wait(&m_engineLock, 1000); |
401 | 398 | } |
402 | 399 | return false; // Stop has been set. Say the object isn't present. |
403 | 400 | } |
… |
… |
bool MHIContext::OfferKey(QString key) |
475 | 472 | m_keyQueue.enqueue(action); |
476 | 473 | VERBOSE(VB_IMPORTANT, "Adding MHEG key "<<key<<":"<<action |
477 | 474 | <<":"<<m_keyQueue.size()); |
| 475 | locker.unlock(); |
| 476 | QMutexLocker locker2(&m_engineLock); |
478 | 477 | m_engine_wait.wakeAll(); |
479 | 478 | return true; |
480 | 479 | } |
diff --git a/mythtv/libs/libmythtv/mhi.h b/mythtv/libs/libmythtv/mhi.h
index 63bae67..3920ae3 100644
a
|
b
|
class MHIContext : public MHContext |
159 | 159 | MHEG *m_engine; // Pointer to the MHEG engine |
160 | 160 | |
161 | 161 | QWaitCondition m_engine_wait; |
| 162 | QMutex m_engineLock; |
162 | 163 | bool m_stop; |
163 | 164 | bool m_stopped; |
164 | 165 | QMutex m_display_lock; |