diff options
author | Alex Blasche <alexander.blasche@digia.com> | 2014-05-22 12:14:11 +0200 |
---|---|---|
committer | The Qt Project <gerrit-noreply@qt-project.org> | 2014-05-23 15:28:43 +0200 |
commit | 749cdff5289412780f0bb8e351cb140ba64d85ce (patch) | |
tree | 0a218bfb326b9ab566369779495f5007815e44d0 | |
parent | 5d6f97ed9450b88098e425d4cf963655b3508248 (diff) | |
download | qtlocation-749cdff5289412780f0bb8e351cb140ba64d85ce.tar.gz |
Fix crash on S4 when running Satellite and Position updates concurrently
This was caused due to unsynchronized access of data between two threads.
The Java satellite updates were sent before the receiving Qt thread could
finish its regular startup. As a consequence the received updates could
not be mapped to a receiving C++ class.
This patch synchronizes the startup and setup of the two threads and
ensures that the relvant data setup on the C++ side is done before the
update thread is started.
In addition some minor debug helpers were added for future references.
Task-number: QTBUG-39082
Change-Id: I1f24ddfcef038fa000801ddb6a3ea0959370f0d3
Reviewed-by: Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@digia.com>
-rw-r--r-- | src/plugins/position/android/jar/src/org/qtproject/qt5/android/positioning/QtPositioning.java | 30 | ||||
-rw-r--r-- | src/plugins/position/android/src/jnipositioning.cpp | 4 |
2 files changed, 23 insertions, 11 deletions
diff --git a/src/plugins/position/android/jar/src/org/qtproject/qt5/android/positioning/QtPositioning.java b/src/plugins/position/android/jar/src/org/qtproject/qt5/android/positioning/QtPositioning.java index f5725813..f2babd08 100644 --- a/src/plugins/position/android/jar/src/org/qtproject/qt5/android/positioning/QtPositioning.java +++ b/src/plugins/position/android/jar/src/org/qtproject/qt5/android/positioning/QtPositioning.java @@ -187,17 +187,18 @@ public class QtPositioning implements LocationListener try { boolean exceptionOccurred = false; QtPositioning positioningListener = new QtPositioning(); - positioningListener.setActiveLooper(true); positioningListener.nativeClassReference = androidClassKey; positioningListener.expectedProviders = locationProvider; positioningListener.isSatelliteUpdate = false; + //start update thread + positioningListener.setActiveLooper(true); if (updateInterval == 0) updateInterval = 1000; //don't update more often than once per second positioningListener.updateIntervalTime = updateInterval; if ((locationProvider & QT_GPS_PROVIDER) > 0) { - Log.d(TAG, "Regular updates using GPS"); + Log.d(TAG, "Regular updates using GPS " + updateInterval); try { locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, updateInterval, 0, @@ -210,7 +211,7 @@ public class QtPositioning implements LocationListener } if ((locationProvider & QT_NETWORK_PROVIDER) > 0) { - Log.d(TAG, "Regular updates using network"); + Log.d(TAG, "Regular updates using network " + updateInterval); try { locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, updateInterval, 0, @@ -263,11 +264,12 @@ public class QtPositioning implements LocationListener try { boolean exceptionOccurred = false; QtPositioning positioningListener = new QtPositioning(); - positioningListener.setActiveLooper(true); positioningListener.nativeClassReference = androidClassKey; positioningListener.isSingleUpdate = true; positioningListener.expectedProviders = locationProvider; positioningListener.isSatelliteUpdate = false; + //start update thread + positioningListener.setActiveLooper(true); if ((locationProvider & QT_GPS_PROVIDER) > 0) { Log.d(TAG, "Single update using GPS"); @@ -321,10 +323,11 @@ public class QtPositioning implements LocationListener boolean exceptionOccurred = false; QtPositioning positioningListener = new QtPositioning(); positioningListener.isSatelliteUpdate = true; - positioningListener.setActiveLooper(true); positioningListener.nativeClassReference = androidClassKey; positioningListener.expectedProviders = 1; //always satellite provider positioningListener.isSingleUpdate = isSingleRequest; + //start update thread + positioningListener.setActiveLooper(true); if (updateInterval == 0) updateInterval = 1000; //don't update more often than once per second @@ -385,9 +388,14 @@ public class QtPositioning implements LocationListener if (isSatelliteUpdate) looperThread.isSatelliteListener(true); + long start = System.currentTimeMillis(); looperThread.start(); + + //busy wait but lasts ~20-30 ms only while (!looperThread.isReady()); - Thread.sleep(1000); + + long stop = System.currentTimeMillis(); + Log.d(TAG, "Looper Thread startup time in ms: " + (stop-start)); } else { looperThread.quitLooper(); } @@ -411,7 +419,6 @@ public class QtPositioning implements LocationListener { Looper.prepare(); Handler handler = new Handler(); - looperRunning = true; if (isSatelliteLooper) { try { @@ -422,8 +429,13 @@ public class QtPositioning implements LocationListener } posLooper = Looper.myLooper(); + synchronized (this) { + looperRunning = true; + } Looper.loop(); - looperRunning = false; + synchronized (this) { + looperRunning = false; + } } public void quitLooper() @@ -433,7 +445,7 @@ public class QtPositioning implements LocationListener looper().quit(); } - public boolean isReady() + public synchronized boolean isReady() { return looperRunning; } diff --git a/src/plugins/position/android/src/jnipositioning.cpp b/src/plugins/position/android/src/jnipositioning.cpp index afae1c8e..d3cce65b 100644 --- a/src/plugins/position/android/src/jnipositioning.cpp +++ b/src/plugins/position/android/src/jnipositioning.cpp @@ -459,7 +459,7 @@ static void positionUpdated(JNIEnv *env, jobject /*thiz*/, jobject location, jin QGeoPositionInfoSourceAndroid *source = AndroidPositioning::idToPosSource()->value(androidClassKey); if (!source) { - qFatal("positionUpdated: source == 0"); + qWarning("positionUpdated: source == 0"); return; } @@ -479,7 +479,7 @@ static void locationProvidersDisabled(JNIEnv *env, jobject /*thiz*/, jint androi if (!source) source = AndroidPositioning::idToSatSource()->value(androidClassKey); if (!source) { - qFatal("locationProvidersDisabled: source == 0"); + qWarning("locationProvidersDisabled: source == 0"); return; } |