summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorConstantin Musca <constantin.musca@intel.com>2016-02-03 00:09:11 +0000
committerandroid-build-merger <android-build-merger@google.com>2016-02-03 00:09:11 +0000
commit0be6534f03823dea5ba20e3b529a1fc21b9646da (patch)
tree14639e8dacc0b745adca8d3745dc9b7ae38046e4
parentc7b07f8429f174944ea76cf4c1ed6152b1e08a29 (diff)
parent017e5df408ad372efd8897eb24575d69a824281e (diff)
downloadintel-0be6534f03823dea5ba20e3b529a1fc21b9646da.tar.gz
sensors: make the HAL thread safe
am: 017e5df408 * commit '017e5df408ad372efd8897eb24575d69a824281e': sensors: make the HAL thread safe
-rw-r--r--peripheral/sensors/mraa/AcquisitionThread.cpp9
-rw-r--r--peripheral/sensors/mraa/Sensor.cpp17
-rw-r--r--peripheral/sensors/mraa/SensorsHAL.cpp29
-rw-r--r--peripheral/sensors/mraa/SensorsHAL.hpp3
4 files changed, 48 insertions, 10 deletions
diff --git a/peripheral/sensors/mraa/AcquisitionThread.cpp b/peripheral/sensors/mraa/AcquisitionThread.cpp
index c1c9206..8485508 100644
--- a/peripheral/sensors/mraa/AcquisitionThread.cpp
+++ b/peripheral/sensors/mraa/AcquisitionThread.cpp
@@ -121,7 +121,7 @@ bool AcquisitionThread::init() {
}
/* create pipe to signal events to the main thread */
- rc = pipe(pipeFds);
+ rc = pipe2(pipeFds, O_NONBLOCK);
if (rc != 0) {
ALOGE("%s: Cannot initialize pipe", __func__);
goto pipe_err;
@@ -175,7 +175,12 @@ bool AcquisitionThread::generateFlushCompleteEvent() {
data.meta_data.sensor = sensor->getHandle();
data.meta_data.what = META_DATA_FLUSH_COMPLETE;
- /* send the event via the associated pipe */
+ /*
+ * Send the event via the associated pipe. It doesn't need to be in a loop
+ * as O_NONBLOCK is enabled and the number of bytes is <= PIPE_BUF.
+ * If there is room to write n bytes to the pipe, then write succeeds
+ * immediately, writing all n bytes; otherwise write fails.
+ */
rc = write(getWritePipeFd(), &data, sizeof(sensors_event_t));
if (rc != sizeof(sensors_event_t)) {
ALOGE("%s: not all data has been sent over the pipe", __func__);
diff --git a/peripheral/sensors/mraa/Sensor.cpp b/peripheral/sensors/mraa/Sensor.cpp
index db76bda..849f380 100644
--- a/peripheral/sensors/mraa/Sensor.cpp
+++ b/peripheral/sensors/mraa/Sensor.cpp
@@ -36,7 +36,9 @@ Sensor::~Sensor() {
int Sensor::activate(int handle, int enabled) { return 0; }
bool Sensor::readOneEvent(sensors_event_t *event) {
- int rc;
+ int bytes_read = 0, bytes_to_read = sizeof(sensors_event_t);
+ int fd = -1;
+ char *ptr = (char *)event;
if (acquisitionThread == nullptr) {
ALOGE("%s: sensor %d doesn't have an acquisition thread", __func__, handle);
@@ -44,8 +46,17 @@ bool Sensor::readOneEvent(sensors_event_t *event) {
}
/* read one event from the pipe read endpoint */
- rc = read(acquisitionThread->getReadPipeFd(), event, sizeof(sensors_event_t));
- if (rc != sizeof(sensors_event_t)) {
+ fd = acquisitionThread->getReadPipeFd();
+ do {
+ bytes_read = read(fd, ptr, bytes_to_read);
+ if (bytes_read <= 0) {
+ break;
+ }
+ bytes_to_read -= bytes_read;
+ ptr += bytes_read;
+ } while (bytes_to_read > 0);
+
+ if (bytes_to_read != 0) {
return false;
}
diff --git a/peripheral/sensors/mraa/SensorsHAL.cpp b/peripheral/sensors/mraa/SensorsHAL.cpp
index 94f768d..eebcd45 100644
--- a/peripheral/sensors/mraa/SensorsHAL.cpp
+++ b/peripheral/sensors/mraa/SensorsHAL.cpp
@@ -24,6 +24,7 @@
Sensor * (*SensorContext::sensorFactoryFuncs[MAX_DEVICES])(int);
struct sensor_t SensorContext::sensorDescs[MAX_DEVICES];
int SensorContext::sensorsNum = 0;
+android::Mutex SensorContext::mutex;
SensorContext::SensorContext(const hw_module_t *module) {
/* create the epoll fd used to register the incoming fds */
@@ -65,6 +66,8 @@ SensorContext::~SensorContext() {
int SensorContext::addSensorModule(struct sensor_t *sensorDesc,
Sensor * (*sensorFactoryFunc)(int)) {
+ android::Mutex::Autolock autolock(mutex);
+
if ((sensorDesc == nullptr) || (sensorFactoryFunc == nullptr)) {
ALOGE("%s: cannot add a null sensor", __func__);
return -EINVAL;
@@ -102,6 +105,8 @@ int SensorContext::OpenWrapper(const struct hw_module_t *module,
int SensorContext::GetSensorsListWrapper(struct sensors_module_t *module,
struct sensor_t const **list) {
+ android::Mutex::Autolock autolock(mutex);
+
if (!list || (sensorsNum == 0)) {
return 0;
}
@@ -188,27 +193,32 @@ int SensorContext::pollEvents(sensors_event_t *data, int count) {
return nfds;
}
+ mutex.lock();
for(i = 0; i < nfds && returnedEvents < count; i++) {
if (ev[i].events == EPOLLIN) {
sensorIndex = ev[i].data.u32;
if ((sensorIndex < 0) || (sensorIndex > sensorsNum)) {
ALOGE("%s: Invalid sensor index", __func__);
+ mutex.unlock();
return -1;
}
if (sensors[sensorIndex] == nullptr) {
- ALOGE("%s: Sensor %d is not activated", __func__, sensorIndex);
- return -1;
+ /* The sensor might have been deactivated by another thread */
+ continue;
}
+ /*
+ * The read operation might fail if the data is read by another
+ * pollEvents call executed by another thread.
+ */
if (sensors[sensorIndex]->readOneEvent(data + returnedEvents)) {
returnedEvents++;
- } else {
- ALOGE("%s: Cannot read event from sensor %d", __func__, sensorIndex);
- return -1;
}
}
}
+ mutex.unlock();
+
if (returnedEvents > 0) {
return returnedEvents;
}
@@ -248,6 +258,7 @@ int SensorContext::flush(int handle) {
int SensorContext::CloseWrapper(hw_device_t *dev) {
SensorContext *sensorContext = reinterpret_cast<SensorContext *>(dev);
+ android::Mutex::Autolock autolock(mutex);
if (sensorContext != nullptr) {
delete sensorContext;
@@ -258,11 +269,15 @@ int SensorContext::CloseWrapper(hw_device_t *dev) {
int SensorContext::ActivateWrapper(sensors_poll_device_t *dev,
int handle, int enabled) {
+ android::Mutex::Autolock autolock(mutex);
+
return reinterpret_cast<SensorContext *>(dev)->activate(handle, enabled);
}
int SensorContext::SetDelayWrapper(sensors_poll_device_t *dev,
int handle, int64_t ns) {
+ android::Mutex::Autolock autolock(mutex);
+
return reinterpret_cast<SensorContext *>(dev)->setDelay(handle, ns);
}
@@ -273,12 +288,16 @@ int SensorContext::PollEventsWrapper(sensors_poll_device_t *dev,
int SensorContext::BatchWrapper(sensors_poll_device_1_t *dev, int handle,
int flags, int64_t period_ns, int64_t timeout) {
+ android::Mutex::Autolock autolock(mutex);
+
return reinterpret_cast<SensorContext *>(dev)->batch(handle, flags, period_ns,
timeout);
}
int SensorContext::FlushWrapper(sensors_poll_device_1_t *dev,
int handle) {
+ android::Mutex::Autolock autolock(mutex);
+
return reinterpret_cast<SensorContext *>(dev)->flush(handle);
}
diff --git a/peripheral/sensors/mraa/SensorsHAL.hpp b/peripheral/sensors/mraa/SensorsHAL.hpp
index 74bc8a4..0e7ef14 100644
--- a/peripheral/sensors/mraa/SensorsHAL.hpp
+++ b/peripheral/sensors/mraa/SensorsHAL.hpp
@@ -18,6 +18,7 @@
#define SENSORS_HAL_HPP
#include <hardware/sensors.h>
+#include <utils/Mutex.h>
#include "Sensor.hpp"
#include "SensorUtils.hpp"
@@ -109,6 +110,8 @@ class SensorContext {
static struct sensor_t sensorDescs[MAX_DEVICES];
/* Number of registered sensors */
static int sensorsNum;
+ /* Mutex used to synchronize the Sensor Context */
+ static android::Mutex mutex;
};
#endif // SENSORS_HAL_HPP