From 6c58c34835cb8616ea61c99129ad3876889fd5d5 Mon Sep 17 00:00:00 2001 From: "kibak.yoon" Date: Thu, 7 Apr 2016 22:48:12 +0900 Subject: [PATCH] sensord: use shared_ptr for sensor data which can be used in serveral callbacks * if app uses 2 more listener with the same sensor, then callback is called twice with the same sensor data. but in that case, because the first callback wrapper releases the data memory, second callback uses this data and even releases the memory which is already released. and it makes the crash. * so in order to fix it, shared_ptr is used. Change-Id: I48af5f35a55738d3a7469ab2fa6225e64e39cb71 Signed-off-by: kibak.yoon --- src/client/sensor_event_listener.cpp | 22 +++++++++++----------- src/client/sensor_event_listener.h | 5 +++-- 2 files changed, 14 insertions(+), 13 deletions(-) diff --git a/src/client/sensor_event_listener.cpp b/src/client/sensor_event_listener.cpp index b7be281..46ea3e8 100644 --- a/src/client/sensor_event_listener.cpp +++ b/src/client/sensor_event_listener.cpp @@ -34,6 +34,12 @@ using std::thread; using std::pair; using std::vector; +struct free_data { + void operator()(void *data) { + free(data); + } +}; + sensor_event_listener::sensor_event_listener() : m_poller(NULL) , m_thread_state(THREAD_STATE_TERMINATE) @@ -101,8 +107,6 @@ client_callback_info* sensor_event_listener::handle_calibration_cb(sensor_handle cal_event_info = handle_info.get_reg_event_info(cal_event_type); if ((accuracy == SENSOR_ACCURACY_BAD) && !handle_info.m_bad_accuracy && cal_event_info) { - void *cal_sensor_data; - cal_event_info->m_previous_event_time = time; event_info = handle_info.get_reg_event_info(event_type); @@ -116,7 +120,7 @@ client_callback_info* sensor_event_listener::handle_calibration_cb(sensor_handle cal_data->timestamp = time; cal_data->values[0] = accuracy; cal_data->value_count = 1; - cal_sensor_data = cal_data; + std::shared_ptr cal_sensor_data(cal_data, free_data()); cal_callback_info = get_callback_info(handle_info.m_sensor_id, cal_event_info, cal_sensor_data); @@ -131,14 +135,12 @@ client_callback_info* sensor_event_listener::handle_calibration_cb(sensor_handle return cal_callback_info; } - void sensor_event_listener::handle_events(void* event) { unsigned long long cur_time; reg_event_info *event_info = NULL; sensor_id_t sensor_id; sensor_handle_info_map handles_info; - void *sensor_data; int accuracy = SENSOR_ACCURACY_GOOD; @@ -149,9 +151,9 @@ void sensor_event_listener::handle_events(void* event) sensor_event_t *sensor_event = (sensor_event_t *)event; sensor_id = sensor_event->sensor_id; - sensor_data = sensor_event->data; cur_time = sensor_event->data->timestamp; accuracy = sensor_event->data->accuracy; + std::shared_ptr sensor_data(sensor_event->data, free_data()); { /* scope for the lock */ m_client_info.get_all_handle_info(handles_info); @@ -209,7 +211,7 @@ void sensor_event_listener::handle_events(void* event) } } -client_callback_info* sensor_event_listener::get_callback_info(sensor_id_t sensor_id, const reg_event_info *event_info, void* sensor_data) +client_callback_info* sensor_event_listener::get_callback_info(sensor_id_t sensor_id, const reg_event_info *event_info, std::shared_ptr sensor_data) { client_callback_info* callback_info; @@ -247,10 +249,9 @@ gboolean sensor_event_listener::callback_dispatcher(gpointer data) if (!sensor_event_listener::get_instance().is_valid_callback(cb_info)) { _W("Discard invalid callback cb(%#x)(%s, %#x, %#x) with id: %llu", - cb_info->cb, get_event_name(cb_info->event_type), cb_info->sensor_data, + cb_info->cb, get_event_name(cb_info->event_type), cb_info->sensor_data.get(), cb_info->user_data, cb_info->event_id); - free(cb_info->sensor_data); delete cb_info; return false; } @@ -258,9 +259,8 @@ gboolean sensor_event_listener::callback_dispatcher(gpointer data) if (cb_info->accuracy_cb) cb_info->accuracy_cb(cb_info->sensor, cb_info->timestamp, cb_info->accuracy, cb_info->accuracy_user_data); - ((sensor_cb_t) cb_info->cb)(cb_info->sensor, cb_info->event_type, (sensor_data_t *) cb_info->sensor_data, cb_info->user_data); + ((sensor_cb_t) cb_info->cb)(cb_info->sensor, cb_info->event_type, (sensor_data_t *) cb_info->sensor_data.get(), cb_info->user_data); - free(cb_info->sensor_data); delete cb_info; /* diff --git a/src/client/sensor_event_listener.h b/src/client/sensor_event_listener.h index baf6fb1..5199d83 100644 --- a/src/client/sensor_event_listener.h +++ b/src/client/sensor_event_listener.h @@ -34,6 +34,7 @@ #include #include #include +#include #include #include @@ -52,7 +53,7 @@ typedef struct { sensor_t sensor; unsigned int event_type; void *cb; - void *sensor_data; + std::shared_ptr sensor_data; void *user_data; sensor_accuracy_changed_cb_t accuracy_cb; unsigned long long timestamp; @@ -110,7 +111,7 @@ private: client_callback_info* handle_calibration_cb(sensor_handle_info &handle_info, unsigned event_type, unsigned long long time, int accuracy); void handle_events(void* event); - client_callback_info* get_callback_info(sensor_id_t sensor_id, const reg_event_info *event_info, void *sensor_data); + client_callback_info* get_callback_info(sensor_id_t sensor_id, const reg_event_info *event_info, std::shared_ptr sensor_data); unsigned long long renew_event_id(void); -- 2.7.4