From 3a8b871c6aaadab5107657c27c836c2368f5cdce Mon Sep 17 00:00:00 2001 From: zqq Date: Mon, 26 Sep 2022 17:17:22 +0800 Subject: [PATCH] fixbug when storage relase and machine still use storage Signed-off-by: zqq --- .../syncer/src/isync_state_machine.h | 3 ++ .../syncer/src/sync_state_machine.cpp | 15 ++++--- .../syncer/src/sync_state_machine.h | 3 ++ .../syncer/src/sync_task_context.cpp | 4 +- .../distributeddb_mock_sync_module_test.cpp | 41 +++++++++++++++++++ .../common/syncer/mock_sync_task_context.h | 15 +++++++ 6 files changed, 74 insertions(+), 7 deletions(-) diff --git a/frameworks/libs/distributeddb/syncer/src/isync_state_machine.h b/frameworks/libs/distributeddb/syncer/src/isync_state_machine.h index 137f0351c75..a2e61c42096 100644 --- a/frameworks/libs/distributeddb/syncer/src/isync_state_machine.h +++ b/frameworks/libs/distributeddb/syncer/src/isync_state_machine.h @@ -45,6 +45,9 @@ public: // Force stop the state machine virtual void Abort() = 0; + // Force stop the state machine now + virtual void AbortImmediately() = 0; + // Force stop current task with sessionId virtual void InnerErrorAbort(uint32_t sessionId) = 0; diff --git a/frameworks/libs/distributeddb/syncer/src/sync_state_machine.cpp b/frameworks/libs/distributeddb/syncer/src/sync_state_machine.cpp index daf71d2eb2b..e04248fa2fe 100644 --- a/frameworks/libs/distributeddb/syncer/src/sync_state_machine.cpp +++ b/frameworks/libs/distributeddb/syncer/src/sync_state_machine.cpp @@ -106,12 +106,7 @@ void SyncStateMachine::Abort() { RefObject::IncObjRef(syncContext_); int errCode = RuntimeContext::GetInstance()->ScheduleTask([this]() { - { - std::lock_guard lock(this->stateMachineLock_); - this->AbortInner(); - StopWatchDog(); - currentState_ = 0; - } + this->AbortImmediately(); RefObject::DecObjRef(this->syncContext_); }); if (errCode != E_OK) { @@ -120,6 +115,14 @@ void SyncStateMachine::Abort() } } +void SyncStateMachine::AbortImmediately() +{ + std::lock_guard lock(stateMachineLock_); + AbortInner(); + StopWatchDog(); + currentState_ = 0; +} + int SyncStateMachine::SwitchMachineState(uint8_t event) { const std::vector &tables = GetStateSwitchTables(); diff --git a/frameworks/libs/distributeddb/syncer/src/sync_state_machine.h b/frameworks/libs/distributeddb/syncer/src/sync_state_machine.h index 0a73b0cc778..ae890d0fd8e 100644 --- a/frameworks/libs/distributeddb/syncer/src/sync_state_machine.h +++ b/frameworks/libs/distributeddb/syncer/src/sync_state_machine.h @@ -58,6 +58,9 @@ public: // Force stop the state machine void Abort() override; + // Force stop the state machine now + void AbortImmediately() override; + // Force stop current task with sessionId void InnerErrorAbort(uint32_t sessionId) override; diff --git a/frameworks/libs/distributeddb/syncer/src/sync_task_context.cpp b/frameworks/libs/distributeddb/syncer/src/sync_task_context.cpp index dc86ece6d1e..01481034db3 100644 --- a/frameworks/libs/distributeddb/syncer/src/sync_task_context.cpp +++ b/frameworks/libs/distributeddb/syncer/src/sync_task_context.cpp @@ -591,7 +591,9 @@ void SyncTaskContext::CopyTargetData(const ISyncTarget *target, const TaskParam void SyncTaskContext::KillWait() { StopTimer(); - stateMachine_->Abort(); + UnlockObj(); + stateMachine_->AbortImmediately(); + LockObj(); LOGW("[SyncTaskContext] Try to kill a context, now wait."); bool noDeadLock = WaitLockedUntil( safeKill_, diff --git a/frameworks/libs/distributeddb/test/unittest/common/syncer/distributeddb_mock_sync_module_test.cpp b/frameworks/libs/distributeddb/test/unittest/common/syncer/distributeddb_mock_sync_module_test.cpp index 2b2812ce820..5b6f8c6b1ae 100644 --- a/frameworks/libs/distributeddb/test/unittest/common/syncer/distributeddb_mock_sync_module_test.cpp +++ b/frameworks/libs/distributeddb/test/unittest/common/syncer/distributeddb_mock_sync_module_test.cpp @@ -53,6 +53,14 @@ void Init(MockSingleVerStateMachine &stateMachine, MockSyncTaskContext &syncTask (void)stateMachine.Initialize(&syncTaskContext, &dbSyncInterface, metadata, &communicator); } +void Init(MockSingleVerStateMachine &stateMachine, MockSyncTaskContext *syncTaskContext, + MockCommunicator &communicator, VirtualSingleVerSyncDBInterface *dbSyncInterface) +{ + std::shared_ptr metadata = std::make_shared(); + (void)syncTaskContext->Initialize("device", dbSyncInterface, metadata, &communicator); + (void)stateMachine.Initialize(syncTaskContext, dbSyncInterface, metadata, &communicator); +} + #ifdef RUN_AS_ROOT void ChangeTime(int sec) { @@ -348,6 +356,39 @@ HWTEST_F(DistributedDBMockSyncModuleTest, StateMachineCheck011, TestSize.Level1) EXPECT_EQ(syncTaskContext.IsCommNormal(), false); } +/** + * @tc.name: StateMachineCheck013 + * @tc.desc: test kill syncTaskContext. + * @tc.type: FUNC + * @tc.require: AR000CCPOM + * @tc.author: zhangqiquan + */ +HWTEST_F(DistributedDBMockSyncModuleTest, StateMachineCheck013, TestSize.Level1) +{ + MockSingleVerStateMachine stateMachine; + auto *syncTaskContext = new(std::nothrow) MockSyncTaskContext(); + auto *dbSyncInterface = new(std::nothrow) VirtualSingleVerSyncDBInterface(); + ASSERT_NE(syncTaskContext, nullptr); + EXPECT_NE(dbSyncInterface, nullptr); + if (dbSyncInterface == nullptr) { + RefObject::KillAndDecObjRef(syncTaskContext); + return; + } + MockCommunicator communicator; + Init(stateMachine, syncTaskContext, communicator, dbSyncInterface); + EXPECT_CALL(*syncTaskContext, Clear()).WillOnce(Return()); + syncTaskContext->RegForkGetDeviceIdFunc([]() { + std::this_thread::sleep_for(std::chrono::seconds(2)); // sleep 2s + }); + int token = 1; + int *tokenPtr = &token; + syncTaskContext->SetContinueToken(tokenPtr); + RefObject::KillAndDecObjRef(syncTaskContext); + delete dbSyncInterface; + std::this_thread::sleep_for(std::chrono::seconds(5)); // sleep 5s and wait for task exist + tokenPtr = nullptr; +} + /** * @tc.name: DataSyncCheck001 * @tc.desc: Test dataSync recv error ack. diff --git a/frameworks/libs/distributeddb/test/unittest/common/syncer/mock_sync_task_context.h b/frameworks/libs/distributeddb/test/unittest/common/syncer/mock_sync_task_context.h index 0f736f54435..81ebf2d2c82 100644 --- a/frameworks/libs/distributeddb/test/unittest/common/syncer/mock_sync_task_context.h +++ b/frameworks/libs/distributeddb/test/unittest/common/syncer/mock_sync_task_context.h @@ -64,6 +64,21 @@ public: { lastFullSyncTaskStatus_ = static_cast(lastFullSyncTaskStatus); } + + void RegForkGetDeviceIdFunc(const std::function &forkGetDeviceIdFunc) + { + forkGetDeviceIdFunc_ = forkGetDeviceIdFunc; + } + + std::string GetDeviceId() const override + { + if (forkGetDeviceIdFunc_) { + forkGetDeviceIdFunc_(); + } + return SingleVerKvSyncTaskContext::GetDeviceId(); + } +private: + std::function forkGetDeviceIdFunc_; }; } // namespace DistributedDB #endif // #define MOCK_SINGLE_VER_STATE_MACHINE_H \ No newline at end of file -- Gitee