From 92af7daae6e2cfa796c300eab8a9221639c7e3ab Mon Sep 17 00:00:00 2001 From: zqz Date: Wed, 9 Jul 2025 17:21:42 +0800 Subject: [PATCH] queryTimeout Signed-off-by: zqz Change-Id: Ibc2c110265fc68b7e6ef69761441c2773540ea35 Signed-off-by: zqz --- .../service/data_share/common/qos_manager.h | 42 ++++++++++ .../data_share/data_share_service_impl.cpp | 77 ++++++++++++++++--- .../data_share/data_share_service_impl.h | 10 ++- .../data_share/data_share_service_stub.cpp | 37 +++------ .../data_share/data_share_service_stub.h | 1 - .../service/data_share/idata_share_service.h | 6 +- .../test/data_share_service_impl_test.cpp | 4 +- 7 files changed, 134 insertions(+), 43 deletions(-) create mode 100644 services/distributeddataservice/service/data_share/common/qos_manager.h diff --git a/services/distributeddataservice/service/data_share/common/qos_manager.h b/services/distributeddataservice/service/data_share/common/qos_manager.h new file mode 100644 index 000000000..8f3d1eac8 --- /dev/null +++ b/services/distributeddataservice/service/data_share/common/qos_manager.h @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef DATASHARESERVICE_QOS_MANAGER_H +#define DATASHARESERVICE_QOS_MANAGER_H + +#include "qos.h" +namespace OHOS { +namespace DataShare { + +class QosManager { +public: + QosManager() + { +#ifndef IS_EMULATOR + // set thread qos QOS_USER_INTERACTIVE + QOS::SetThreadQos(QOS::QosLevel::QOS_USER_INTERACTIVE); +#endif + } + ~QosManager() + { +#ifndef IS_EMULATOR + QOS::ResetThreadQos(); +#endif + } +}; + +} // namespace DataShare +} // namespace OHOS +#endif // DATASHARESERVICE_QOS_MANAGER_H \ No newline at end of file diff --git a/services/distributeddataservice/service/data_share/data_share_service_impl.cpp b/services/distributeddataservice/service/data_share/data_share_service_impl.cpp index 9fca1eee9..b6c6ef150 100644 --- a/services/distributeddataservice/service/data_share/data_share_service_impl.cpp +++ b/services/distributeddataservice/service/data_share/data_share_service_impl.cpp @@ -22,6 +22,7 @@ #include "account/account_delegate.h" #include "app_connect_manager.h" +#include "block_data.h" #include "common_event_manager.h" #include "common_event_support.h" #include "concurrent_task_client.h" @@ -62,6 +63,7 @@ #include "parameters.h" #include "dataproxy_handle_common.h" #include "proxy_data_manager.h" +#include "qos_manager.h" #include "datashare_observer.h" #include "subscriber_managers/proxy_data_subscriber_manager.h" @@ -73,6 +75,8 @@ using namespace OHOS::DistributedData; __attribute__((used)) DataShareServiceImpl::Factory DataShareServiceImpl::factory_; // decimal base static constexpr int DECIMAL_BASE = 10; +static constexpr int MAX_QUERYTIMEOUT_COUNT = 8; +std::atomic DataShareServiceImpl::queryTimeoutCount_ = 0; DataShareServiceImpl::BindInfo DataShareServiceImpl::binderInfo_; class DataShareServiceImpl::SystemAbilityStatusChangeListener : public SystemAbilityStatusChangeStub { @@ -220,17 +224,73 @@ std::pair DataShareServiceImpl::DeleteEx(const std::string &ur return ExecuteEx(uri, extUri, callingTokenId, false, callBack); } -std::shared_ptr DataShareServiceImpl::Query(const std::string &uri, const std::string &extUri, - const DataSharePredicates &predicates, const std::vector &columns, int &errCode) +std::pair> DataShareServiceImpl::QueryTimeout(const std::string &uri, + const std::string &extUri, const DataSharePredicates &predicates, + const std::vector &columns, DataShareOption &option) +{ + // 1. This function itself is an IPC call. 2. It is not allowed for other non-IPC requests to call this function. + int count = queryTimeoutCount_.fetch_add(1); + if (count >= MAX_QUERYTIMEOUT_COUNT) { + queryTimeoutCount_.fetch_sub(1); + ZLOGW("Query Timeout busy, uri: %{public}s", URIUtils::Anonymous(uri).c_str()); + return std::make_pair(E_RESULTSET_BUSY, nullptr); + } + auto pid = IPCSkeleton::GetCallingPid(); + auto tokenId = IPCSkeleton::GetCallingTokenID(); + auto resultTuple = std::make_shared>, std::chrono::milliseconds>>(option.timeout, + std::tuple{false, 0, nullptr}); + std::shared_ptr> overTime = std::make_shared>(false); + binderInfo_.executors->Execute([uri, extUri, predicates, columns, resultTuple, + pid, tokenId, overTime, this]() { + // set thread qos + QosManager qosManager; + if (overTime->load()) { + queryTimeoutCount_.fetch_sub(1); + return; + } + std::shared_ptr resultSet = nullptr; + auto callBack = [&uri, &predicates, &columns, pid, tokenId, &resultTuple, &resultSet, this] + (ProviderInfo &info, DistributedData::StoreMetaData &, + std::shared_ptr dbDelegate) -> std::pair { + std::string func = __FUNCTION__; + TimeoutReport timeoutReport({info.bundleName, info.moduleName, "", func, tokenId}, true); + auto [err, result] = dbDelegate->Query(info.tableName, predicates, columns, pid, tokenId); + if (err != E_OK) { + ReportExcuteFault(tokenId, info, err, func); + } + resultSet = std::move(result); + timeoutReport.Report(); + return std::make_pair(err, E_OK); + }; + auto [errVal, status] = ExecuteEx(uri, extUri, tokenId, true, callBack); + resultTuple->SetValue({true, errVal, std::move(resultSet)}); + queryTimeoutCount_.fetch_sub(1); + }); + auto [finish, status, res] = resultTuple->GetValue(); + if (finish) { + return std::make_pair(status, res); + } + overTime->store(true); + ZLOGW("Query Timeout, uri: %{public}s", URIUtils::Anonymous(uri).c_str()); + return std::make_pair(E_TIMEOUT_ERROR, nullptr); +} + +std::pair> DataShareServiceImpl::Query(const std::string &uri, + const std::string &extUri, const DataSharePredicates &predicates, + const std::vector &columns, DataShareOption &option) { std::string func = __FUNCTION__; - XCollie xcollie(std::string(LOG_TAG) + "::" + func, - XCollie::XCOLLIE_LOG | XCollie::XCOLLIE_RECOVERY); - if (GetSilentProxyStatus(uri, false) != E_OK) { + XCollie xcollie(std::string(LOG_TAG) + "::" + func, XCollie::XCOLLIE_LOG | XCollie::XCOLLIE_RECOVERY); + int errCode = GetSilentProxyStatus(uri, false); + if (errCode != E_OK) { ZLOGW("silent proxy disable, %{public}s", URIUtils::Anonymous(uri).c_str()); - return nullptr; + return std::make_pair(errCode, nullptr); + } + if (option.timeout != 0 && binderInfo_.executors != nullptr) { + return QueryTimeout(uri, extUri, predicates, columns, option); } - std::shared_ptr resultSet; + std::shared_ptr resultSet = nullptr; auto callingPid = IPCSkeleton::GetCallingPid(); auto callingTokenId = IPCSkeleton::GetCallingTokenID(); auto callBack = [&uri, &predicates, &columns, &resultSet, &callingPid, &callingTokenId, &func, this] @@ -248,8 +308,7 @@ std::shared_ptr DataShareServiceImpl::Query(const std::strin return std::make_pair(err, E_OK); }; auto [errVal, status] = ExecuteEx(uri, extUri, callingTokenId, true, callBack); - errCode = errVal; - return resultSet; + return std::make_pair(errVal, resultSet); } int32_t DataShareServiceImpl::AddTemplate(const std::string &uri, const int64_t subscriberId, const Template &tplt) diff --git a/services/distributeddataservice/service/data_share/data_share_service_impl.h b/services/distributeddataservice/service/data_share/data_share_service_impl.h index 04448e729..8408c10f9 100644 --- a/services/distributeddataservice/service/data_share/data_share_service_impl.h +++ b/services/distributeddataservice/service/data_share/data_share_service_impl.h @@ -30,6 +30,7 @@ #include "data_share_db_config.h" #include "data_share_service_stub.h" #include "data_share_silent_config.h" +#include "datashare_option.h" #include "datashare_template.h" #include "db_delegate.h" #include "eventcenter/event.h" @@ -50,8 +51,9 @@ public: DistributedData::StoreMetaData &, std::shared_ptr)>; DataShareServiceImpl() = default; virtual ~DataShareServiceImpl(); - std::shared_ptr Query(const std::string &uri, const std::string &extUri, - const DataSharePredicates &predicates, const std::vector &columns, int &errCode) override; + std::pair> Query(const std::string &uri, const std::string &extUri, + const DataSharePredicates &predicates, const std::vector &columns, + DataShareOption &option) override; int32_t AddTemplate(const std::string &uri, const int64_t subscriberId, const Template &tplt) override; int32_t DelTemplate(const std::string &uri, const int64_t subscriberId) override; std::vector Publish(const Data &data, const std::string &bundleNameOfProvider) override; @@ -154,6 +156,9 @@ private: bool VerifyPermission(const std::string &bundleName, const std::string &permission, bool isFromExtension, const int32_t tokenId); bool GetCallerBundleInfo(BundleInfo &callerBundleInfo); + std::pair> QueryTimeout(const std::string &uri, + const std::string &extUri, const DataSharePredicates &predicates, const std::vector &columns, + DataShareOption &option); static Factory factory_; static constexpr int32_t ERROR = -1; static constexpr int32_t ERROR_PERMISSION_DENIED = -2; @@ -169,6 +174,7 @@ private: static BindInfo binderInfo_; std::shared_ptr timerReceiver_ = nullptr; DataShareSilentConfig dataShareSilentConfig_; + static std::atomic queryTimeoutCount_; }; } // namespace OHOS::DataShare #endif // DATASHARESERVICE_DATA_SERVICE_IMPL_H diff --git a/services/distributeddataservice/service/data_share/data_share_service_stub.cpp b/services/distributeddataservice/service/data_share/data_share_service_stub.cpp index a1548b4f6..eb5b6b498 100644 --- a/services/distributeddataservice/service/data_share/data_share_service_stub.cpp +++ b/services/distributeddataservice/service/data_share/data_share_service_stub.cpp @@ -21,13 +21,14 @@ #include #include "common_utils.h" #include "data_share_obs_proxy.h" +#include "datashare_option.h" #include "hiview_adapter.h" #include "hiview_fault_adapter.h" #include "ipc_skeleton.h" #include "ishared_result_set.h" #include "itypes_util.h" #include "log_print.h" -#include "qos.h" +#include "qos_manager.h" #include "uri_utils.h" #include "utils/anonymous.h" #include "dataproxy_handle_common.h" @@ -35,23 +36,6 @@ namespace OHOS { namespace DataShare { -class DataShareServiceStub::QosManager { -public: - QosManager() - { -#ifndef IS_EMULATOR - // set thread qos QOS_USER_INTERACTIVE - QOS::SetThreadQos(QOS::QosLevel::QOS_USER_INTERACTIVE); -#endif - } - ~QosManager() - { -#ifndef IS_EMULATOR - QOS::ResetThreadQos(); -#endif - } -}; - bool DataShareServiceStub::CheckInterfaceToken(MessageParcel &data) { auto localDescriptor = IDataShareService::GetDescriptor(); @@ -125,19 +109,18 @@ int32_t DataShareServiceStub::OnDeleteEx(MessageParcel &data, MessageParcel &rep int32_t DataShareServiceStub::OnQuery(MessageParcel &data, MessageParcel &reply) { - std::string uri; - std::string extUri; DataSharePredicates predicate; std::vector columns; - if (!ITypesUtil::Unmarshal(data, uri, extUri, predicate, columns)) { - ZLOGE("Unmarshal uri:%{public}s columns size:%{public}zu", URIUtils::Anonymous(uri).c_str(), + DataShareParamSet paramSet; + if (!ITypesUtil::Unmarshal(data, paramSet, predicate, columns)) { + ZLOGE("Unmarshal uri:%{public}s columns size:%{public}zu", URIUtils::Anonymous(paramSet.uri).c_str(), columns.size()); return IPC_STUB_INVALID_DATA_ERR; } - int status = 0; - auto result = ISharedResultSet::WriteToParcel(Query(uri, extUri, predicate, columns, status), reply); - if (!ITypesUtil::Marshal(reply, status)) { - ZLOGE("Marshal status:0x%{public}x", status); + auto [errCode, resultset] = Query(paramSet.uri, paramSet.extUri, predicate, columns, paramSet.option); + auto result = ISharedResultSet::WriteToParcel(resultset, reply); + if (!ITypesUtil::Marshal(reply, errCode)) { + ZLOGE("Marshal status:0x%{public}x", errCode); return IPC_STUB_WRITE_PARCEL_ERR; } return 0; @@ -357,7 +340,7 @@ int32_t DataShareServiceStub::OnNotifyConnectDone(MessageParcel &data, MessagePa int DataShareServiceStub::OnRemoteRequest(uint32_t code, MessageParcel &data, MessageParcel &reply) { // set thread qos - DataShareServiceStub::QosManager qos; + QosManager qos; int tryTimes = TRY_TIMES; while (!isReady_.load() && tryTimes > 0) { diff --git a/services/distributeddataservice/service/data_share/data_share_service_stub.h b/services/distributeddataservice/service/data_share/data_share_service_stub.h index 27f1690ff..a242a4455 100644 --- a/services/distributeddataservice/service/data_share/data_share_service_stub.h +++ b/services/distributeddataservice/service/data_share/data_share_service_stub.h @@ -27,7 +27,6 @@ public: void SetServiceReady(); private: - class QosManager; static constexpr std::chrono::milliseconds TIME_THRESHOLD = std::chrono::milliseconds(500); static bool CheckInterfaceToken(MessageParcel& data); int32_t OnQuery(MessageParcel& data, MessageParcel& reply); diff --git a/services/distributeddataservice/service/data_share/idata_share_service.h b/services/distributeddataservice/service/data_share/idata_share_service.h index 9f08d74c5..99d2a5901 100644 --- a/services/distributeddataservice/service/data_share/idata_share_service.h +++ b/services/distributeddataservice/service/data_share/idata_share_service.h @@ -19,6 +19,7 @@ #include #include +#include "datashare_common.h" #include "datashare_predicates.h" #include "datashare_result_set.h" #include "datashare_values_bucket.h" @@ -88,8 +89,9 @@ public: enum { DATA_SHARE_ERROR = -1, DATA_SHARE_OK = 0 }; DECLARE_INTERFACE_DESCRIPTOR(u"OHOS.DataShare.IDataShareService"); - virtual std::shared_ptr Query(const std::string &uri, const std::string &extUri, - const DataSharePredicates &predicates, const std::vector &columns, int &errCode) = 0; + virtual std::pair> Query(const std::string &uri, + const std::string &extUri, const DataSharePredicates &predicates, const std::vector &columns, + DataShareOption &option) = 0; virtual int32_t AddTemplate(const std::string &uri, const int64_t subscriberId, const Template &tplt) = 0; virtual int32_t DelTemplate(const std::string &uri, const int64_t subscriberId) = 0; virtual std::vector Publish(const Data &data, const std::string &bundleNameOfProvider) = 0; diff --git a/services/distributeddataservice/service/test/data_share_service_impl_test.cpp b/services/distributeddataservice/service/test/data_share_service_impl_test.cpp index 9eecec988..5159d619f 100644 --- a/services/distributeddataservice/service/test/data_share_service_impl_test.cpp +++ b/services/distributeddataservice/service/test/data_share_service_impl_test.cpp @@ -132,8 +132,8 @@ HWTEST_F(DataShareServiceImplTest, DataShareServiceImpl001, TestSize.Level1) predicates.EqualTo("", ""); std::vector columns; - int errVal = 0; - auto resQuery = dataShareServiceImpl.Query(uri, "", predicates, columns, errVal); + DataShareOption option; + auto [errVal, resQuery] = dataShareServiceImpl.Query(uri, "", predicates, columns, option); int resultSet = 0; if (resQuery != nullptr) { resQuery->GetRowCount(resultSet); -- Gitee