diff --git a/base/src/event_reactor.cpp b/base/src/event_reactor.cpp index e54d183e2d7bbd737e8af63751d0610114010d8c..ea5383776e8e76bf9288a72438e82d373bc49f4b 100644 --- a/base/src/event_reactor.cpp +++ b/base/src/event_reactor.cpp @@ -95,9 +95,6 @@ uint32_t EventReactor::ScheduleTimer(const TimerCallback& cb, uint32_t interval, { std::lock_guard lock(mutex_); std::shared_ptr handler = std::make_shared(this, interval, once); - if (handler == nullptr) { - return TIMER_ERR_INVALID_VALUE; - } handler->SetTimerCallback(cb); uint32_t ret = handler->Initialize(); if (ret != TIMER_ERR_OK) { diff --git a/base/src/parcel.cpp b/base/src/parcel.cpp index ae218eeff6cf76527033095bc70632c9582b5b2f..441a4df2f304048f8265591a94393eefcd345c67 100644 --- a/base/src/parcel.cpp +++ b/base/src/parcel.cpp @@ -964,8 +964,8 @@ const std::string Parcel::ReadString() return std::string(); } - size_t readCapacity = dataLength + 1; - if ((readCapacity > (size_t)dataLength) && (readCapacity <= GetReadableBytes())) { + size_t readCapacity = static_cast(dataLength) + 1; + if (readCapacity <= GetReadableBytes()) { const uint8_t *dest = ReadBuffer(readCapacity); if (dest != nullptr) { const auto *str = reinterpret_cast(dest); @@ -990,8 +990,8 @@ bool Parcel::ReadString(std::string &value) return false; } - size_t readCapacity = dataLength + 1; - if ((readCapacity > (size_t)dataLength) && (readCapacity <= GetReadableBytes())) { + size_t readCapacity = static_cast(dataLength) + 1; + if (readCapacity <= GetReadableBytes()) { const uint8_t *dest = ReadBuffer(readCapacity); if (dest != nullptr) { const auto *str = reinterpret_cast(dest); @@ -1017,8 +1017,8 @@ const std::u16string Parcel::ReadString16() return std::u16string(); } - size_t readCapacity = (dataLength + 1) * sizeof(char16_t); - if ((readCapacity > (size_t)dataLength) && (readCapacity <= GetReadableBytes())) { + size_t readCapacity = (static_cast(dataLength) + 1) * sizeof(char16_t); + if ((readCapacity > (static_cast(dataLength))) && (readCapacity <= GetReadableBytes())) { const uint8_t *str = ReadBuffer(readCapacity); if (str != nullptr) { const auto *u16Str = reinterpret_cast(str); @@ -1043,7 +1043,7 @@ bool Parcel::ReadString16(std::u16string &value) return false; } - size_t readCapacity = (dataLength + 1) * sizeof(char16_t); + size_t readCapacity = (static_cast(dataLength) + 1) * sizeof(char16_t); if (readCapacity <= GetReadableBytes()) { const uint8_t *str = ReadBuffer(readCapacity); if (str != nullptr) { @@ -1075,8 +1075,8 @@ const std::u16string Parcel::ReadString16WithLength(int32_t &readLength) return std::u16string(); } - size_t readCapacity = (dataLength + 1) * sizeof(char16_t); - if ((readCapacity > (size_t)dataLength) && (readCapacity <= GetReadableBytes())) { + size_t readCapacity = (static_cast(dataLength) + 1) * sizeof(char16_t); + if ((readCapacity > (static_cast(dataLength))) && (readCapacity <= GetReadableBytes())) { const uint8_t *str = ReadBuffer(readCapacity); if (str != nullptr) { const auto *u16Str = reinterpret_cast(str); @@ -1106,8 +1106,8 @@ const std::string Parcel::ReadString8WithLength(int32_t &readLength) return std::string(); } - size_t readCapacity = (dataLength + 1) * sizeof(char); - if ((readCapacity > (size_t)dataLength) && (readCapacity <= GetReadableBytes())) { + size_t readCapacity = (static_cast(dataLength) + 1) * sizeof(char); + if (readCapacity <= GetReadableBytes()) { const uint8_t *str = ReadBuffer(readCapacity); if (str != nullptr) { const auto *u8Str = reinterpret_cast(str); diff --git a/base/test/unittest/common/BUILD.gn b/base/test/unittest/common/BUILD.gn index 0d7f4b4a183dae3873203b5f613f3d4b314234f9..f9f6cbad10b509eacbc492b92e512510cfd6a8e5 100644 --- a/base/test/unittest/common/BUILD.gn +++ b/base/test/unittest/common/BUILD.gn @@ -292,6 +292,19 @@ ohos_unittest("UtilsTimerTest") { ] } +############################################################################### +ohos_unittest("UtilsRWLockTest") { + module_out_path = module_output_path + sources = [ "utils_rwlock_test.cpp" ] + + configs = [ ":module_private_config" ] + + deps = [ + "//commonlibrary/c_utils/base:utils", + "//third_party/googletest:gtest_main", + ] +} + ############################################################################### group("unittest") { @@ -304,6 +317,7 @@ group("unittest") { ":UtilsDateTimeTest", ":UtilsDirectoryTest", ":UtilsParcelTest", + ":UtilsRWLockTest", ":UtilsRefbaseTest", ":UtilsSafeBlockQueueTest", ":UtilsSafeBlockQueueTrackingTest", diff --git a/base/test/unittest/common/utils_rwlock_test.cpp b/base/test/unittest/common/utils_rwlock_test.cpp new file mode 100644 index 0000000000000000000000000000000000000000..dbd6d48c72750d309c806d151f29addf41839671 --- /dev/null +++ b/base/test/unittest/common/utils_rwlock_test.cpp @@ -0,0 +1,128 @@ +/* + * Copyright (c) 2021 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. + */ +#include +#include +#include + +#include "rwlock.h" + +using namespace testing::ext; +using namespace std; + +namespace OHOS { +namespace { + +class UtilsRWLockTest : public testing::Test {}; + +// This class is designed for test RWLock. "buf" is protected by "rwLock". +class TestRWLock { +public: + TestRWLock():rwLock(), buf() {} + + explicit TestRWLock(bool writeFirst):rwLock(writeFirst), buf() {} + + void WriteStr(const string& str) + { + rwLock.LockWrite(); + for (auto it = str.begin(); it != str.end(); it++) { + buf.push_back(*it); + this_thread::sleep_for(std::chrono::milliseconds(1)); + } + rwLock.UnLockWrite(); + return; + } + + void ReadStr(string& str) + { + rwLock.LockRead(); + for (auto it = buf.begin(); it != buf.end(); it++) { + str.push_back(*it); + this_thread::sleep_for(std::chrono::milliseconds(1)); + } + rwLock.UnLockRead(); + return; + } +private: + Utils::RWLock rwLock; + string buf; +}; + +const string WRITE_IN_1("write1"); +const string WRITE_IN_2("write2"); + +/* + * @tc.name: testRWLock001 + * @tc.desc: RWLock here is under write-first mode. If there are some writing operation waiting, + * reading will never happen. Reading operations will happen at the same time, when all writing operations + * have finished. + */ +HWTEST_F(UtilsRWLockTest, testRWLock001, TestSize.Level1) +{ + TestRWLock test; + + thread first(bind(&TestRWLock::WriteStr, ref(test), ref(WRITE_IN_1))); + this_thread::sleep_for(chrono::milliseconds(1)); + + string readOut1(""); + thread second(bind(&TestRWLock::ReadStr, ref(test), ref(readOut1))); + this_thread::sleep_for(chrono::milliseconds(1)); + + thread third(bind(&TestRWLock::WriteStr, ref(test), ref(WRITE_IN_2))); + this_thread::sleep_for(chrono::milliseconds(1)); + + string readOut2(""); + thread fourth(bind(&TestRWLock::ReadStr, ref(test), ref(readOut2))); + + first.join(); + second.join(); + third.join(); + fourth.join(); + + EXPECT_EQ(readOut1, WRITE_IN_1 + WRITE_IN_2); + EXPECT_EQ(readOut2, WRITE_IN_1 + WRITE_IN_2); +} + +/* + * @tc.name: testRWLock002 + * @tc.desc: RWLock here is not under write-first mode. So if there are writing and reading operations in queue + * with a writing mission running, they will compete when the writing mission completing. But what we can ensure + * is that reading operations in queue will happen at the same time. + */ +HWTEST_F(UtilsRWLockTest, testRWLock002, TestSize.Level1) +{ + TestRWLock test(false); + + thread first(bind(&TestRWLock::WriteStr, ref(test), ref(WRITE_IN_1))); + this_thread::sleep_for(chrono::milliseconds(1)); + + string readOut1(""); + thread second(bind(&TestRWLock::ReadStr, ref(test), ref(readOut1))); + this_thread::sleep_for(chrono::milliseconds(1)); + + thread third(bind(&TestRWLock::WriteStr, ref(test), ref(WRITE_IN_2))); + this_thread::sleep_for(chrono::milliseconds(1)); + + string readOut2(""); + thread fourth(bind(&TestRWLock::ReadStr, ref(test), ref(readOut2))); + + first.join(); + second.join(); + third.join(); + fourth.join(); + + EXPECT_EQ(readOut1, readOut2); +} +} // namespace +} // namespace OHOS \ No newline at end of file