With this patch, sync-read requests from clients do not need to call get_data() functions of HALs anymore.
Change-Id: I00560691f23fe15a0d785f7597b78b75b939a930
Signed-off-by: Mu-Woong Lee <muwoong.lee@samsung.com>
bool command_worker::cmd_get_data(void *payload)
{
const unsigned int GET_DATA_MIN_INTERVAL = 10;
- int state = OP_ERROR;
- int remain_count;
+ int state;
bool adjusted = false;
int length;
- sensor_data_t *data;
+ sensor_data_t *data = NULL;
_D("CMD_GET_VALUE Handler invoked\n");
if (!is_permission_allowed()) {
_E("Permission denied to get data for client [%d], for sensor [0x%llx]",
m_client_id, m_sensor_id);
- state = OP_ERROR;
- data = NULL;
+ state = -EACCES;
goto out;
}
- remain_count = m_module->get_data(&data, &length);
-
- if (remain_count < 0) {
- state = OP_ERROR;
- data = NULL;
- goto out;
- }
+ state = m_module->get_cache(&data);
// In case of not getting sensor data, wait short time and retry again
// 1. changing interval to be less than 10ms
// 4. retrying to get data
// 5. repeat 2 ~ 4 operations RETRY_CNT times
// 6. reverting back to original interval
- if ((remain_count >= 0) && !data->timestamp) {
+ if (state == -ENODATA) {
const int RETRY_CNT = 10;
int retry = 0;
adjusted = true;
}
- while ((remain_count >= 0) && !data->timestamp && (retry++ < RETRY_CNT)) {
+ while ((state == -ENODATA) && (retry++ < RETRY_CNT)) {
_I("Wait sensor[0x%llx] data updated for client [%d] #%d", m_sensor_id, m_client_id, retry);
usleep(WAIT_TIME(retry));
- remain_count = m_module->get_data(&data, &length);
+ state = m_module->get_cache(&data);
}
if (adjusted)
m_module->add_interval(m_client_id, interval, false);
}
- if (data->timestamp)
- state = OP_SUCCESS;
-
if (state < 0) {
_E("Failed to get data for client [%d], for sensor [0x%llx]",
m_client_id, m_sensor_id);
}
out:
- send_cmd_get_data_done(state, data);
+ send_cmd_get_data_done(state < 0 ? OP_ERROR : OP_SUCCESS, data);
return true;
}
, m_permission(SENSOR_PERMISSION_STANDARD)
, m_started(false)
, m_client(0)
+, m_last_data(NULL)
{
}
}
m_started = false;
+
+ free(m_last_data);
+ m_last_data = NULL;
}
_I("[%s] sensor stopped, #client = %d", get_name(), m_client);
bool sensor_base::push(sensor_event_t *event)
{
+ set_cache(event->data);
+
AUTOLOCK(m_client_mutex);
if (m_client <= 0)
return true;
}
+void sensor_base::set_cache(sensor_data_t *data)
+{
+ AUTOLOCK(m_data_cache_mutex);
+
+ /* Caching the last known data for sync-read support */
+ if (m_last_data == NULL) {
+ m_last_data = (sensor_data_t*)malloc(sizeof(sensor_data_t));
+ retm_if(m_last_data == NULL, "Memory allocation failed");
+ }
+
+ memcpy(m_last_data, data, sizeof(sensor_data_t));
+}
+
+int sensor_base::get_cache(sensor_data_t **data)
+{
+ retv_if(m_last_data == NULL, -ENODATA);
+
+ *data = (sensor_data_t *)malloc(sizeof(sensor_data_t));
+ retvm_if(*data == NULL, -ENOMEM, "Memory allocation failed");
+
+ AUTOLOCK(m_data_cache_mutex);
+
+ memcpy(*data, m_last_data, sizeof(sensor_data_t));
+ return 0;
+}
+
bool sensor_base::set_interval(unsigned long interval)
{
return true;
/* set/get data */
virtual int get_data(sensor_data_t **data, int *length);
+ int get_cache(sensor_data_t **data);
virtual bool flush(void);
virtual int add_attribute(int client_id, int32_t attribute, int32_t value);
unsigned int m_client;
cmutex m_client_mutex;
+ sensor_data_t *m_last_data;
+ cmutex m_data_cache_mutex;
+
virtual int set_attribute(int32_t attribute, int32_t value);
virtual int set_attribute(int32_t attribute, char *value, int value_size);
virtual bool on_start(void);
virtual bool on_stop(void);
+
+ void set_cache(sensor_data_t *data);
};
#endif /* _SENSOR_BASE_H_ */