diff --git a/frameworks/libs/distributeddb/common/include/log_print.h b/frameworks/libs/distributeddb/common/include/log_print.h index a4012d50bc0c56b7c290b77f5d8e27fdb5f0552d..39028c36a7a7775936debe8863be218c28f7e883 100644 --- a/frameworks/libs/distributeddb/common/include/log_print.h +++ b/frameworks/libs/distributeddb/common/include/log_print.h @@ -19,6 +19,8 @@ #include #include #include +#include +#include #include namespace DistributedDB { @@ -35,15 +37,15 @@ public: }; Logger() = default; virtual ~Logger() {}; - static Logger *GetInstance(); + static std::shared_ptr GetInstance(); static void DeleteInstance(); - static void RegisterLogger(Logger *logger); static void Log(Level level, const std::string &tag, const char *func, int line, const char *format, ...); private: virtual void Print(Level level, const std::string &tag, const std::string &msg) = 0; static void PreparePrivateLog(const char *format, std::string &outStrFormat); - static Logger *logHandler; + static std::shared_ptr logHandler; + static std::shared_mutex logMutex; static const std::string PRIVATE_TAG; }; diff --git a/frameworks/libs/distributeddb/common/src/log_print.cpp b/frameworks/libs/distributeddb/common/src/log_print.cpp index 0e05ff07cc86197dff85aea40f755053288ca119..1a9df0e7b926fe25188bdc95f6186d2ff27b9a5c 100644 --- a/frameworks/libs/distributeddb/common/src/log_print.cpp +++ b/frameworks/libs/distributeddb/common/src/log_print.cpp @@ -25,10 +25,9 @@ #include "hilog/log.h" namespace DistributedDB { -Logger *Logger::logHandler = nullptr; +std::shared_ptr Logger::logHandler = nullptr; +std::shared_mutex Logger::logMutex; const std::string Logger::PRIVATE_TAG = "s{private}"; -static std::mutex g_logInstanceLock; -static std::atomic g_logInstance = nullptr; class HiLogger : public Logger { public: @@ -65,42 +64,33 @@ public: } }; -Logger *Logger::GetInstance() +std::shared_ptr Logger::GetInstance() { - // For Double-Checked Locking, we need check logInstance twice - if (g_logInstance == nullptr) { - std::lock_guard lock(g_logInstanceLock); - if (g_logInstance == nullptr) { - // Here, we new logInstance to print log, if new failed, we can do nothing. - g_logInstance = new (std::nothrow) HiLogger; + std::shared_ptr inst = nullptr; + { + std::shared_lock readLock(logMutex); + if (logHandler != nullptr) { + inst = logHandler; + return inst; } } - return g_logInstance; + { + std::unique_lock writeLock(logMutex); + if (logHandler != nullptr) { + inst = logHandler; + return inst; + } + inst = std::make_shared(); + logHandler = inst; + } + LOGI("[TimeHelper] init"); + return logHandler; } void Logger::DeleteInstance() { - std::lock_guard lock(g_logInstanceLock); - if (g_logInstance == nullptr) { - return; - } - delete g_logInstance.load(); - g_logInstance = nullptr; - logHandler = nullptr; -} - -void Logger::RegisterLogger(Logger *logger) -{ - static std::mutex logHandlerLock; - if (logger == nullptr) { - return; - } - if (logHandler == nullptr) { - std::lock_guard lock(logHandlerLock); - if (logHandler == nullptr) { - logHandler = logger; - } - } + std::unique_lock writeLock(logMutex); + logHandler.reset(); } void Logger::Log(Level level, const std::string &tag, const char *func, int line, const char *format, ...) @@ -125,15 +115,7 @@ void Logger::Log(Level level, const std::string &tag, const char *func, int line msg = logBuff; } va_end(argList); - if (logHandler != nullptr) { - logHandler->Print(level, tag, msg); - return; - } - - Logger::RegisterLogger(Logger::GetInstance()); - if (logHandler != nullptr) { - logHandler->Print(level, tag, msg); - } + Logger::GetInstance()->Print(level, tag, msg); } void Logger::PreparePrivateLog(const char *format, std::string &outStrFormat) diff --git a/frameworks/libs/distributeddb/interfaces/src/relational/relational_store_sqlite_ext.cpp b/frameworks/libs/distributeddb/interfaces/src/relational/relational_store_sqlite_ext.cpp index 39503ec97f5b136132e8261b0300daf00f25e5b6..e1f0b50d0d2aed36340f1a75537199ce7ccc582d 100644 --- a/frameworks/libs/distributeddb/interfaces/src/relational/relational_store_sqlite_ext.cpp +++ b/frameworks/libs/distributeddb/interfaces/src/relational/relational_store_sqlite_ext.cpp @@ -319,24 +319,30 @@ public: class TimeHelperManager { public: - static TimeHelperManager *GetInstance() + static std::shared_ptr GetInstance() { - if (timeHelperInstance_ == nullptr) { - std::lock_guard lock(timeHelperMutex_); - if (timeHelperInstance_ == nullptr) { - timeHelperInstance_ = new TimeHelperManager(); + std::shared_ptr inst = nullptr; + { + std::shared_lock readLock(timeHelperMutex_); + if (timeHelperInstance_ != nullptr) { + inst = timeHelperInstance_; + return inst; } } + std::unique_lock writeLock(timeHelperMutex_); + if (timeHelperInstance_ != nullptr) { + inst = timeHelperInstance_; + return inst; + } + timeHelperInstance_ = std::make_shared(); + LOGI("[TimeHelper] init"); return timeHelperInstance_; } static void DestroyInstance() { - std::lock_guard lock(timeHelperMutex_); - if (timeHelperInstance_ != nullptr) { - delete timeHelperInstance_; - timeHelperInstance_ = nullptr; - } + std::unique_lock writeLock(timeHelperMutex_); + timeHelperInstance_.reset(); } void AddStore(const std::string &storeId) @@ -391,18 +397,17 @@ public: return it->second.GetTime(timeOffset, getDbMaxTimestamp, getDbLocalTimeOffset); } private: - TimeHelperManager() = default; std::mutex metaDataLock_; std::map metaData_; - static TimeHelperManager *timeHelperInstance_; - static std::mutex timeHelperMutex_; + static std::shared_ptr timeHelperInstance_; + static std::shared_mutex timeHelperMutex_; }; std::mutex TimeHelper::systemTimeLock_; Timestamp TimeHelper::lastSystemTimeUs_ = 0; Timestamp TimeHelper::currentIncCount_ = 0; -TimeHelperManager *TimeHelperManager::timeHelperInstance_ = nullptr; -std::mutex TimeHelperManager::timeHelperMutex_; +std::shared_ptr TimeHelperManager::timeHelperInstance_ = nullptr; +std::shared_mutex TimeHelperManager::timeHelperMutex_; int GetStatement(sqlite3 *db, const std::string &sql, sqlite3_stmt *&stmt); int ResetStatement(sqlite3_stmt *&stmt); @@ -2080,6 +2085,7 @@ DistributedDB::DBStatus CleanDeletedData(sqlite3 *db, const std::string &tableNa void Clean(bool isOpenSslClean) { + LOGI("[Clean] ssl:%d", isOpenSslClean); if (isOpenSslClean) { OPENSSL_cleanup(); } diff --git a/frameworks/libs/distributeddb/test/unittest/common/interfaces/distributeddb_cloud_interfaces_relational_ext_test.cpp b/frameworks/libs/distributeddb/test/unittest/common/interfaces/distributeddb_cloud_interfaces_relational_ext_test.cpp index 65872dc9e7e88aa7572ef4aa31b4db79fd794998..377d475d5c56b26b975fd9a3ed493fa041c0cd54 100644 --- a/frameworks/libs/distributeddb/test/unittest/common/interfaces/distributeddb_cloud_interfaces_relational_ext_test.cpp +++ b/frameworks/libs/distributeddb/test/unittest/common/interfaces/distributeddb_cloud_interfaces_relational_ext_test.cpp @@ -1896,15 +1896,43 @@ HWTEST_F(DistributedDBCloudInterfacesRelationalExtTest, FuncExceptionTest001, Te */ HWTEST_F(DistributedDBCloudInterfacesRelationalExtTest, CleanTest001, TestSize.Level0) { - Logger *loggerInstance = Logger::GetInstance(); + auto loggerInstance = Logger::GetInstance(); ASSERT_NE(loggerInstance, nullptr); Clean(true); Clean(false); loggerInstance = nullptr; - Logger *newLoggerInstance = Logger::GetInstance(); + auto newLoggerInstance = Logger::GetInstance(); ASSERT_NE(newLoggerInstance, nullptr); } +/** + * @tc.name: CleanTest002 + * @tc.desc: Test concurrent clean + * @tc.type: FUNC + * @tc.require: + * @tc.author: bty + */ +HWTEST_F(DistributedDBCloudInterfacesRelationalExtTest, CleanTest002, TestSize.Level2) +{ + size_t loopTimes = 5000; + std::thread t1 ([loopTimes]() { + for (size_t i = 0; i < loopTimes; i++) { + sqlite3 *db = RelationalTestUtils::CreateDataBase(g_dbDir + STORE_ID + DB_SUFFIX); + EXPECT_NE(db, nullptr); + EXPECT_EQ(sqlite3_close_v2(db), E_OK); + Clean(true); + } + }); + + for (size_t i = 0; i < loopTimes; i++) { + sqlite3 *db = RelationalTestUtils::CreateDataBase(g_dbDir + STORE_ID_1 + DB_SUFFIX); + EXPECT_NE(db, nullptr); + EXPECT_EQ(sqlite3_close_v2(db), E_OK); + } + t1.join(); + Clean(true); +} + /** * @tc.name: CreateTempTriggerTest001 * @tc.desc: Test create data change temp trigger. @@ -1930,6 +1958,7 @@ HWTEST_F(DistributedDBCloudInterfacesRelationalExtTest, CreateTempTriggerTest001 EXPECT_EQ(CreateDataChangeTempTrigger(db), OK); Clean(false); EXPECT_EQ(sqlite3_close_v2(db), E_OK); + Clean(true); } /**