已合并
稳定性问题处理 #174
稳定性问题处理 #174
已合并
guoxu1111创建于 8月5日
2 个文件变更+94-36
@@ -18,6 +18,7 @@
18 18 
19#include <map>19#include <map>
20#include <mutex>20#include <mutex>
21+#include <shared_mutex>
21#include <future>22#include <future>
22#include <string>23#include <string>
23 24 
@@ -184,7 +185,7 @@ private:
184 185 
185 // 插件 .so 句柄和函数指针186 // 插件 .so 句柄和函数指针
186 void* pluginSo_ = nullptr;187 void* pluginSo_ = nullptr;
187- uint32_t pluginUnloadTimerId_ {0}; // 插件自动卸载定时器ID188+ std::atomic<uint32_t> pluginUnloadTimerId_ {0}; // 插件自动卸载定时器ID
188 DatabaseSaveConfigFunc databaseSave_ = nullptr;189 DatabaseSaveConfigFunc databaseSave_ = nullptr;
189 DatabaseGetConfigFunc databaseGet_ = nullptr;190 DatabaseGetConfigFunc databaseGet_ = nullptr;
190 DatabaseIsAvailableFunc databaseAvailable_ = nullptr;191 DatabaseIsAvailableFunc databaseAvailable_ = nullptr;
@@ -197,7 +198,7 @@ private:
197 198 
198 int32_t inputMonitorId_ {-1};199 int32_t inputMonitorId_ {-1};
199 mutable std::mutex mutex_;200 mutable std::mutex mutex_;
200- mutable std::mutex pluginMutex_;201+ mutable std::shared_mutex pluginMutex_;
201 static sptr<ISelectionListener> listener_;202 static sptr<ISelectionListener> listener_;
202 sptr<SelectionExtensionAbilityConnection> connectInner_ {nullptr};203 sptr<SelectionExtensionAbilityConnection> connectInner_ {nullptr};
203 std::mutex connectMutex_;204 std::mutex connectMutex_;
@@ -348,9 +348,18 @@ void SelectionService::PersistSelectionConfig()
348 auto selectionConfig = MemSelectionConfig::GetInstance().GetSelectionConfig();348 auto selectionConfig = MemSelectionConfig::GetInstance().GetSelectionConfig();
349 SELECTION_HILOGI("========== PersistSelectionConfig: Start ==========");349 SELECTION_HILOGI("========== PersistSelectionConfig: Start ==========");
350 350 
351- if (!LoadPluginSo()) {351+ std::shared_lock<std::shared_mutex> readLock(pluginMutex_);
352- SELECTION_HILOGW("Using in-memory config as fallback, service continues to run");352+ if (!pluginSo_) {
353- return;353+ readLock.unlock();
354+ if (!LoadPluginSo()) {
355+ SELECTION_HILOGW("Using in-memory config as fallback, service continues to run");
356+ return;
357+ }
358+ readLock.lock();
359+ if (!pluginSo_) {
360+ SELECTION_HILOGW("Plugin unloaded during operation, using in-memory config as fallback");
361+ return;
362+ }
354 }363 }
355 364 
356 if (databaseSave_) {365 if (databaseSave_) {
@@ -413,12 +422,19 @@ int32_t SelectionService::DoConnectNewExtAbility(const std::string& bundleName,
413 return SELECTION_CONFIG_FAILURE;422 return SELECTION_CONFIG_FAILURE;
414 }423 }
415 424 
416- if (!LoadPluginSo() || !abilityConnect_) {425+ if (!LoadPluginSo()) {
417 SELECTION_HILOGE("Ability manager plugin not available");426 SELECTION_HILOGE("Ability manager plugin not available");
418 connectInner_ = nullptr;427 connectInner_ = nullptr;
419 return SELECTION_CONFIG_FAILURE;428 return SELECTION_CONFIG_FAILURE;
420 }429 }
421 430 
431+ std::shared_lock<std::shared_mutex> readLock(pluginMutex_);
432+ if (!pluginSo_ || !abilityConnect_) {
433+ SELECTION_HILOGE("Ability manager plugin not available after load");
434+ connectInner_ = nullptr;
435+ return SELECTION_CONFIG_FAILURE;
436+ }
437+ 
422 auto ret = abilityConnect_(&want, &connectInner_, userId);438 auto ret = abilityConnect_(&want, &connectInner_, userId);
423 if (ret != 0) {439 if (ret != 0) {
424 SELECTION_HILOGE("[selectevent] StartExtensionAbility failed. error code is %{public}d.", ret);440 SELECTION_HILOGE("[selectevent] StartExtensionAbility failed. error code is %{public}d.", ret);
@@ -446,7 +462,9 @@ void SelectionService::DoDisconnectCurrentExtAbility()
446 connectInner_->InitDisconnectPromise();462 connectInner_->InitDisconnectPromise();
447 463 
448 // 如果插件已卸载,直接清理连接对象,不重新加载插件464 // 如果插件已卸载,直接清理连接对象,不重新加载插件
465+ std::shared_lock<std::shared_mutex> readLock(pluginMutex_);
449 if (!abilityDisconnect_) {466 if (!abilityDisconnect_) {
467+ readLock.unlock();
450 SELECTION_HILOGW("Ability manager plugin not available, clean up connection only");468 SELECTION_HILOGW("Ability manager plugin not available, clean up connection only");
451 connectInner_->DestroyDisconnectPromise();469 connectInner_->DestroyDisconnectPromise();
452 connectInner_ = nullptr;470 connectInner_ = nullptr;
@@ -454,6 +472,7 @@ void SelectionService::DoDisconnectCurrentExtAbility()
454 }472 }
455 473 
456 int32_t ret = abilityDisconnect_(&connectInner_);474 int32_t ret = abilityDisconnect_(&connectInner_);
475+ readLock.unlock();
457 if (ret != ERR_OK) {476 if (ret != ERR_OK) {
458 connectInner_->DestroyDisconnectPromise();477 connectInner_->DestroyDisconnectPromise();
459 SELECTION_HILOGE("DisconnectServiceAbility failed, ret: %{public}d", ret);478 SELECTION_HILOGE("DisconnectServiceAbility failed, ret: %{public}d", ret);
@@ -660,9 +679,18 @@ void SelectionService::SynchronizeSelectionConfig()
660 679 
661std::optional<SelectionConfig> SelectionService::LoadDatabaseSelectionConfig()680std::optional<SelectionConfig> SelectionService::LoadDatabaseSelectionConfig()
662{681{
663- if (!LoadPluginSo()) {682+ std::shared_lock<std::shared_mutex> readLock(pluginMutex_);
664- SELECTION_HILOGW("Using system default config as fallback");683+ if (!pluginSo_) {
665- return std::nullopt;684+ readLock.unlock();
685+ if (!LoadPluginSo()) {
686+ SELECTION_HILOGW("Using system default config as fallback");
687+ return std::nullopt;
688+ }
689+ readLock.lock();
690+ if (!pluginSo_) {
691+ SELECTION_HILOGW("Plugin unloaded during operation, using fallback");
692+ return std::nullopt;
693+ }
666 }694 }
667 695 
668 if (!databaseGet_) {696 if (!databaseGet_) {
@@ -691,13 +719,15 @@ void SelectionService::SyncConfigToSystem(const SelectionConfig& config)
691 719 
692void SelectionService::SyncConfigToDatabase(int32_t userId, const SelectionConfig& config)720void SelectionService::SyncConfigToDatabase(int32_t userId, const SelectionConfig& config)
693{721{
694- SELECTION_HILOGI("SyncConfigToDatabase: %{public}s", config.ToString().c_str());722+ if (!LoadPluginSo()) {
695- 723+ SELECTION_HILOGW("Config saved to system params as fallback");
696- if (!LoadPluginSo() || !databaseSave_) {724+ return;
725+ }
726+ std::shared_lock<std::shared_mutex> readLock(pluginMutex_);
727+ if (!pluginSo_ || !databaseSave_) {
697 SELECTION_HILOGW("Config saved to system params as fallback");728 SELECTION_HILOGW("Config saved to system params as fallback");
698 return;729 return;
699 }730 }
700- 
701 auto ret = databaseSave_(userId, &config);731 auto ret = databaseSave_(userId, &config);
702 if (ret != SELECTION_CONFIG_OK) {732 if (ret != SELECTION_CONFIG_OK) {
703 SELECTION_HILOGE("Save database failed. ret = %{public}d", ret);733 SELECTION_HILOGE("Save database failed. ret = %{public}d", ret);
@@ -978,8 +1008,9 @@ void SelectionService::PerformParamBootCompleted(const char* key, const char* va
978 1008 
979bool SelectionService::LoadPluginSo()1009bool SelectionService::LoadPluginSo()
980{1010{
981- std::lock_guard<std::mutex> lock(pluginMutex_);1011+ std::unique_lock<std::shared_mutex> lock(pluginMutex_);
982 if (pluginSo_) {1012 if (pluginSo_) {
1013+ ResetPluginUnloadTimer(); //新增已加载分支也重置
983 return true; // 已加载1014 return true; // 已加载
984 }1015 }
985 1016 
@@ -1019,10 +1050,11 @@ bool SelectionService::LoadPluginSo()
1019 1050 
1020void SelectionService::UnloadPluginSo()1051void SelectionService::UnloadPluginSo()
1021{1052{
1053+ std::unique_lock<std::shared_mutex> lock(pluginMutex_);
1022 // 取消卸载定时器1054 // 取消卸载定时器
1023- if (pluginUnloadTimerId_ != 0) {1055+ if (pluginUnloadTimerId_.load() != 0) {
1024- SelectionFwkTimer::GetInstance()->UnRegister(pluginUnloadTimerId_);1056+ SelectionFwkTimer::GetInstance()->UnRegister(pluginUnloadTimerId_.load());
1025- pluginUnloadTimerId_ = 0;1057+ pluginUnloadTimerId_.store(0);
1026 }1058 }
1027 1059 
1028 if (pluginSo_) {1060 if (pluginSo_) {
@@ -1053,15 +1085,15 @@ void SelectionService::UnloadPluginSo()
1053void SelectionService::ResetPluginUnloadTimer()1085void SelectionService::ResetPluginUnloadTimer()
1054{1086{
1055 // 取消旧的定时器1087 // 取消旧的定时器
1056- if (pluginUnloadTimerId_ != 0) {1088+ if (pluginUnloadTimerId_.load() != 0) {
1057- SelectionFwkTimer::GetInstance()->UnRegister(pluginUnloadTimerId_);1089+ SelectionFwkTimer::GetInstance()->UnRegister(pluginUnloadTimerId_.load());
1058- pluginUnloadTimerId_ = 0;1090+ pluginUnloadTimerId_.store(0);
1059 }1091 }
1060 1092 
1061 // 启动新的定时器:5分钟后自动卸载插件1093 // 启动新的定时器:5分钟后自动卸载插件
1062- pluginUnloadTimerId_ = SelectionFwkTimer::GetInstance()->Register([this]() {1094+ pluginUnloadTimerId_.store(SelectionFwkTimer::GetInstance()->Register([this]() {
1063 OnPluginUnloadTimer();1095 OnPluginUnloadTimer();
1064- }, PLUGIN_UNLOAD_TIMEOUT_MS);1096+ }, PLUGIN_UNLOAD_TIMEOUT_MS));
1065 1097 
1066 SELECTION_HILOGI("Plugin unload timer reset: %{public}d ms", PLUGIN_UNLOAD_TIMEOUT_MS);1098 SELECTION_HILOGI("Plugin unload timer reset: %{public}d ms", PLUGIN_UNLOAD_TIMEOUT_MS);
1067}1099}
@@ -1080,43 +1112,57 @@ void SelectionService::OnPluginUnloadTimer()
1080 DisconnectCurrentExtAbility();1112 DisconnectCurrentExtAbility();
1081 }1113 }
1082 UnloadPluginSo();1114 UnloadPluginSo();
1083- pluginUnloadTimerId_ = 0;1115+ // pluginUnloadTimerId_ is already set to 0 inside UnloadPluginSo()
1084}1116}
1085 1117 
1086int SelectionService::GetDatabaseConfig(int32_t uid, SelectionConfig& config)1118int SelectionService::GetDatabaseConfig(int32_t uid, SelectionConfig& config)
1087{1119{
1088- if (!LoadPluginSo() || !databaseGet_) {1120+ if (!LoadPluginSo()) {
1089 SELECTION_HILOGE("Database plugin not available");1121 SELECTION_HILOGE("Database plugin not available");
1090 return SELECTION_CONFIG_RDB_NO_INIT;1122 return SELECTION_CONFIG_RDB_NO_INIT;
1091 }1123 }
1124+
1125+ std::shared_lock<std::shared_mutex> readLock(pluginMutex_);
1126+ if (!pluginSo_ || !databaseGet_) {
1127+ SELECTION_HILOGE("Database plugin not available after load");
1128+ return SELECTION_CONFIG_RDB_NO_INIT;
1129+ }
1092 1130 
1093 SelectionConfig* configPtr = &config;1131 SelectionConfig* configPtr = &config;
1094 int ret = databaseGet_(uid, configPtr);1132 int ret = databaseGet_(uid, configPtr);
1095 if (ret != 0) {1133 if (ret != 0) {
1096 SELECTION_HILOGE("DatabaseGetConfig failed, ret=%{public}d", ret);1134 SELECTION_HILOGE("DatabaseGetConfig failed, ret=%{public}d", ret);
1097 }1135 }
1098- ResetPluginUnloadTimer(); // 重置5分钟卸载定时器
1099 return ret;1136 return ret;
1100}1137}
1101 1138 
1102int SelectionService::SaveDatabaseConfig(int32_t uid, const SelectionConfig& config)1139int SelectionService::SaveDatabaseConfig(int32_t uid, const SelectionConfig& config)
1103{1140{
1104- if (!LoadPluginSo() || !databaseSave_) {1141+ if (!LoadPluginSo()) {
1105 SELECTION_HILOGE("Database plugin not available");1142 SELECTION_HILOGE("Database plugin not available");
1106 return SELECTION_CONFIG_RDB_NO_INIT;1143 return SELECTION_CONFIG_RDB_NO_INIT;
1107 }1144 }
1145+
1146+ std::shared_lock<std::shared_mutex> readLock(pluginMutex_);
1147+ if (!pluginSo_ || !databaseSave_) {
1148+ SELECTION_HILOGE("Database plugin not available after load");
1149+ return SELECTION_CONFIG_RDB_NO_INIT;
1150+ }
1108 1151 
1109 int ret = databaseSave_(uid, &config);1152 int ret = databaseSave_(uid, &config);
1110 if (ret != 0) {1153 if (ret != 0) {
1111 SELECTION_HILOGE("DatabaseSaveConfig failed, ret=%{public}d", ret);1154 SELECTION_HILOGE("DatabaseSaveConfig failed, ret=%{public}d", ret);
1112 }1155 }
1113- ResetPluginUnloadTimer(); // 重置5分钟卸载定时器
1114 return ret;1156 return ret;
1115}1157}
1116 1158 
1117bool SelectionService::IsDatabaseAvailable()1159bool SelectionService::IsDatabaseAvailable()
1118{1160{
1119- if (!LoadPluginSo() || !databaseAvailable_) {1161+ if (!LoadPluginSo()) {
1162+ return false;
1163+ }
1164+ std::shared_lock<std::shared_mutex> readLock(pluginMutex_);
1165+ if (!pluginSo_ || !databaseAvailable_) {
1120 return false;1166 return false;
1121 }1167 }
1122 return databaseAvailable_() != 0;1168 return databaseAvailable_() != 0;
@@ -1128,34 +1174,45 @@ int SelectionService::GetPasteboardContent(std::string& content, uint32_t window
1128 constexpr uint32_t BYTES_PER_CHINESE_CHAR = 3;1174 constexpr uint32_t BYTES_PER_CHINESE_CHAR = 3;
1129 constexpr uint32_t bufferSize = MAX_PASTERBOARD_TEXT_LENGTH * BYTES_PER_CHINESE_CHAR + 1;1175 constexpr uint32_t bufferSize = MAX_PASTERBOARD_TEXT_LENGTH * BYTES_PER_CHINESE_CHAR + 1;
1130 1176 
1131- if (!LoadPluginSo() || !pasteboardGetContent_) {1177+ if (!LoadPluginSo()) {
1132 SELECTION_HILOGE("Pasteboard plugin not available");1178 SELECTION_HILOGE("Pasteboard plugin not available");
1133 return SelectionServiceError::INVALID_DATA;1179 return SelectionServiceError::INVALID_DATA;
1134 }1180 }
1181+
1182+ std::shared_lock<std::shared_mutex> readLock(pluginMutex_);
1183+ if (!pluginSo_ || !pasteboardGetContent_) {
1184+ SELECTION_HILOGE("Pasteboard plugin not available after load");
1185+ return SelectionServiceError::INVALID_DATA;
1186+ }
1135 1187 
1136 char buffer[bufferSize] = {0};1188 char buffer[bufferSize] = {0};
1137 int ret = pasteboardGetContent_(buffer, bufferSize, windowId, bundleName.c_str());1189 int ret = pasteboardGetContent_(buffer, bufferSize, windowId, bundleName.c_str());
1138 if (ret == 0) {1190 if (ret == 0) {
1139 content = buffer;1191 content = buffer;
1140 }1192 }
1141- ResetPluginUnloadTimer(); // 重置5分钟卸载定时器
1142 return ret;1193 return ret;
1143}1194}
1144 1195 
1145bool SelectionService::CanGetPasteboardContent()1196bool SelectionService::CanGetPasteboardContent()
1146{1197{
1147- if (!LoadPluginSo() || !pasteboardCanGetContent_) {1198+ if (!LoadPluginSo()) {
1199+ return false;
1200+ }
1201+ std::shared_lock<std::shared_mutex> readLock(pluginMutex_);
1202+ if (!pluginSo_ || !pasteboardCanGetContent_) {
1148 return false;1203 return false;
1149 }1204 }
1150 bool result = pasteboardCanGetContent_() != 0;1205 bool result = pasteboardCanGetContent_() != 0;
1151- ResetPluginUnloadTimer(); // 重置5分钟卸载定时器
1152 return result;1206 return result;
1153}1207}
1154 1208 
1155void SelectionService::SetPasteboardFlag(bool flag)1209void SelectionService::SetPasteboardFlag(bool flag)
1156{1210{
1157- if (LoadPluginSo() && pasteboardSetFlag_) {1211+ if (!LoadPluginSo()) {
1158- pasteboardSetFlag_(flag ? 1 : 0);1212+ return;
1159- ResetPluginUnloadTimer(); // 重置5分钟卸载定时器
1160 }1213 }
1161-}1214+ std::shared_lock<std::shared_mutex> readLock(pluginMutex_);
1215+ if (pluginSo_ && pasteboardSetFlag_) {
1216+ pasteboardSetFlag_(flag ? 1 : 0);
1217+ }
1218+}