Android: Avoid deadlocks on suspend

Get rid of the rendezvous at shutdown: the android thread does not
need to wait for the GUI thread. Since the GUI thread frequently does
blocking calls to the android thread, this fixes several known and
potential deadlocks.

Task-number: QTBUG-41072
Change-Id: Ia6fa8da026b1727e7352b22f4df4d72b63b8c847
Reviewed-by: BogDan Vatra <bogdan@kde.org>
Reviewed-by: Christian Stromme <christian.stromme@digia.com>
This commit is contained in:
Paul Olav Tvete 2014-09-03 09:57:58 +02:00
parent a02d798bbd
commit 7e1e42cbf2
2 changed files with 14 additions and 9 deletions

View File

@ -55,20 +55,26 @@ QAndroidEventDispatcher::~QAndroidEventDispatcher()
QAndroidEventDispatcherStopper::instance()->removeEventDispatcher(this);
}
enum States {Running = 0, StopRequest = 1, Stopping = 2};
void QAndroidEventDispatcher::start()
{
if (m_stopRequest.testAndSetAcquire(1, 0)) {
m_dispatcherSemaphore.release();
int prevState = m_stopRequest.fetchAndStoreAcquire(Running);
if (prevState == Stopping) {
m_semaphore.release();
wakeUp();
} else if (prevState == Running) {
qWarning("Error: start without corresponding stop");
}
//else if prevState == StopRequest, no action needed
}
void QAndroidEventDispatcher::stop()
{
if (m_stopRequest.testAndSetAcquire(0, 1)) {
if (m_stopRequest.testAndSetAcquire(Running, StopRequest))
wakeUp();
m_stopperSemaphore.acquire();
}
else
qWarning("Error: start/stop out of sync");
}
void QAndroidEventDispatcher::goingToStop(bool stop)
@ -80,9 +86,8 @@ void QAndroidEventDispatcher::goingToStop(bool stop)
int QAndroidEventDispatcher::select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, timespec *timeout)
{
if (m_stopRequest.load() == 1) {
m_stopperSemaphore.release();
m_dispatcherSemaphore.acquire();
if (m_stopRequest.testAndSetAcquire(StopRequest, Stopping)) {
m_semaphore.acquire();
wakeUp();
}

View File

@ -66,7 +66,7 @@ protected:
private:
QAtomicInt m_stopRequest;
QAtomicInt m_goingToStop;
QSemaphore m_dispatcherSemaphore, m_stopperSemaphore;
QSemaphore m_semaphore;
};
class QAndroidEventDispatcherStopper