sensor_base: add sensor event data caching for sync-read support 18/64518/1
authorMu-Woong Lee <muwoong.lee@samsung.com>
Thu, 31 Mar 2016 10:32:23 +0000 (19:32 +0900)
committerkibak.yoon <kibak.yoon@samsung.com>
Fri, 1 Apr 2016 12:12:27 +0000 (21:12 +0900)
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>
src/server/command_worker.cpp
src/server/sensor_base.cpp
src/server/sensor_base.h

index 48a3cb4..d088078 100644 (file)
@@ -696,30 +696,22 @@ out:
 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
@@ -728,7 +720,7 @@ bool command_worker::cmd_get_data(void *payload)
        // 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;
 
@@ -739,26 +731,23 @@ bool command_worker::cmd_get_data(void *payload)
                        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;
 }
index ad9ef95..6398cd6 100644 (file)
@@ -35,6 +35,7 @@ sensor_base::sensor_base()
 , m_permission(SENSOR_PERMISSION_STANDARD)
 , m_started(false)
 , m_client(0)
+, m_last_data(NULL)
 {
 }
 
@@ -148,6 +149,9 @@ bool sensor_base::stop(void)
                }
 
                m_started = false;
+
+               free(m_last_data);
+               m_last_data = NULL;
        }
 
        _I("[%s] sensor stopped, #client = %d", get_name(), m_client);
@@ -293,6 +297,8 @@ void sensor_base::set_permission(int permission)
 
 bool sensor_base::push(sensor_event_t *event)
 {
+       set_cache(event->data);
+
        AUTOLOCK(m_client_mutex);
 
        if (m_client <= 0)
@@ -302,6 +308,32 @@ bool sensor_base::push(sensor_event_t *event)
        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;
index 0e013d1..adbabc2 100644 (file)
@@ -50,6 +50,7 @@ public:
 
        /* 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);
@@ -92,6 +93,9 @@ private:
        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);
 
@@ -100,6 +104,8 @@ private:
 
        virtual bool on_start(void);
        virtual bool on_stop(void);
+
+       void set_cache(sensor_data_t *data);
 };
 
 #endif /* _SENSOR_BASE_H_ */