From: Lukasz Bardeli Date: Thu, 7 Dec 2017 12:09:10 +0000 (+0100) Subject: [Iotcon] fix for crash while finding resource X-Git-Tag: submit/tizen_3.0/20171208.100556~1 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=e588fd2338d3c88a03d822c6d60d9dd0faaea580;p=platform%2Fcore%2Fapi%2Fwebapi-plugins.git [Iotcon] fix for crash while finding resource Fix for crash when ResourceFoundCallback is called first time with TIMEOUT and second time with proper value. Now data is deleted 10 seconds after time when device stopped finding resources [Verification] Code compiles without error. TCT tests 100% passrate Change-Id: I3320a70dabddbbb1b5ff8fcc0161dbe1ffc23b95 Signed-off-by: Lukasz Bardeli --- diff --git a/src/iotcon/iotcon_instance.cc b/src/iotcon/iotcon_instance.cc index 1ca926dd..d6506992 100644 --- a/src/iotcon/iotcon_instance.cc +++ b/src/iotcon/iotcon_instance.cc @@ -45,11 +45,6 @@ struct CallbackData { } }; -struct CallbackData2 { - common::PostCallback fun; - bool callback_called; -}; - long long GetId(const picojson::object& args) { return static_cast(args.find(kId)->second.get()); } @@ -110,7 +105,6 @@ void RemoteResourceResponseCallback(iotcon_remote_resource_h resource, iotcon_er ret = IotconUtils::ResponseToJson(response, &value.get()); if (CallbackDataManager::GetInstance()->IfExists(data.get())) { LoggerD("user_data was called earlier, so ignore."); - data.release(); return; } break; @@ -119,7 +113,6 @@ void RemoteResourceResponseCallback(iotcon_remote_resource_h resource, iotcon_er ret = IotconUtils::ConvertIotconError(err); if (CallbackDataManager::GetInstance()->IfExists(data.get())) { LoggerD("user_data was called earlier, so ignore."); - data.release(); return; } break; @@ -127,13 +120,13 @@ void RemoteResourceResponseCallback(iotcon_remote_resource_h resource, iotcon_er ret = IotconUtils::ConvertIotconError(err); if (CallbackDataManager::GetInstance()->IfExists(data.get())) { LoggerD("user_data was called earlier, so ignore."); - data.release(); return; } break; } CallbackDataManager::GetInstance()->Add(data.get()); data->fun(ret, value); + data.release(); } else { LoggerE("Native callback data is null"); } @@ -1302,38 +1295,28 @@ common::TizenResult IotconInstance::RemoteResourceSetTimeInterval(const picojson bool IotconInstance::ResourceFoundCallback(iotcon_remote_resource_h resource, iotcon_error_e result, void* user_data) { ScopeLogger(); - CallbackData2* data = static_cast(user_data); + CallbackData* data = static_cast(user_data); if (nullptr == data) { LoggerE("ResourceFoundCallback() failed. Ignoring callback"); return IOTCON_FUNC_STOP; } + picojson::value v{picojson::object{}}; + common::TizenResult ret = common::TizenSuccess(); switch (result) { case IOTCON_ERROR_NONE: + ret = IotconUtils::RemoteResourceToJson(resource, &v.get()); break; case IOTCON_ERROR_TIMEOUT: - LoggerD("IOTCON_TIMEOUT data->callback_called :%d", data->callback_called); - if (!data->callback_called) { - auto ret = IotconUtils::ConvertIotconError(result); - data->fun(ret, picojson::value{}); - } - delete data; - return IOTCON_FUNC_STOP; + LoggerD("IOTCON_TIMEOUT"); default: - auto ret = IotconUtils::ConvertIotconError(result); - data->fun(ret, picojson::value{}); - return IOTCON_FUNC_STOP; + ret = IotconUtils::ConvertIotconError(result); } - picojson::value json_result = picojson::value(picojson::object()); - - auto ret = IotconUtils::RemoteResourceToJson(resource, &(json_result.get())); + data->fun(ret, v); if (!ret) { - data->fun(ret, picojson::value{}); return IOTCON_FUNC_STOP; } - data->callback_called = true; - data->fun(ret, json_result); return IOTCON_FUNC_CONTINUE; } @@ -1386,9 +1369,7 @@ common::TizenResult IotconInstance::ClientFindResource(const picojson::object& a Post(kFindResourceListenerToken, common::TizenSuccess{response}); }; - CallbackData2* data = new CallbackData2{}; - data->fun = response; - data->callback_called = false; + CallbackData* data = new CallbackData{response}; LoggerD("Running find with:\nhost_address: %s,\nconnectivity_type: %d", host_address, connectivity_type); @@ -1397,6 +1378,20 @@ common::TizenResult IotconInstance::ClientFindResource(const picojson::object& a if (!result) { delete data; LogAndReturnTizenError(result); + } else { + int timeout = 60; //default value set much bigger than default value for iotcon = 30s + auto result = IotconUtils::ConvertIotconError(iotcon_get_timeout(&timeout)); + if (!result) { + LoggerE("iotcon_get_timeout - function call failed, using default value %d", timeout); + } else { + timeout = timeout + 10; //add 10 extra second to prevent too fast delete + } + // adding listener to delete data, when find would be finished + std::thread([data, timeout]() { + std::this_thread::sleep_for(std::chrono::seconds(timeout)); + LoggerD("Deleting resource find data: %p", data); + delete data; + }).detach(); } return common::TizenSuccess(); @@ -1471,7 +1466,7 @@ common::TizenResult IotconInstance::ClientRemovePresenceEventListener( bool IotconDeviceInfoCb(iotcon_device_info_h device_info, iotcon_error_e result, void* user_data) { ScopeLogger(); - CallbackData2* data = static_cast(user_data); + CallbackData* data = static_cast(user_data); if (nullptr == data) { LoggerE("IotconDeviceInfoCb() failed. Ignoring callback"); return IOTCON_FUNC_STOP; @@ -1483,21 +1478,17 @@ bool IotconDeviceInfoCb(iotcon_device_info_h device_info, iotcon_error_e result, switch (result) { case IOTCON_ERROR_NONE: ret = IotconUtils::DeviceInfoToJson(device_info, &v.get()); - data->callback_called = true; break; case IOTCON_ERROR_TIMEOUT: - LoggerD("IOTCON_TIMEOUT data->callback_called :%d", data->callback_called); - if (!data->callback_called) { - ret = IotconUtils::ConvertIotconError(result); - data->fun(ret, v); - } - delete data; - return IOTCON_FUNC_STOP; + LoggerD("IOTCON_TIMEOUT"); default: ret = IotconUtils::ConvertIotconError(result); } data->fun(ret, v); + if (!ret) { + return IOTCON_FUNC_STOP; + } return IOTCON_FUNC_CONTINUE; } @@ -1550,9 +1541,7 @@ common::TizenResult IotconInstance::ClientFindDeviceInfo(const picojson::object& Post(kFindDeviceInfoListenerToken, common::TizenSuccess{response}); }; - CallbackData2* data = new CallbackData2{}; - data->fun = response; - data->callback_called = false; + CallbackData* data = new CallbackData{response}; auto result = IotconUtils::ConvertIotconError( iotcon_find_device_info(host_address, con_type_e, query, IotconDeviceInfoCb, data)); @@ -1560,6 +1549,20 @@ common::TizenResult IotconInstance::ClientFindDeviceInfo(const picojson::object& if (!result) { delete data; LogAndReturnTizenError(result); + } else { + int timeout = 60; //default value set much bigger than default value for iotcon = 30s + auto result = IotconUtils::ConvertIotconError(iotcon_get_timeout(&timeout)); + if (!result) { + LoggerE("iotcon_get_timeout - function call failed, using default value %d", timeout); + } else { + timeout = timeout + 10; //add 10 extra second to prevent too fast delete + } + // adding listener to delete data, when find would be finished + std::thread([data, timeout]() { + std::this_thread::sleep_for(std::chrono::seconds(timeout)); + LoggerD("Deleting resource find data: %p", data); + delete data; + }).detach(); } return common::TizenSuccess(); @@ -1569,7 +1572,7 @@ bool IotconPlatformInfoCb(iotcon_platform_info_h platform_info, iotcon_error_e r void* user_data) { ScopeLogger(); - CallbackData2* data = static_cast(user_data); + CallbackData* data = static_cast(user_data); if (nullptr == data) { LoggerE("IotconPlatformInfoCb() failed. Ignoring callback"); return IOTCON_FUNC_STOP; @@ -1581,21 +1584,17 @@ bool IotconPlatformInfoCb(iotcon_platform_info_h platform_info, iotcon_error_e r switch (result) { case IOTCON_ERROR_NONE: ret = IotconUtils::PlatformInfoToJson(platform_info, &v.get()); - data->callback_called = true; break; case IOTCON_ERROR_TIMEOUT: - LoggerD("IOTCON_TIMEOUT data->callback_called :%d", data->callback_called); - if (!data->callback_called) { - ret = IotconUtils::ConvertIotconError(result); - data->fun(ret, v); - } - delete data; - return IOTCON_FUNC_STOP; + LoggerD("IOTCON_TIMEOUT"); default: ret = IotconUtils::ConvertIotconError(result); } data->fun(ret, v); + if (!ret) { + return IOTCON_FUNC_STOP; + } return IOTCON_FUNC_CONTINUE; } @@ -1648,9 +1647,7 @@ common::TizenResult IotconInstance::ClientFindPlatformInfo(const picojson::objec Post(kFindPlatformInfoListenerToken, common::TizenSuccess{response}); }; - CallbackData2* data = new CallbackData2{}; - data->fun = response; - data->callback_called = false; + CallbackData* data = new CallbackData{response}; auto result = IotconUtils::ConvertIotconError( iotcon_find_platform_info(host_address, con_type_e, query, IotconPlatformInfoCb, data)); @@ -1658,6 +1655,20 @@ common::TizenResult IotconInstance::ClientFindPlatformInfo(const picojson::objec if (!result) { delete data; LogAndReturnTizenError(result); + } else { + int timeout = 60; //default value set much bigger than default value for iotcon = 30s + auto result = IotconUtils::ConvertIotconError(iotcon_get_timeout(&timeout)); + if (!result) { + LoggerE("iotcon_get_timeout - function call failed, using default value %d", timeout); + } else { + timeout = timeout + 10; //add 10 extra second to prevent too fast delete + } + // adding listener to delete data, when find would be finished + std::thread([data, timeout]() { + std::this_thread::sleep_for(std::chrono::seconds(timeout)); + LoggerD("Deleting resource find data: %p", data); + delete data; + }).detach(); } return common::TizenSuccess();