From a489612b023b9bd4fca0a111ae88d819f99a04dd Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Thu, 21 Mar 2013 17:09:23 +0100 Subject: iOS: add QPointer guard to accelerometer and gyro MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Since we process data from the sensors using a callback queued to the application operation queue, we need to check that the qt sensor is still alive before accessing it. Change-Id: I697d72f94aedec34b125006d6405428e282bfc0d Reviewed-by: Tor Arne Vestbø Reviewed-by: Lorn Potter --- src/plugins/sensors/ios/iosaccelerometer.mm | 31 ++++++++++++++++++----------- src/plugins/sensors/ios/iosgyroscope.mm | 23 +++++++++++++-------- 2 files changed, 34 insertions(+), 20 deletions(-) (limited to 'src/plugins') diff --git a/src/plugins/sensors/ios/iosaccelerometer.mm b/src/plugins/sensors/ios/iosaccelerometer.mm index ab6e8c45..b657b507 100644 --- a/src/plugins/sensors/ios/iosaccelerometer.mm +++ b/src/plugins/sensors/ios/iosaccelerometer.mm @@ -39,11 +39,12 @@ ** ****************************************************************************/ -#include "iosaccelerometer.h" -#include "iosmotionmanager.h" - #include #include +#include + +#include "iosaccelerometer.h" +#include "iosmotionmanager.h" char const * const IOSAccelerometer::id("ios.accelerometer"); @@ -70,17 +71,23 @@ void IOSAccelerometer::start() int hz = sensor()->dataRate(); motionManager.accelerometerUpdateInterval = (hz == 0) ? 0 : 1. / hz; + QPointer self = this; [motionManager startAccelerometerUpdatesToQueue:m_updateQueue withHandler:^(CMAccelerometerData *data, NSError *error) { + // NSOperationQueue is multi-threaded, so we process the data by queuing a callback to + // the main application queue. By the time the callback executes, IOSAccelerometer might + // have been deleted, so we need an extra QPointer check for that: dispatch_async(dispatch_get_main_queue(), ^{ - Q_UNUSED(error); - // Convert from NSTimeInterval to microseconds and G to m/s2, and flip axes: - CMAcceleration acc = data.acceleration; - const qreal G = 9.8066; - m_reading.setTimestamp(quint64(data.timestamp * 1000000)); - m_reading.setX(qreal(acc.x) * G * -1); - m_reading.setY(qreal(acc.y) * G * -1); - m_reading.setZ(qreal(acc.z) * G * -1); - newReadingAvailable(); + if (self) { + Q_UNUSED(error); + // Convert from NSTimeInterval to microseconds and G to m/s2, and flip axes: + CMAcceleration acc = data.acceleration; + const qreal G = 9.8066; + m_reading.setTimestamp(quint64(data.timestamp * 1000000)); + m_reading.setX(qreal(acc.x) * G * -1); + m_reading.setY(qreal(acc.y) * G * -1); + m_reading.setZ(qreal(acc.z) * G * -1); + newReadingAvailable(); + } }); }]; } diff --git a/src/plugins/sensors/ios/iosgyroscope.mm b/src/plugins/sensors/ios/iosgyroscope.mm index 987f5688..03289913 100644 --- a/src/plugins/sensors/ios/iosgyroscope.mm +++ b/src/plugins/sensors/ios/iosgyroscope.mm @@ -40,6 +40,7 @@ ****************************************************************************/ #include +#include #include "iosmotionmanager.h" #include "iosgyroscope.h" @@ -69,17 +70,23 @@ void IOSGyroscope::start() int hz = sensor()->dataRate(); motionManager.gyroUpdateInterval = (hz == 0) ? 0 : 1. / hz; + QPointer self = this; NSOperationQueue *queue = static_cast(m_updateQueue); [motionManager startGyroUpdatesToQueue:queue withHandler:^(CMGyroData *data, NSError *error) { + // NSOperationQueue is multi-threaded, so we process the data by queuing a callback to + // the main application queue. By the time the callback executes, IOSAccelerometer might + // have been deleted, so we need an extra QPointer check for that: dispatch_async(dispatch_get_main_queue(), ^{ - Q_UNUSED(error); - // Convert NSTimeInterval to microseconds and radians to degrees: - CMRotationRate rate = data.rotationRate; - m_reading.setTimestamp(quint64(data.timestamp * 1000000)); - m_reading.setX((qreal(rate.x) / M_PI) * 180); - m_reading.setY((qreal(rate.y) / M_PI) * 180); - m_reading.setZ((qreal(rate.z) / M_PI) * 180); - newReadingAvailable(); + if (self) { + Q_UNUSED(error); + // Convert NSTimeInterval to microseconds and radians to degrees: + CMRotationRate rate = data.rotationRate; + m_reading.setTimestamp(quint64(data.timestamp * 1000000)); + m_reading.setX((qreal(rate.x) / M_PI) * 180); + m_reading.setY((qreal(rate.y) / M_PI) * 180); + m_reading.setZ((qreal(rate.z) / M_PI) * 180); + newReadingAvailable(); + } }); }]; } -- cgit v1.2.3