From 851f13d868f15a622724ceaeef880e63c876d0f4 Mon Sep 17 00:00:00 2001 From: wuzhihuitmac Date: Mon, 28 Oct 2024 15:16:10 +0800 Subject: [PATCH] Modify the issue about report data send failed Signed-off-by: wuzhihuitmac Change-Id: I1f9283f97676a5fce20af04b959abcc472485af6 --- .../include/sensor_file_descriptor_listener.h | 1 + .../src/sensor_file_descriptor_listener.cpp | 35 ++++---- .../sensor_basic_data_channel_test.cpp | 19 +++-- .../include/sensor_basic_data_channel.h | 3 +- .../common/src/sensor_basic_data_channel.cpp | 79 +++++++++++++++---- 5 files changed, 99 insertions(+), 38 deletions(-) diff --git a/frameworks/native/include/sensor_file_descriptor_listener.h b/frameworks/native/include/sensor_file_descriptor_listener.h index bef8b685..6c2439ae 100644 --- a/frameworks/native/include/sensor_file_descriptor_listener.h +++ b/frameworks/native/include/sensor_file_descriptor_listener.h @@ -31,6 +31,7 @@ public: void OnShutdown(int32_t fileDescriptor) override; void OnException(int32_t fileDescriptor) override; void SetChannel(SensorDataChannel *channel); + void ExcuteCallback(int32_t length); private: SensorDataChannel *channel_ = nullptr; diff --git a/frameworks/native/src/sensor_file_descriptor_listener.cpp b/frameworks/native/src/sensor_file_descriptor_listener.cpp index b55f13af..a3ea247a 100644 --- a/frameworks/native/src/sensor_file_descriptor_listener.cpp +++ b/frameworks/native/src/sensor_file_descriptor_listener.cpp @@ -57,23 +57,26 @@ void SensorFileDescriptorListener::OnReadable(int32_t fileDescriptor) SEN_HILOGE("Receive data buff_ is null"); return; } - int32_t len = channel_->ReceiveData(receiveDataBuff_, sizeof(SensorData) * RECEIVE_DATA_SIZE); + channel_->ReceiveData([this] (int32_t length) { + this->ExcuteCallback(length); + }, receiveDataBuff_, sizeof(SensorData) * RECEIVE_DATA_SIZE); +} + +void SensorFileDescriptorListener::ExcuteCallback(int32_t length) +{ int32_t eventSize = static_cast(sizeof(SensorData)); - while (len > 0) { - int32_t num = len / eventSize; - for (int i = 0; i < num; i++) { - SensorEvent event = { - .sensorTypeId = receiveDataBuff_[i].sensorTypeId, - .version = receiveDataBuff_[i].version, - .timestamp = receiveDataBuff_[i].timestamp, - .option = receiveDataBuff_[i].option, - .mode = receiveDataBuff_[i].mode, - .data = receiveDataBuff_[i].data, - .dataLen = receiveDataBuff_[i].dataLen - }; - channel_->dataCB_(&event, 1, channel_->privateData_); - } - len = channel_->ReceiveData(receiveDataBuff_, sizeof(SensorData) * RECEIVE_DATA_SIZE); + int32_t num = length / eventSize; + for (int i = 0; i < num; i++) { + SensorEvent event = { + .sensorTypeId = receiveDataBuff_[i].sensorTypeId, + .version = receiveDataBuff_[i].version, + .timestamp = receiveDataBuff_[i].timestamp, + .option = receiveDataBuff_[i].option, + .mode = receiveDataBuff_[i].mode, + .data = receiveDataBuff_[i].data, + .dataLen = receiveDataBuff_[i].dataLen + }; + channel_->dataCB_(&event, 1, channel_->privateData_); } } diff --git a/test/unittest/coverage/sensor_basic_data_channel_test.cpp b/test/unittest/coverage/sensor_basic_data_channel_test.cpp index 04ad39f3..6c2bfa49 100644 --- a/test/unittest/coverage/sensor_basic_data_channel_test.cpp +++ b/test/unittest/coverage/sensor_basic_data_channel_test.cpp @@ -41,6 +41,7 @@ public: static void TearDownTestCase(); void SetUp(); void TearDown(); + void ReceiveData(int32_t length); }; void SensorBasicDataChannelTest::SetUpTestCase() {} @@ -51,6 +52,8 @@ void SensorBasicDataChannelTest::SetUp() {} void SensorBasicDataChannelTest::TearDown() {} +void SensorBasicDataChannelTest::ReceiveData(int32_t length) {} + HWTEST_F(SensorBasicDataChannelTest, SensorBasicDataChannelTest_001, TestSize.Level1) { SEN_HILOGI("SensorBasicDataChannelTest_001 in"); @@ -65,11 +68,13 @@ HWTEST_F(SensorBasicDataChannelTest, SensorBasicDataChannelTest_001, TestSize.Le ret = sensorChannel.SendToBinder(data); ASSERT_EQ(ret, ERR_OK); - char buff[128] = {}; - ret = sensorChannel.SendData(static_cast(buff), sizeof(buff)); + SensorData sensorData; + ret = sensorChannel.SendData(static_cast(&sensorData), sizeof(sensorData)); ASSERT_EQ(ret, ERR_OK); - ret = sensorChannel.ReceiveData(static_cast(buff), sizeof(buff)); + ret = sensorChannel.ReceiveData([this] (int32_t length) { + this->ReceiveData(length); + }, static_cast(&sensorData), sizeof(sensorData)); ASSERT_NE(ret, ERROR); sensorChannel.DestroySensorBasicChannel(); @@ -134,12 +139,16 @@ HWTEST_F(SensorBasicDataChannelTest, ReceiveData_001, TestSize.Level1) SEN_HILOGI("ReceiveData_001 in"); SensorBasicDataChannel sensorChannel = SensorBasicDataChannel(); char buff[128] = {}; - int32_t ret = sensorChannel.ReceiveData(static_cast(buff), sizeof(buff)); + int32_t ret = sensorChannel.ReceiveData([this] (int32_t length) { + this->ReceiveData(length); + }, static_cast(buff), sizeof(buff)); ASSERT_EQ(ret, ERROR); sensorChannel.CreateSensorBasicChannel(); char *buff1 = nullptr; - ret = sensorChannel.ReceiveData(static_cast(buff1), sizeof(buff1)); + ret = sensorChannel.ReceiveData([this] (int32_t length) { + this->ReceiveData(length); + }, static_cast(buff1), sizeof(buff1)); ASSERT_EQ(ret, ERROR); sensorChannel.DestroySensorBasicChannel(); diff --git a/utils/common/include/sensor_basic_data_channel.h b/utils/common/include/sensor_basic_data_channel.h index c895e15c..4cfbe60a 100644 --- a/utils/common/include/sensor_basic_data_channel.h +++ b/utils/common/include/sensor_basic_data_channel.h @@ -26,6 +26,7 @@ namespace OHOS { namespace Sensors { +using ClientExcuteCB = std::function; class SensorBasicDataChannel : public RefBase { public: SensorBasicDataChannel(); @@ -38,7 +39,7 @@ public: int32_t SendToBinder(MessageParcel &data); void CloseSendFd(); int32_t SendData(const void *vaddr, size_t size); - int32_t ReceiveData(void *vaddr, size_t size); + int32_t ReceiveData(ClientExcuteCB callBack, void *vaddr, size_t size); bool GetSensorStatus() const; void SetSensorStatus(bool isActive); const std::unordered_map &GetDataCacheBuf() const; diff --git a/utils/common/src/sensor_basic_data_channel.cpp b/utils/common/src/sensor_basic_data_channel.cpp index 4a4a1c2f..b92af95d 100644 --- a/utils/common/src/sensor_basic_data_channel.cpp +++ b/utils/common/src/sensor_basic_data_channel.cpp @@ -34,7 +34,10 @@ using namespace OHOS::HiviewDFX; namespace { constexpr int32_t SENSOR_READ_DATA_SIZE = sizeof(SensorData) * 100; constexpr int32_t DEFAULT_CHANNEL_SIZE = 2 * 1024; +constexpr int32_t MAX_RECV_LIMIT = 32; constexpr int32_t SOCKET_PAIR_SIZE = 2; +constexpr int32_t SEND_RETRY_LIMIT = 32; +constexpr int32_t SEND_RETRY_SLEEP_TIME = 500; } // namespace SensorBasicDataChannel::SensorBasicDataChannel() : sendFd_(-1), receiveFd_(-1), isActive_(false) @@ -151,31 +154,75 @@ void SensorBasicDataChannel::CloseSendFd() int32_t SensorBasicDataChannel::SendData(const void *vaddr, size_t size) { CHKPR(vaddr, SENSOR_CHANNEL_SEND_ADDR_ERR); - std::unique_lock lock(fdLock_); - if (sendFd_ < 0) { - SEN_HILOGE("Failed, param is invalid"); - return SENSOR_CHANNEL_SEND_ADDR_ERR; - } - ssize_t length; + auto sensorData = reinterpret_cast(vaddr); + int32_t idx = 0; + int32_t retryCount = 0; + int32_t buffSize = static_cast(size); + int32_t remSize = buffSize; do { - length = send(sendFd_, vaddr, size, MSG_DONTWAIT | MSG_NOSIGNAL); - } while (errno == EINTR); - if (length < 0) { - SEN_HILOGD("Send fail:%{public}d, length:%{public}d", errno, (int32_t)length); + std::unique_lock lock(fdLock_); + if (sendFd_ < 0) { + SEN_HILOGE("Failed, param is invalid"); + return SENSOR_CHANNEL_SEND_ADDR_ERR; + } + retryCount++; + ssize_t length = send(sendFd_, &sensorData[idx], remSize, MSG_DONTWAIT | MSG_NOSIGNAL); + if (length < 0) { + if (errno == EAGAIN || errno == EINTR || errno == EWOULDBLOCK) { + SEN_HILOGD("Continue for EAGAIN|EINTR|EWOULDBLOCK, errno:%{public}d, sendFd_:%{public}d", + errno, sendFd_); + usleep(SEND_RETRY_SLEEP_TIME); + continue; + } + SEN_HILOGE("Send fail, errno:%{public}d, length:%{public}d, sendFd: %{public}d", + errno, static_cast(length), sendFd_); + return SENSOR_CHANNEL_SEND_DATA_ERR; + } + idx += length; + remSize -= length; + if (remSize > 0) { + usleep(SEND_RETRY_SLEEP_TIME); + } + } while (remSize > 0 && retryCount < SEND_RETRY_LIMIT); + if ((retryCount >= SEND_RETRY_LIMIT) && (remSize > 0)) { + SEN_HILOGE("Send fail, size:%{public}d, retryCount:%{public}d, idx:%{public}d, " + "buffSize:%{public}d, errno:%{public}d", buffSize, retryCount, idx, buffSize, errno); return SENSOR_CHANNEL_SEND_DATA_ERR; } return ERR_OK; } -int32_t SensorBasicDataChannel::ReceiveData(void *vaddr, size_t size) +int32_t SensorBasicDataChannel::ReceiveData(ClientExcuteCB callBack, void *vaddr, size_t size) { - std::unique_lock lock(fdLock_); - if ((vaddr == nullptr) || (receiveFd_ < 0)) { - SEN_HILOGE("Failed, vaddr is null or receiveFd_ invalid"); + if (vaddr == nullptr || callBack == nullptr) { + SEN_HILOGE("Failed, callBack is null or vaddr is null"); return ERROR; } - ssize_t length = recv(receiveFd_, vaddr, size, 0); - return static_cast(length); + ssize_t length = 0; + int32_t retryCount = 0; + for (int32_t i = 0; i < MAX_RECV_LIMIT; i++) { + { + std::unique_lock lock(fdLock_); + if (receiveFd_ < 0) { + SEN_HILOGE("Failed, receiveFd_ invalid"); + return ERROR; + } + length = recv(receiveFd_, vaddr, size, MSG_DONTWAIT | MSG_NOSIGNAL); + } + retryCount++; + if (length > 0) { + callBack(static_cast(length)); + } else { + if ((length < 0) && (errno == EINTR || errno == EAGAIN || errno == EWOULDBLOCK)) { + SEN_HILOGD("Continue for EAGAIN|EINTR|EWOULDBLOCK, errno:%{public}d, sendFd_:%{public}d", + errno, sendFd_); + continue; + } + SEN_HILOGE("recv failed:%{public}s", ::strerror(errno)); + return ERROR; + } + }; + return ERR_OK; } int32_t SensorBasicDataChannel::GetSendDataFd() -- Gitee