1 Star 0 Fork 1

itopen/napi_demo

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
该仓库未声明开源许可证文件(LICENSE),使用请关注具体项目描述及其代码上游依赖。
克隆/下载
serial_async_callback.cpp 5.50 KB
一键复制 编辑 原始数据 按行查看 历史
wenfei6316 提交于 2024-07-23 10:54 . dayu800 napi demo
/*
* 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 "serial_async_callback.h"
#include <cassert>
#include <unistd.h>
#include "uv.h"
#include "log/serialport_log_wrapper.h"
#include "i_serialport_client.h"
namespace OHOS {
namespace SerialPort {
SerialAsyncCallback::~SerialAsyncCallback()
{
if (env_ != 0 && funcRef_ != 0) {
napi_delete_reference(env_, funcRef_);
funcRef_ = 0;
}
std::lock_guard<std::mutex> lock(mutex_);
name_ = "";
while (!buffer_.empty()) {
SerialData *data = buffer_.front();
buffer_.pop();
free(data);
}
}
void SerialAsyncCallback::SetEnv(const std::string &name, napi_env env, napi_value func)
{
name_ = name;
env_ = env;
napi_status result_status = napi_create_reference(env_, func, 1, &funcRef_);
if (result_status != napi_ok) {
SERIALPORT_LOGE("serial '%{public}s' setenv failed", name_.c_str());
}
}
void SerialAsyncCallback::OnCallBackEvent()
{
do {
if (buffer_.empty()) {
break;
}
struct AsyncData {
std::shared_ptr<SerialCallbackBase> callback;
};
AsyncData *asyncData = new(std::nothrow) AsyncData;
if (asyncData == nullptr) {
break;
}
asyncData->callback = shared_from_this();
uv_loop_s *loop = nullptr;
uv_work_t *work = new(std::nothrow) uv_work_t;
if (work == nullptr) {
delete asyncData;
break;
}
napi_get_uv_event_loop(env_, &loop);
work->data = (void *)asyncData;
int32_t ret = uv_queue_work(loop, work, [](uv_work_t *) {}, [](uv_work_t *work, int status) {
AsyncData *callData = (AsyncData *) work->data;
std::shared_ptr<SerialCallbackBase> callback = callData->callback;
int32_t delay = ((SerialAsyncCallback *)callback.get())->OnUvWork();
get_serial_client()->SendCallbackEvent(callback, delay);
delete callData;
delete work;
});
if (ret == 0) {
return; // work don't set busy_
}
SERIALPORT_LOGE("serial '%{public}s' queue_work failed", name_.c_str());
delete asyncData;
delete work;
} while(0);
busy_ = false;
}
int32_t SerialAsyncCallback::OnUvWork() {
SerialData *buffer = nullptr;
{
std::lock_guard<std::mutex> lock(mutex_);
if (!buffer_.empty()) {
buffer = buffer_.front();
buffer_.pop();
}
}
if (buffer == nullptr) {
SERIALPORT_LOGI("serial uv_work buffer null");
return 10;
}
napi_handle_scope scope = nullptr;
napi_open_handle_scope(env_, &scope);
SERIALPORT_LOGI("serial '%{public}s' uv_work fun", name_.c_str());
napi_value cb = 0;
napi_status result_status = napi_get_reference_value(env_, funcRef_, &cb);
if (result_status != napi_ok) {
SERIALPORT_LOGE("serial '%{public}s' uv_work get fun ref failed", name_.c_str());
}
napi_value thisVar = 0;
napi_value outData;
napi_value arrayBuffer = nullptr;
napi_create_external_arraybuffer(env_, (void *)buffer->data, buffer->length,
[](napi_env env, void *finalize_data, void *finalize_hint) {
free(finalize_hint);
}, buffer, &arrayBuffer);
napi_create_typedarray(env_, napi_uint8_array, buffer->length, arrayBuffer, 0, &outData);
napi_value args[1] = {outData};
napi_value cb_result;
napi_get_undefined(env_, &thisVar);
result_status = napi_call_function(env_, thisVar, cb, 1, args, &cb_result);
if (result_status != napi_ok) {
SERIALPORT_LOGE("serial '%{public}s' uv_work napi_call_function failed", name_.c_str());
}
napi_close_handle_scope(env_, scope);
return 5; // delay 5 ms
}
void SerialAsyncCallback::OnRecvData(const uint8_t *buffer, uint32_t length)
{
std::lock_guard<std::mutex> lock(mutex_);
if (name_.length() <= 0) {
SERIALPORT_LOGI("serial name is empty");
return;
}
SerialData *old = nullptr;
if (!buffer_.empty()) {
old = buffer_.back();
if (old != nullptr && (old->length + length <= MIN_BUFFER_SIZE)) {
memcpy(&old->data[old->length], buffer, length);
old->length += length;
} else {
old = nullptr;
}
}
if (old == nullptr) {
uint32_t newLen = sizeof(uint32_t) + (length<MIN_BUFFER_SIZE?MIN_BUFFER_SIZE:length);
SerialData *recv = (SerialData *)malloc(newLen);
if (recv == nullptr) {
SERIALPORT_LOGE("serial %{public}s allocate memory failed", name_.c_str());
return;
}
recv->length = length;
memcpy(recv->data, buffer, length);
buffer_.push(recv);
}
if (!busy_) {
busy_ = true;
get_serial_client()->SendCallbackEvent(shared_from_this(), 0);
}
SERIALPORT_LOGI("serial %{public}s buffer size %{public}d", name_.c_str(), buffer_.size());
return;
}
} // namespace SerialPort
} // namespace OHOS
Loading...
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
1
https://gitee.com/itopen/napi_demo.git
git@gitee.com:itopen/napi_demo.git
itopen
napi_demo
napi_demo
master

搜索帮助