From 5cb93d4dc9668d2d84b5c4904dfa3efe1141a91e Mon Sep 17 00:00:00 2001 From: Hollokin Date: Wed, 17 Jan 2024 14:31:47 +0800 Subject: [PATCH 01/11] =?UTF-8?q?fs.copy=E6=94=AF=E6=8C=81=E5=8F=96?= =?UTF-8?q?=E6=B6=88=E6=8B=B7=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Hollokin --- interfaces/kits/js/BUILD.gn | 2 + .../class_tasksignal/task_signal_entity.h | 39 ++++ .../task_signal_n_exporter.cpp | 177 ++++++++++++++++++ .../class_tasksignal/task_signal_n_exporter.h | 46 +++++ .../kits/js/src/mod_fs/properties/copy.cpp | 57 +++++- .../kits/js/src/mod_fs/properties/copy.h | 7 +- interfaces/kits/native/BUILD.gn | 45 ++++- .../kits/native/task_signal/task_signal.cpp | 56 ++++++ .../kits/native/task_signal/task_signal.h | 45 +++++ .../native/task_signal/task_signal_listener.h | 30 +++ 10 files changed, 497 insertions(+), 7 deletions(-) create mode 100644 interfaces/kits/js/src/mod_fs/class_tasksignal/task_signal_entity.h create mode 100644 interfaces/kits/js/src/mod_fs/class_tasksignal/task_signal_n_exporter.cpp create mode 100644 interfaces/kits/js/src/mod_fs/class_tasksignal/task_signal_n_exporter.h create mode 100644 interfaces/kits/native/task_signal/task_signal.cpp create mode 100644 interfaces/kits/native/task_signal/task_signal.h create mode 100644 interfaces/kits/native/task_signal/task_signal_listener.h diff --git a/interfaces/kits/js/BUILD.gn b/interfaces/kits/js/BUILD.gn index 49baa2f84..251de2eaf 100644 --- a/interfaces/kits/js/BUILD.gn +++ b/interfaces/kits/js/BUILD.gn @@ -152,6 +152,7 @@ ohos_shared_library("fs") { deps = [ "${utils_path}/filemgmt_libhilog:filemgmt_libhilog", "${utils_path}/filemgmt_libn:filemgmt_libn", + "${file_api_path}/interfaces/kits/native:task_signal_native", ] use_exceptions = true @@ -185,6 +186,7 @@ ohos_shared_library("fs") { "src/mod_fs/class_readeriterator/readeriterator_n_exporter.cpp", "src/mod_fs/class_stream/flush.cpp", "src/mod_fs/class_stream/stream_n_exporter.cpp", + "src/mod_fs/class_tasksignal/task_signal_n_exporter.cpp", "src/mod_fs/class_watcher/watcher_entity.cpp", "src/mod_fs/class_watcher/watcher_n_exporter.cpp", "src/mod_fs/properties/copy.cpp", diff --git a/interfaces/kits/js/src/mod_fs/class_tasksignal/task_signal_entity.h b/interfaces/kits/js/src/mod_fs/class_tasksignal/task_signal_entity.h new file mode 100644 index 000000000..e116f5125 --- /dev/null +++ b/interfaces/kits/js/src/mod_fs/class_tasksignal/task_signal_entity.h @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2024 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. + */ + +#ifndef FILEMANAGEMENT_FILE_API_TASK_SIGNAL_ENTITY_H +#define FILEMANAGEMENT_FILE_API_TASK_SIGNAL_ENTITY_H + +#include "task_signal.h" +namespace OHOS::FileManagement::ModuleFileIO { +class JSCallbackContext { +public: + explicit JSCallbackContext(LibN::NVal jsVal) : ref_(jsVal) {} + ~JSCallbackContext() {} + + napi_env env_; + LibN::NRef ref_; + std::string filePath; + uint32_t event_ = 0; + uint32_t cookie_ = 0; +}; + +struct TaskSignalEntity { + DistributedFS::ModuleTaskSignal::TaskSignal taskSignal; + std::shared_ptr callbackContext = nullptr; +}; +} // namespace OHOS::FileManagement::ModuleFileIO + +#endif // FILEMANAGEMENT_FILE_API_TASK_SIGNAL_ENTITY_H diff --git a/interfaces/kits/js/src/mod_fs/class_tasksignal/task_signal_n_exporter.cpp b/interfaces/kits/js/src/mod_fs/class_tasksignal/task_signal_n_exporter.cpp new file mode 100644 index 000000000..e43fc2b4b --- /dev/null +++ b/interfaces/kits/js/src/mod_fs/class_tasksignal/task_signal_n_exporter.cpp @@ -0,0 +1,177 @@ +/* + * Copyright (c) 2024 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 "task_signal_n_exporter.h" + +#include "task_signal.h" +#include "task_signal_entity.h" +#include "file_utils.h" + +namespace OHOS::FileManagement::ModuleFileIO { +using namespace std; +using namespace OHOS::FileManagement::LibN; +napi_value TaskSignalNExporter::Constructor(napi_env env, napi_callback_info info) +{ + HILOGI("run in JsConstructor"); + NFuncArg funcArg(env, info); + if (!funcArg.InitArgs(NARG_CNT::ZERO)) { + HILOGE("Failed to get param."); + NError(EINVAL).ThrowErr(env); + return nullptr; + } + + auto taskSignalNExporter = CreateUniquePtr(); + if (taskSignalNExporter == nullptr) { + HILOGE("Failed to request heap memory."); + NError(ENOMEM).ThrowErr(env); + return nullptr; + } + taskSignal_.SetTaskSignalListener(taskSignalNExporter); // todo taskSignalNExporter能不能设置为unique_ptr? taskSignal初始化的时机? + if (!NClass::SetEntityFor(env, funcArg.GetThisVar(), move(taskSignalEntity))) { + HILOGE("Failed to set taskSignalEntity."); + NError(EIO).ThrowErr(env); + return nullptr; + } + return funcArg.GetThisVar(); +} + +bool TaskSignalNExporter::Export() +{ + vector props = { + NVal::DeclareNapiFunction("cancel", Cancel), + NVal::DeclareNapiFunction("onCancel", OnCancel), + }; + + auto [succ, classValue] = NClass::DefineClass(exports_.env_, className_, Constructor, std::move(props)); + if (!succ) { + HILOGE("Failed to DefineClass"); + NError(EIO).ThrowErr(exports_.env_); + return false; + } + + succ = NClass::SaveClass(exports_.env_, className_, classValue); + if (!succ) { + HILOGE("Failed to SaveClass"); + NError(EIO).ThrowErr(exports_.env_); + return false; + } + + return exports_.AddProp(className_, classValue); +} + +napi_value TaskSignalNExporter::Cancel(napi_env env, napi_callback_info info) +{ + NFuncArg funcArg(env, info); + if (!funcArg.InitArgs(NARG_CNT::ZERO)) { + HILOGE("Failed to get param when stop."); + NError(EINVAL).ThrowErr(env); + return nullptr; + } + + auto taskSignalNExporter = NClass::GetEntityOf(env, funcArg.GetThisVar()); + if (!taskSignalNExporter) { + HILOGE("Failed to get watcherEntity when stop."); + NError(EINVAL).ThrowErr(env); + return nullptr; + } + taskSignalNExporter->taskSignal_.Cancel(); + return NVal::CreateUndefined(env).val_; +} + +napi_value TaskSignalNExporter::OnCancel(napi_env env, napi_callback_info info) +{ + HILOGE("OnCancel run."); + NFuncArg funcArg(env, info); + if (!funcArg.InitArgs(NARG_CNT::ONE)) { + HILOGE("Failed to get param when stop."); + NError(EINVAL).ThrowErr(env); + return nullptr; + } + auto taskSignalNExporter = NClass::GetEntityOf(env, funcArg.GetThisVar()); // todo entity是否应该是当前类的成员属性??这个不能是单例的 + if (!taskSignalNExporter) { + HILOGE("Failed to get watcherEntity when stop."); + NError(EINVAL).ThrowErr(env); + return nullptr; + } + auto callbackContext = std::make_shared(NVal(env, funcArg[0])); // todo 这里需要换成裸指针不? +// JSCallbackContext *callbackContext = new (std::nothrow) JSCallbackContext(funcArg[0]); // todo 换成智能指针 + callbackContext->env_ = env; + +// taskSignalEntity->RegisterListener(funcArg[0], callbackContext); // todo 不需要注册,只需要将callbackContext记录下来,作为类成员属性 + taskSignalNExporter->callbackContext_ = callbackContext; + napi_value result = nullptr; + napi_get_null(env, &result); + return result; +} + +void TaskSignalNExporter::OnCancel(const std::string &path) +{ + HILOGE("run in."); + // todo 不要entity,放在当前类中。 + // todo 获取到保存的jsCallbackContext, 保存到uv_work_t的data中 + // todo 给jsCallbackContext的filePath赋值,抛到异步线程给开发者 + uv_loop_s *loop = nullptr; + if (!callbackContext) { + HILOGE("Failed to parse watcher callback"); + return; + } + auto env = callbackContext->env_; // todo callback搞成智能指针 + callbackContext->filePath = path; + napi_get_uv_event_loop(env, &loop); + if (loop == nullptr) { + HILOGE("Failed to get uv event loop"); + return; + } + uv_work_t *work = new (std::nothrow) uv_work_t; + if (work == nullptr) { + HILOGE("Failed to create uv_work_t pointer"); + return; + } + work->data = reinterpret_cast(&callbackContext); + uv_queue_work_with_qos( + loop, work, [](uv_work_t *work) {}, + [](uv_work_t *work, int status) { + JSCallbackContext *callbackContext = + reinterpret_cast(work->data); + if (callbackContext == nullptr) { + HILOGE("Failed to create context pointer"); + return; + } + if (!callbackContext->ref_) { + HILOGE("Failed to get nref reference"); + return; + } + napi_handle_scope scope = nullptr; + napi_status ret = napi_open_handle_scope(callbackContext->env_, &scope); + if (ret != napi_ok) { + HILOGE("Failed to open handle scope, ret: %{public}d", ret); + return; + } + napi_env env = callbackContext->env_; + napi_value jsCallback = callbackContext->ref_.Deref(env).val_; + napi_value filePath = NVal::CreateUTF8String(env, callbackContext->filePath).val_; + napi_value retVal = nullptr; + ret = napi_call_function(env, nullptr, jsCallback, 1, &filePath, &retVal); + if (ret != napi_ok) { + HILOGE("Failed to call napi_call_function, ret: %{public}d", ret); + } + ret = napi_close_handle_scope(callbackContext->env_, scope); + if (ret != napi_ok) { + HILOGE("Failed to close handle scope, ret: %{public}d", ret); + } + }, + uv_qos_user_initiated); +} +} diff --git a/interfaces/kits/js/src/mod_fs/class_tasksignal/task_signal_n_exporter.h b/interfaces/kits/js/src/mod_fs/class_tasksignal/task_signal_n_exporter.h new file mode 100644 index 000000000..e2904b250 --- /dev/null +++ b/interfaces/kits/js/src/mod_fs/class_tasksignal/task_signal_n_exporter.h @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2024 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. + */ + +#ifndef FILEMANAGEMENT_FILE_API_TASK_SIGNAL_N_EXPORTER_H +#define FILEMANAGEMENT_FILE_API_TASK_SIGNAL_N_EXPORTER_H + +#include + +#include "filemgmt_libn.h" +#include "task_signal_listener.h" +#include "task_signal_entity.h" + +namespace OHOS::FileManagement::ModuleFileIO { +class TaskSignalNExporter final : public LibN::NExporter, public DistributedFS::ModuleTaskSignal::TaskSignalListener { +public: + inline static const std::string className_ = "TaskSignal"; + DistributedFS::ModuleTaskSignal::TaskSignal taskSignal_; + + bool Export() override; + std::string GetClassName() override; + + static napi_value Constructor(napi_env env, napi_callback_info info); + static napi_value Cancel(napi_env env, napi_callback_info info); + static napi_value OnCancel(napi_env env, napi_callback_info info); + void OnCancel(const std::string &path) override; + + TaskSignalNExporter(napi_env env, napi_value exports); + TaskSignalNExporter(): taskSignal_(){}; + ~TaskSignalNExporter() override; + std::shared_ptr callbackContext_ = nullptr; +}; +} // namespace OHOS::FileManagement::ModuleFileIO + +#endif // FILEMANAGEMENT_FILE_API_TASK_SIGNAL_N_EXPORTER_H diff --git a/interfaces/kits/js/src/mod_fs/properties/copy.cpp b/interfaces/kits/js/src/mod_fs/properties/copy.cpp index 2b8ee3963..938a1ed52 100644 --- a/interfaces/kits/js/src/mod_fs/properties/copy.cpp +++ b/interfaces/kits/js/src/mod_fs/properties/copy.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Huawei Device Co., Ltd. + * Copyright (c) 2023-2024 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 @@ -26,6 +26,7 @@ #include #include #include +#include #include #include #include @@ -39,6 +40,7 @@ #include "iservice_registry.h" #include "system_ability_definition.h" #include "trans_listener.h" +#include "../../common/file_helper/fd_guard.h" namespace OHOS { namespace FileManagement { @@ -50,6 +52,7 @@ const string PROCEDURE_COPY_NAME = "FileFSCopy"; constexpr int DISMATCH = 0; constexpr int MATCH = 1; constexpr int BUF_SIZE = 1024; +constexpr long COPY_CHECKPOINT_BYTES = 524288; constexpr std::chrono::milliseconds NOTIFY_PROGRESS_DELAY(200); std::recursive_mutex Copy::mutex_; std::map> Copy::jsCbMap_; @@ -88,6 +91,21 @@ tuple Copy::GetListenerFromOptionArg(napi_env env, const NFuncArg &f return { true, NVal() }; } +tuple Copy::GetCopySignalFromOptionArg(napi_env env, const NFuncArg &funcArg) +{ + if (funcArg.GetArgc() >= NARG_CNT::THREE) { + NVal op(env, funcArg[NARG_POS::THIRD]); + if (op.HasProp("copySignal") && !op.GetProp("copySignal").TypeIs(napi_undefined)) { + if (!op.GetProp("copySignal").TypeIs(napi_object)) { + HILOGE("Illegal options.progressListener type"); + return { false, NVal() }; + } + return { true, op.GetProp("copySignal") }; + } + } + return { true, NVal() }; +} + bool Copy::IsRemoteUri(const std::string &uri) { // NETWORK_PARA @@ -137,6 +155,33 @@ void Copy::CheckOrCreatePath(const std::string &destPath) } } +int Copy::SendFile(const string &src, const string &dest, std::shared_ptr signal) +{ + auto [err, fileSize] = GetFileSize(src); + DistributedFS::FDGuard sfd; + DistributedFS::FDGuard ofd; + struct stat attrSrc; + if (stat(src.c_str(), &attrSrc) == FAILED) { + return EIO; + } + sfd.SetFD(open(src.c_str(), O_RDONLY)); + ofd.SetFD(open(dest.c_str(), O_WRONLY | O_CREAT, attrSrc.st_mode)); + if (sfd.GetFD() == FAILED || ofd.GetFD() == FAILED) { + return EIO; + } + int ret = EIO; + while (ret = sendfile(ofd.GetFD(), sfd.GetFD(), nullptr, COPY_CHECKPOINT_BYTES)) { + if (ret == -1) { + remove(dest.c_str()); + return EIO; + } + if (signal != nullptr) { + signal->CheckCancelIfNeed(src); // todo 根据返回值确认是否中断成功 + } + } + return ERRNO_NOERR; +} + int Copy::CopyFile(const string &src, const string &dest) { HILOGD("src = %{public}s, dest = %{public}s", src.c_str(), dest.c_str()); @@ -621,7 +666,7 @@ std::string Copy::ConvertUriToPath(const std::string &uri) } tuple> Copy::CreateFileInfos( - const std::string &srcUri, const std::string &destUri, NVal &listener) + const std::string &srcUri, const std::string &destUri, NVal &listener, NVal ©Signal) { auto infos = CreateSharedPtr(); if (infos == nullptr) { @@ -631,6 +676,7 @@ tuple> Copy::CreateFileInfos( infos->srcUri = srcUri; infos->destUri = destUri; infos->listener = listener; + infos->copySignal = copySignal; // todo copySignal也要绑定FileInfos,双向绑定,才能在开发者调用cancel时,知道是否绑定了拷贝任务。 infos->srcPath = ConvertUriToPath(infos->srcUri); infos->destPath = ConvertUriToPath(infos->destUri); infos->notifyTime = std::chrono::steady_clock::now() + NOTIFY_PROGRESS_DELAY; @@ -670,12 +716,13 @@ int Copy::ParseJsParam(napi_env env, NFuncArg &funcArg, std::shared_ptr filePaths; int exceptionCode = ERRNO_NOERR; // notify copy thread or listener thread has exceptions. bool operator==(const FileInfos &infos) const @@ -120,6 +122,7 @@ private: // operator of napi static tuple ParseJsOperand(napi_env env, NVal pathOrFdFromJsArg); static tuple GetListenerFromOptionArg(napi_env env, const NFuncArg &funcArg); + static tuple GetCopySignalFromOptionArg(napi_env env, const NFuncArg &funcArg); static void CheckOrCreatePath(const std::string &destPath); static int ParseJsParam(napi_env env, NFuncArg &funcArg, std::shared_ptr &fileInfos); @@ -143,11 +146,13 @@ private: static tuple GetFileSize(const std::string &path); static uint64_t GetDirSize(std::shared_ptr infos, std::string path); static int CopyFile(const string &src, const string &dest); + static int SendFile( + const string &src, const string &dest, std::shared_ptr signal); static int MakeDir(const string &path); static int CopySubDir(const string &srcPath, const string &destPath, std::shared_ptr infos); static int CopyDirFunc(const string &src, const string &dest, std::shared_ptr infos); static tuple> CreateFileInfos( - const std::string &srcUri, const std::string &destUri, NVal &listener); + const std::string &srcUri, const std::string &destUri, NVal &listener, NVal ©Signal); static int ExecCopy(std::shared_ptr infos); // operator of file size diff --git a/interfaces/kits/native/BUILD.gn b/interfaces/kits/native/BUILD.gn index 4a9848961..90cac966d 100644 --- a/interfaces/kits/native/BUILD.gn +++ b/interfaces/kits/native/BUILD.gn @@ -22,6 +22,14 @@ config("remote_uri_config") { ] } +config("task_signal_config") { + visibility = [ ":*" ] + include_dirs = [ + "include", + "task_signal", + ] +} + ohos_shared_library("remote_uri_native") { if (!use_mingw_win && !use_mac) { stack_protector_ret = true @@ -51,6 +59,41 @@ ohos_shared_library("remote_uri_native") { subsystem_name = "filemanagement" } +ohos_shared_library("task_signal_native") { + if (!use_mingw_win && !use_mac) { + stack_protector_ret = true + sanitize = { + integer_overflow = true + ubsan = true + boundary_sanitize = true + cfi = true + cfi_cross_dso = true + debug = false + } + } + + sources = [ "task_signal/task_signal.cpp" ] + + public_configs = [ ":task_signal_config" ] + + deps = [ "${utils_path}/filemgmt_libhilog:filemgmt_libhilog" ] + + external_deps = [ + #"ability_base:zuri", + #"access_token:libaccesstoken_sdk", + "c_utils:utils", + "hilog:libhilog", + #"ipc:ipc_core", + ] + + innerapi_tags = [ "platformsdk" ] + part_name = "file_api" + subsystem_name = "filemanagement" +} + group("build_kits_native") { - deps = [ ":remote_uri_native" ] + deps = [ + ":remote_uri_native", + ":task_signal_native" + ] } diff --git a/interfaces/kits/native/task_signal/task_signal.cpp b/interfaces/kits/native/task_signal/task_signal.cpp new file mode 100644 index 000000000..9132feedd --- /dev/null +++ b/interfaces/kits/native/task_signal/task_signal.cpp @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2024 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 "task_signal.h" + +#include "filemgmt_libhilog.h" + +namespace OHOS { +namespace DistributedFS { +namespace ModuleTaskSignal { +using namespace FileManagement; +void TaskSignal::Cancel() +{ + needCancel_ = true; +} + +bool TaskSignal::IsCanceled() +{ + return needCancel_; +} + +void TaskSignal::SetTaskSignalListener(std::shared_ptr signalListener) +{ + HILOGI("SetTaskSignalListener in."); + if (signalListener_ == nullptr) { + signalListener_ = signalListener; + } +} + +void TaskSignal::OnCancel(const std::string &path) +{ + signalListener_->OnCancel(path); +} + +void TaskSignal::CheckCancelIfNeed(const std::string &path) +{ + if (!needCancel_) { + return; + } + OnCancel(path); +} +} +} // namespace DistributedFS +} // namespace OHOS diff --git a/interfaces/kits/native/task_signal/task_signal.h b/interfaces/kits/native/task_signal/task_signal.h new file mode 100644 index 000000000..e17f39669 --- /dev/null +++ b/interfaces/kits/native/task_signal/task_signal.h @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2024 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. + */ + +#ifndef FILEMANAGEMENT_FILE_API_TASK_SIGNAL_H +#define FILEMANAGEMENT_FILE_API_TASK_SIGNAL_H + +#include +#include + +#include "task_signal_listener.h" + +namespace OHOS { +namespace DistributedFS { +namespace ModuleTaskSignal { +class TaskSignal { +public: + TaskSignal(); + ~TaskSignal(); + void Cancel(); + bool IsCanceled(); + void SetCancelListener(); + void CheckCancelIfNeed(const std::string &path); + void OnCancel(const std::string &path); + void SetTaskSignalListener(std::shared_ptr signalListener); + bool needCancel_ = false; + +private: + std::shared_ptr signalListener_; +}; +} // namespace ModuleTaskSignal +} // namespace DistributedFS +} // namespace OHOS +#endif // FILEMANAGEMENT_FILE_API_TASK_SIGNAL_H diff --git a/interfaces/kits/native/task_signal/task_signal_listener.h b/interfaces/kits/native/task_signal/task_signal_listener.h new file mode 100644 index 000000000..4d98776d4 --- /dev/null +++ b/interfaces/kits/native/task_signal/task_signal_listener.h @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2024 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. + */ + +#ifndef FILEMANAGEMENT_FILE_API_TASK_SIGNAL_LISTENER_H +#define FILEMANAGEMENT_FILE_API_TASK_SIGNAL_LISTENER_H + +namespace OHOS { +namespace DistributedFS { +namespace ModuleTaskSignal { +class TaskSignalListener { +public: + virtual ~TaskSignalListener() = default; + virtual void OnCancel(const std::string &path) = 0; +}; +} // namespace ModuleTaskSignal +} // namespace DistributedFS +} // namespace OHOS +#endif // FILEMANAGEMENT_FILE_API_TASK_SIGNAL_LISTENER_H -- Gitee From 32ee84d7683239317d8be8fa00597933020eaffc Mon Sep 17 00:00:00 2001 From: Hollokin Date: Wed, 17 Jan 2024 14:45:20 +0800 Subject: [PATCH 02/11] =?UTF-8?q?fs.copy=E6=94=AF=E6=8C=81=E5=8F=96?= =?UTF-8?q?=E6=B6=88=E6=8B=B7=E8=B4=9D=E8=83=BD=E5=8A=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Hollokin --- interfaces/kits/js/src/mod_fs/properties/copy.cpp | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/interfaces/kits/js/src/mod_fs/properties/copy.cpp b/interfaces/kits/js/src/mod_fs/properties/copy.cpp index 938a1ed52..68c441487 100644 --- a/interfaces/kits/js/src/mod_fs/properties/copy.cpp +++ b/interfaces/kits/js/src/mod_fs/properties/copy.cpp @@ -170,13 +170,23 @@ int Copy::SendFile(const string &src, const string &dest, std::shared_ptr= COPY_CHECKPOINT_BYTES时, + // if (signal != nullptr) { + // signal->CheckCancelIfNeed(src); + // } + } while (ret = sendfile(ofd.GetFD(), sfd.GetFD(), nullptr, COPY_CHECKPOINT_BYTES)) { if (ret == -1) { remove(dest.c_str()); return EIO; } if (signal != nullptr) { - signal->CheckCancelIfNeed(src); // todo 根据返回值确认是否中断成功 + signal->CheckCancelIfNeed(src); // todo 根据返回值确认是否中断 } } return ERRNO_NOERR; -- Gitee From b9227fd734dbe3eba53bc2dfd5d472f4c5e9f500 Mon Sep 17 00:00:00 2001 From: Hollokin Date: Thu, 18 Jan 2024 09:20:00 +0800 Subject: [PATCH 03/11] =?UTF-8?q?js.copy=E6=94=AF=E6=8C=81=E5=8F=96?= =?UTF-8?q?=E6=B6=88=E6=8B=B7=E8=B4=9D=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Hollokin --- interfaces/kits/js/BUILD.gn | 1 + .../class_tasksignal/task_signal_entity.cpp | 79 +++++++++ .../class_tasksignal/task_signal_entity.h | 13 +- .../task_signal_n_exporter.cpp | 154 ++++++++++-------- .../class_tasksignal/task_signal_n_exporter.h | 11 +- .../kits/js/src/mod_fs/properties/copy.cpp | 39 +++-- .../kits/js/src/mod_fs/properties/copy.h | 4 +- .../kits/native/task_signal/task_signal.cpp | 3 + 8 files changed, 213 insertions(+), 91 deletions(-) create mode 100644 interfaces/kits/js/src/mod_fs/class_tasksignal/task_signal_entity.cpp diff --git a/interfaces/kits/js/BUILD.gn b/interfaces/kits/js/BUILD.gn index 251de2eaf..73f19e358 100644 --- a/interfaces/kits/js/BUILD.gn +++ b/interfaces/kits/js/BUILD.gn @@ -186,6 +186,7 @@ ohos_shared_library("fs") { "src/mod_fs/class_readeriterator/readeriterator_n_exporter.cpp", "src/mod_fs/class_stream/flush.cpp", "src/mod_fs/class_stream/stream_n_exporter.cpp", + "src/mod_fs/class_tasksignal/task_signal_entity.cpp", "src/mod_fs/class_tasksignal/task_signal_n_exporter.cpp", "src/mod_fs/class_watcher/watcher_entity.cpp", "src/mod_fs/class_watcher/watcher_n_exporter.cpp", diff --git a/interfaces/kits/js/src/mod_fs/class_tasksignal/task_signal_entity.cpp b/interfaces/kits/js/src/mod_fs/class_tasksignal/task_signal_entity.cpp new file mode 100644 index 000000000..479dbb642 --- /dev/null +++ b/interfaces/kits/js/src/mod_fs/class_tasksignal/task_signal_entity.cpp @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2024 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 "task_signal_entity.h" + +namespace OHOS::FileManagement::ModuleFileIO { +void TaskSignalEntity::OnCancel(const std::string &path) +{ + HILOGI("tyx::OnCancel run in."); + // todo 不要entity,放在当前类中。 + // todo 获取到保存的jsCallbackContext, 保存到uv_work_t的data中 + // todo 给jsCallbackContext的filePath赋值,抛到异步线程给开发者 + uv_loop_s *loop = nullptr; + if (!callbackContext) { + HILOGE("Failed to parse watcher callback"); + return; + } + auto env = callbackContext->env_; // todo callback搞成智能指针 + callbackContext->filePath = path; + napi_get_uv_event_loop(env, &loop); + if (loop == nullptr) { + HILOGE("Failed to get uv event loop"); + return; + } + uv_work_t *work = new (std::nothrow) uv_work_t; + if (work == nullptr) { + HILOGE("Failed to create uv_work_t pointer"); + return; + } + work->data = reinterpret_cast(&callbackContext); + uv_queue_work_with_qos( + loop, work, [](uv_work_t *work) {}, + [](uv_work_t *work, int status) { + JSCallbackContext *callbackContext = + reinterpret_cast(work->data); + if (callbackContext == nullptr) { + HILOGE("Failed to create context pointer"); + return; + } + if (!callbackContext->ref_) { + HILOGE("Failed to get nref reference"); + return; + } + napi_handle_scope scope = nullptr; + napi_status ret = napi_open_handle_scope(callbackContext->env_, &scope); + if (ret != napi_ok) { + HILOGE("Failed to open handle scope, ret: %{public}d", ret); + return; + } + napi_env env = callbackContext->env_; + napi_value jsCallback = callbackContext->ref_.Deref(env).val_; + napi_value filePath = LibN::NVal::CreateUTF8String(env, callbackContext->filePath).val_; + napi_value retVal = nullptr; + ret = napi_call_function(env, nullptr, jsCallback, 1, &filePath, &retVal); + if (ret != napi_ok) { + HILOGE("Failed to call napi_call_function, ret: %{public}d", ret); + } + ret = napi_close_handle_scope(callbackContext->env_, scope); + if (ret != napi_ok) { + HILOGE("Failed to close handle scope, ret: %{public}d", ret); + } + }, + uv_qos_user_initiated); +} +} diff --git a/interfaces/kits/js/src/mod_fs/class_tasksignal/task_signal_entity.h b/interfaces/kits/js/src/mod_fs/class_tasksignal/task_signal_entity.h index e116f5125..9f2f29b60 100644 --- a/interfaces/kits/js/src/mod_fs/class_tasksignal/task_signal_entity.h +++ b/interfaces/kits/js/src/mod_fs/class_tasksignal/task_signal_entity.h @@ -17,6 +17,10 @@ #define FILEMANAGEMENT_FILE_API_TASK_SIGNAL_ENTITY_H #include "task_signal.h" + +#include "filemgmt_libn.h" +#include "task_signal_listener.h" + namespace OHOS::FileManagement::ModuleFileIO { class JSCallbackContext { public: @@ -30,8 +34,13 @@ public: uint32_t cookie_ = 0; }; -struct TaskSignalEntity { - DistributedFS::ModuleTaskSignal::TaskSignal taskSignal; +class TaskSignalEntity: public DistributedFS::ModuleTaskSignal::TaskSignalListener { +public: + TaskSignalEntity() = default; + ~TaskSignalEntity() override = default; + void OnCancel(const std::string &path) override; + + std::shared_ptr taskSignal = nullptr; std::shared_ptr callbackContext = nullptr; }; } // namespace OHOS::FileManagement::ModuleFileIO diff --git a/interfaces/kits/js/src/mod_fs/class_tasksignal/task_signal_n_exporter.cpp b/interfaces/kits/js/src/mod_fs/class_tasksignal/task_signal_n_exporter.cpp index e43fc2b4b..cbf65a6c6 100644 --- a/interfaces/kits/js/src/mod_fs/class_tasksignal/task_signal_n_exporter.cpp +++ b/interfaces/kits/js/src/mod_fs/class_tasksignal/task_signal_n_exporter.cpp @@ -32,18 +32,33 @@ napi_value TaskSignalNExporter::Constructor(napi_env env, napi_callback_info inf return nullptr; } - auto taskSignalNExporter = CreateUniquePtr(); - if (taskSignalNExporter == nullptr) { + auto taskSignalEntity = CreateUniquePtr(); + if (taskSignalEntity == nullptr) { HILOGE("Failed to request heap memory."); NError(ENOMEM).ThrowErr(env); return nullptr; } - taskSignal_.SetTaskSignalListener(taskSignalNExporter); // todo taskSignalNExporter能不能设置为unique_ptr? taskSignal初始化的时机? - if (!NClass::SetEntityFor(env, funcArg.GetThisVar(), move(taskSignalEntity))) { - HILOGE("Failed to set taskSignalEntity."); + taskSignalEntity->taskSignal = std::make_shared(); + if (!NClass::SetEntityFor(env, funcArg.GetThisVar(), move(taskSignalEntity))) { + HILOGE("Failed to set watcherEntity."); NError(EIO).ThrowErr(env); return nullptr; } + + +// auto taskSignalNExporter = CreateUniquePtr(); +// if (taskSignalNExporter == nullptr) { +// HILOGE("Failed to request heap memory."); +// NError(ENOMEM).ThrowErr(env); +// return nullptr; +// } +// // todo 还是放在entity中吧 +// taskSignal_.SetTaskSignalListener(taskSignalNExporter); // todo taskSignalNExporter能不能设置为unique_ptr? taskSignal初始化的时机? +// if (!NClass::SetEntityFor(env, funcArg.GetThisVar(), move(taskSignalEntity))) { +// HILOGE("Failed to set taskSignalEntity."); +// NError(EIO).ThrowErr(env); +// return nullptr; +// } return funcArg.GetThisVar(); } @@ -80,13 +95,13 @@ napi_value TaskSignalNExporter::Cancel(napi_env env, napi_callback_info info) return nullptr; } - auto taskSignalNExporter = NClass::GetEntityOf(env, funcArg.GetThisVar()); - if (!taskSignalNExporter) { + auto taskSignalEntity = NClass::GetEntityOf(env, funcArg.GetThisVar()); + if (!taskSignalEntity) { HILOGE("Failed to get watcherEntity when stop."); NError(EINVAL).ThrowErr(env); return nullptr; } - taskSignalNExporter->taskSignal_.Cancel(); + taskSignalEntity->taskSignal->Cancel(); return NVal::CreateUndefined(env).val_; } @@ -99,8 +114,8 @@ napi_value TaskSignalNExporter::OnCancel(napi_env env, napi_callback_info info) NError(EINVAL).ThrowErr(env); return nullptr; } - auto taskSignalNExporter = NClass::GetEntityOf(env, funcArg.GetThisVar()); // todo entity是否应该是当前类的成员属性??这个不能是单例的 - if (!taskSignalNExporter) { + auto taskSignalEntity = NClass::GetEntityOf(env, funcArg.GetThisVar()); // todo entity是否应该是当前类的成员属性??这个不能是单例的 + if (!taskSignalEntity) { HILOGE("Failed to get watcherEntity when stop."); NError(EINVAL).ThrowErr(env); return nullptr; @@ -110,68 +125,69 @@ napi_value TaskSignalNExporter::OnCancel(napi_env env, napi_callback_info info) callbackContext->env_ = env; // taskSignalEntity->RegisterListener(funcArg[0], callbackContext); // todo 不需要注册,只需要将callbackContext记录下来,作为类成员属性 - taskSignalNExporter->callbackContext_ = callbackContext; + // todo 需要再SetEntity进去 + taskSignalEntity->callbackContext = callbackContext; napi_value result = nullptr; napi_get_null(env, &result); return result; } -void TaskSignalNExporter::OnCancel(const std::string &path) -{ - HILOGE("run in."); - // todo 不要entity,放在当前类中。 - // todo 获取到保存的jsCallbackContext, 保存到uv_work_t的data中 - // todo 给jsCallbackContext的filePath赋值,抛到异步线程给开发者 - uv_loop_s *loop = nullptr; - if (!callbackContext) { - HILOGE("Failed to parse watcher callback"); - return; - } - auto env = callbackContext->env_; // todo callback搞成智能指针 - callbackContext->filePath = path; - napi_get_uv_event_loop(env, &loop); - if (loop == nullptr) { - HILOGE("Failed to get uv event loop"); - return; - } - uv_work_t *work = new (std::nothrow) uv_work_t; - if (work == nullptr) { - HILOGE("Failed to create uv_work_t pointer"); - return; - } - work->data = reinterpret_cast(&callbackContext); - uv_queue_work_with_qos( - loop, work, [](uv_work_t *work) {}, - [](uv_work_t *work, int status) { - JSCallbackContext *callbackContext = - reinterpret_cast(work->data); - if (callbackContext == nullptr) { - HILOGE("Failed to create context pointer"); - return; - } - if (!callbackContext->ref_) { - HILOGE("Failed to get nref reference"); - return; - } - napi_handle_scope scope = nullptr; - napi_status ret = napi_open_handle_scope(callbackContext->env_, &scope); - if (ret != napi_ok) { - HILOGE("Failed to open handle scope, ret: %{public}d", ret); - return; - } - napi_env env = callbackContext->env_; - napi_value jsCallback = callbackContext->ref_.Deref(env).val_; - napi_value filePath = NVal::CreateUTF8String(env, callbackContext->filePath).val_; - napi_value retVal = nullptr; - ret = napi_call_function(env, nullptr, jsCallback, 1, &filePath, &retVal); - if (ret != napi_ok) { - HILOGE("Failed to call napi_call_function, ret: %{public}d", ret); - } - ret = napi_close_handle_scope(callbackContext->env_, scope); - if (ret != napi_ok) { - HILOGE("Failed to close handle scope, ret: %{public}d", ret); - } - }, - uv_qos_user_initiated); -} +//void TaskSignalNExporter::OnCancel(const std::string &path) +//{ +// HILOGI("tyx::OnCancel run in."); +// // todo 不要entity,放在当前类中。 +// // todo 获取到保存的jsCallbackContext, 保存到uv_work_t的data中 +// // todo 给jsCallbackContext的filePath赋值,抛到异步线程给开发者 +// uv_loop_s *loop = nullptr; +// if (!callbackContext) { +// HILOGE("Failed to parse watcher callback"); +// return; +// } +// auto env = callbackContext->env_; // todo callback搞成智能指针 +// callbackContext->filePath = path; +// napi_get_uv_event_loop(env, &loop); +// if (loop == nullptr) { +// HILOGE("Failed to get uv event loop"); +// return; +// } +// uv_work_t *work = new (std::nothrow) uv_work_t; +// if (work == nullptr) { +// HILOGE("Failed to create uv_work_t pointer"); +// return; +// } +// work->data = reinterpret_cast(&callbackContext); +// uv_queue_work_with_qos( +// loop, work, [](uv_work_t *work) {}, +// [](uv_work_t *work, int status) { +// JSCallbackContext *callbackContext = +// reinterpret_cast(work->data); +// if (callbackContext == nullptr) { +// HILOGE("Failed to create context pointer"); +// return; +// } +// if (!callbackContext->ref_) { +// HILOGE("Failed to get nref reference"); +// return; +// } +// napi_handle_scope scope = nullptr; +// napi_status ret = napi_open_handle_scope(callbackContext->env_, &scope); +// if (ret != napi_ok) { +// HILOGE("Failed to open handle scope, ret: %{public}d", ret); +// return; +// } +// napi_env env = callbackContext->env_; +// napi_value jsCallback = callbackContext->ref_.Deref(env).val_; +// napi_value filePath = NVal::CreateUTF8String(env, callbackContext->filePath).val_; +// napi_value retVal = nullptr; +// ret = napi_call_function(env, nullptr, jsCallback, 1, &filePath, &retVal); +// if (ret != napi_ok) { +// HILOGE("Failed to call napi_call_function, ret: %{public}d", ret); +// } +// ret = napi_close_handle_scope(callbackContext->env_, scope); +// if (ret != napi_ok) { +// HILOGE("Failed to close handle scope, ret: %{public}d", ret); +// } +// }, +// uv_qos_user_initiated); +//} } diff --git a/interfaces/kits/js/src/mod_fs/class_tasksignal/task_signal_n_exporter.h b/interfaces/kits/js/src/mod_fs/class_tasksignal/task_signal_n_exporter.h index e2904b250..f83123b46 100644 --- a/interfaces/kits/js/src/mod_fs/class_tasksignal/task_signal_n_exporter.h +++ b/interfaces/kits/js/src/mod_fs/class_tasksignal/task_signal_n_exporter.h @@ -19,14 +19,14 @@ #include #include "filemgmt_libn.h" -#include "task_signal_listener.h" +//#include "task_signal_listener.h" #include "task_signal_entity.h" namespace OHOS::FileManagement::ModuleFileIO { -class TaskSignalNExporter final : public LibN::NExporter, public DistributedFS::ModuleTaskSignal::TaskSignalListener { +class TaskSignalNExporter final : public LibN::NExporter { public: inline static const std::string className_ = "TaskSignal"; - DistributedFS::ModuleTaskSignal::TaskSignal taskSignal_; +// DistributedFS::ModuleTaskSignal::TaskSignal taskSignal_; bool Export() override; std::string GetClassName() override; @@ -34,12 +34,11 @@ public: static napi_value Constructor(napi_env env, napi_callback_info info); static napi_value Cancel(napi_env env, napi_callback_info info); static napi_value OnCancel(napi_env env, napi_callback_info info); - void OnCancel(const std::string &path) override; +// void OnCancel(const std::string &path) override; TaskSignalNExporter(napi_env env, napi_value exports); - TaskSignalNExporter(): taskSignal_(){}; ~TaskSignalNExporter() override; - std::shared_ptr callbackContext_ = nullptr; +// std::shared_ptr callbackContext_ = nullptr; }; } // namespace OHOS::FileManagement::ModuleFileIO diff --git a/interfaces/kits/js/src/mod_fs/properties/copy.cpp b/interfaces/kits/js/src/mod_fs/properties/copy.cpp index 68c441487..1fe1d91a4 100644 --- a/interfaces/kits/js/src/mod_fs/properties/copy.cpp +++ b/interfaces/kits/js/src/mod_fs/properties/copy.cpp @@ -41,6 +41,7 @@ #include "system_ability_definition.h" #include "trans_listener.h" #include "../../common/file_helper/fd_guard.h" +#include "../class_tasksignal/task_signal_n_exporter.h" namespace OHOS { namespace FileManagement { @@ -155,13 +156,15 @@ void Copy::CheckOrCreatePath(const std::string &destPath) } } -int Copy::SendFile(const string &src, const string &dest, std::shared_ptr signal) +int Copy::SendFile(const string &src, const string &dest, std::shared_ptr infos) { + HILOGI("tyx::SendFile in, src = %{public}s, dest = %{public}s", src.c_str(), dest.c_str()); auto [err, fileSize] = GetFileSize(src); DistributedFS::FDGuard sfd; DistributedFS::FDGuard ofd; struct stat attrSrc; if (stat(src.c_str(), &attrSrc) == FAILED) { + HILOGE("tyx::stat failed, src = %{public}s, errno = %{public}d", src.c_str(), errno); return EIO; } sfd.SetFD(open(src.c_str(), O_RDONLY)); @@ -170,24 +173,34 @@ int Copy::SendFile(const string &src, const string &dest, std::shared_ptr(infos->env, infos->copySignal.val_); // todo 传入infos->copySignal.val_不应该 + if (!taskSignalEntity) { + HILOGE("Failed to get watcherEntity when stop."); + return EIO; + } if (fileSize <= COPY_CHECKPOINT_BYTES) { - if (sendfile(ofd.GetFD(), sfd.GetFD(), nullptr, COPY_CHECKPOINT_BYTES) == -1) { + HILOGI("tyx::fileSize <= COPY_CHECKPOINT_BYTES, fileSize = %{public}llu", fileSize); + if (sendfile(ofd.GetFD(), sfd.GetFD(), nullptr, fileSize) == -1) { + HILOGE("tyx::sendfile failed, errno = %{public}d", errno); remove(dest.c_str()); return EIO; } // todo 更新checkpoint, 当checkpoint >= COPY_CHECKPOINT_BYTES时, - // if (signal != nullptr) { - // signal->CheckCancelIfNeed(src); - // } - } - while (ret = sendfile(ofd.GetFD(), sfd.GetFD(), nullptr, COPY_CHECKPOINT_BYTES)) { + if (infos != nullptr && !infos->copySignal) { + HILOGI("tyx::ready to CheckCancelIfNeed."); + // todo copySignal为object类型,napi_unwrap之后,拿到对应的C++对象,再调用CheckCancelIfNeed接口 + taskSignalEntity->taskSignal->CheckCancelIfNeed(src); + } + } else { + while ((ret = sendfile(ofd.GetFD(), sfd.GetFD(), nullptr, COPY_CHECKPOINT_BYTES)) != -1) { + if (infos != nullptr && !infos->copySignal) { + taskSignalEntity->taskSignal->CheckCancelIfNeed(src); // todo 根据返回值确认是否中断 + } + } if (ret == -1) { remove(dest.c_str()); return EIO; } - if (signal != nullptr) { - signal->CheckCancelIfNeed(src); // todo 根据返回值确认是否中断 - } } return ERRNO_NOERR; } @@ -317,7 +330,8 @@ int Copy::RecurCopyDir(const string &srcPath, const string &destPath, std::share return CopySubDir(src, dest, infos); } infos->filePaths.insert(dest); - auto res = CopyFile(src, dest); + auto res = SendFile(src, dest, infos); +// auto res = CopyFile(src, dest); if (res != ERRNO_NOERR) { return res; } @@ -709,7 +723,8 @@ int Copy::ExecCopy(std::shared_ptr infos) { if (IsFile(infos->srcPath) && IsFile(infos->destPath)) { // copyFile - return CopyFile(infos->srcPath.c_str(), infos->destPath.c_str()); + return SendFile(infos->srcPath, infos->destPath, infos); +// return CopyFile(infos->srcPath.c_str(), infos->destPath.c_str()); } if (IsDirectory(infos->srcPath) && IsDirectory(infos->destPath)) { // copyDir diff --git a/interfaces/kits/js/src/mod_fs/properties/copy.h b/interfaces/kits/js/src/mod_fs/properties/copy.h index 8de9af72e..6b6cecfda 100644 --- a/interfaces/kits/js/src/mod_fs/properties/copy.h +++ b/interfaces/kits/js/src/mod_fs/properties/copy.h @@ -85,6 +85,7 @@ struct FileInfos { NVal listener; NVal copySignal; std::set filePaths; + long checkPoint = 0; int exceptionCode = ERRNO_NOERR; // notify copy thread or listener thread has exceptions. bool operator==(const FileInfos &infos) const { @@ -146,8 +147,7 @@ private: static tuple GetFileSize(const std::string &path); static uint64_t GetDirSize(std::shared_ptr infos, std::string path); static int CopyFile(const string &src, const string &dest); - static int SendFile( - const string &src, const string &dest, std::shared_ptr signal); + static int SendFile(const string &src, const string &dest, std::shared_ptr infos); static int MakeDir(const string &path); static int CopySubDir(const string &srcPath, const string &destPath, std::shared_ptr infos); static int CopyDirFunc(const string &src, const string &dest, std::shared_ptr infos); diff --git a/interfaces/kits/native/task_signal/task_signal.cpp b/interfaces/kits/native/task_signal/task_signal.cpp index 9132feedd..b23a0ac4a 100644 --- a/interfaces/kits/native/task_signal/task_signal.cpp +++ b/interfaces/kits/native/task_signal/task_signal.cpp @@ -41,12 +41,15 @@ void TaskSignal::SetTaskSignalListener(std::shared_ptr signa void TaskSignal::OnCancel(const std::string &path) { + HILOGI("tyx::OnCancel in."); signalListener_->OnCancel(path); } void TaskSignal::CheckCancelIfNeed(const std::string &path) { + HILOGI("tyx::CheckCancelIfNeed in."); if (!needCancel_) { + HILOGI("tyx::do not need to cancel."); return; } OnCancel(path); -- Gitee From 50c72c2e6b9ea0b5dbb45def03ed0f501d56f5e6 Mon Sep 17 00:00:00 2001 From: Hollokin Date: Thu, 18 Jan 2024 20:54:25 +0800 Subject: [PATCH 04/11] =?UTF-8?q?fs.copy=E6=94=AF=E6=8C=81=E5=8F=96?= =?UTF-8?q?=E6=B6=88=E6=8B=B7=E8=B4=9D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Hollokin --- interfaces/kits/js/src/common/napi/n_class.h | 4 +- .../class_tasksignal/task_signal_entity.h | 5 ++- .../task_signal_n_exporter.cpp | 36 +++++++--------- interfaces/kits/js/src/mod_fs/module.cpp | 2 + .../kits/js/src/mod_fs/properties/copy.cpp | 42 +++++++++++++------ .../kits/js/src/mod_fs/properties/copy.h | 6 ++- .../kits/native/task_signal/task_signal.cpp | 8 ++-- .../kits/native/task_signal/task_signal.h | 6 +-- utils/filemgmt_libn/include/n_class.h | 4 +- utils/filemgmt_libn/src/n_async/n_ref.cpp | 2 + 10 files changed, 69 insertions(+), 46 deletions(-) diff --git a/interfaces/kits/js/src/common/napi/n_class.h b/interfaces/kits/js/src/common/napi/n_class.h index 45ca773e9..146c17a43 100644 --- a/interfaces/kits/js/src/common/napi/n_class.h +++ b/interfaces/kits/js/src/common/napi/n_class.h @@ -40,13 +40,13 @@ public: template static T *GetEntityOf(napi_env env, napi_value objStat) { if (!env || !objStat) { - HILOGE("Empty input: env %d, obj %d", env == nullptr, objStat == nullptr); + HILOGE("Empty input: env %{public}d, obj %{public}d", env == nullptr, objStat == nullptr); return nullptr; } T *t = nullptr; napi_status status = napi_unwrap(env, objStat, (void **)&t); if (status != napi_ok) { - HILOGE("Cannot umwarp for pointer: %d", status); + HILOGE("Cannot umwarp for pointer: %{public}d", status); return nullptr; } return t; diff --git a/interfaces/kits/js/src/mod_fs/class_tasksignal/task_signal_entity.h b/interfaces/kits/js/src/mod_fs/class_tasksignal/task_signal_entity.h index 9f2f29b60..f1ece0f28 100644 --- a/interfaces/kits/js/src/mod_fs/class_tasksignal/task_signal_entity.h +++ b/interfaces/kits/js/src/mod_fs/class_tasksignal/task_signal_entity.h @@ -22,6 +22,7 @@ #include "task_signal_listener.h" namespace OHOS::FileManagement::ModuleFileIO { +using namespace DistributedFS::ModuleTaskSignal; class JSCallbackContext { public: explicit JSCallbackContext(LibN::NVal jsVal) : ref_(jsVal) {} @@ -34,13 +35,13 @@ public: uint32_t cookie_ = 0; }; -class TaskSignalEntity: public DistributedFS::ModuleTaskSignal::TaskSignalListener { +class TaskSignalEntity: public TaskSignalListener { public: TaskSignalEntity() = default; ~TaskSignalEntity() override = default; void OnCancel(const std::string &path) override; - std::shared_ptr taskSignal = nullptr; + std::shared_ptr taskSignal = nullptr; std::shared_ptr callbackContext = nullptr; }; } // namespace OHOS::FileManagement::ModuleFileIO diff --git a/interfaces/kits/js/src/mod_fs/class_tasksignal/task_signal_n_exporter.cpp b/interfaces/kits/js/src/mod_fs/class_tasksignal/task_signal_n_exporter.cpp index cbf65a6c6..3624f34f0 100644 --- a/interfaces/kits/js/src/mod_fs/class_tasksignal/task_signal_n_exporter.cpp +++ b/interfaces/kits/js/src/mod_fs/class_tasksignal/task_signal_n_exporter.cpp @@ -22,9 +22,18 @@ namespace OHOS::FileManagement::ModuleFileIO { using namespace std; using namespace OHOS::FileManagement::LibN; +TaskSignalNExporter::TaskSignalNExporter(napi_env env, napi_value exports) : NExporter(env, exports) {} + +TaskSignalNExporter::~TaskSignalNExporter() {} + +string TaskSignalNExporter::GetClassName() +{ + return TaskSignalNExporter::className_; +} + napi_value TaskSignalNExporter::Constructor(napi_env env, napi_callback_info info) { - HILOGI("run in JsConstructor"); + HILOGI("tyx::run in JsConstructor"); NFuncArg funcArg(env, info); if (!funcArg.InitArgs(NARG_CNT::ZERO)) { HILOGE("Failed to get param."); @@ -44,21 +53,7 @@ napi_value TaskSignalNExporter::Constructor(napi_env env, napi_callback_info inf NError(EIO).ThrowErr(env); return nullptr; } - - -// auto taskSignalNExporter = CreateUniquePtr(); -// if (taskSignalNExporter == nullptr) { -// HILOGE("Failed to request heap memory."); -// NError(ENOMEM).ThrowErr(env); -// return nullptr; -// } -// // todo 还是放在entity中吧 -// taskSignal_.SetTaskSignalListener(taskSignalNExporter); // todo taskSignalNExporter能不能设置为unique_ptr? taskSignal初始化的时机? -// if (!NClass::SetEntityFor(env, funcArg.GetThisVar(), move(taskSignalEntity))) { -// HILOGE("Failed to set taskSignalEntity."); -// NError(EIO).ThrowErr(env); -// return nullptr; -// } + HILOGI("tyx::JsConstructor end."); return funcArg.GetThisVar(); } @@ -68,6 +63,7 @@ bool TaskSignalNExporter::Export() NVal::DeclareNapiFunction("cancel", Cancel), NVal::DeclareNapiFunction("onCancel", OnCancel), }; + string className = GetClassName(); auto [succ, classValue] = NClass::DefineClass(exports_.env_, className_, Constructor, std::move(props)); if (!succ) { @@ -76,14 +72,14 @@ bool TaskSignalNExporter::Export() return false; } - succ = NClass::SaveClass(exports_.env_, className_, classValue); + succ = NClass::SaveClass(exports_.env_, className, classValue); + HILOGI("tyx::TaskSignalNExporter::SaveClass end, className = %{public}s.", className.c_str()); if (!succ) { HILOGE("Failed to SaveClass"); NError(EIO).ThrowErr(exports_.env_); return false; } - - return exports_.AddProp(className_, classValue); + return exports_.AddProp(className, classValue); } napi_value TaskSignalNExporter::Cancel(napi_env env, napi_callback_info info) @@ -107,7 +103,7 @@ napi_value TaskSignalNExporter::Cancel(napi_env env, napi_callback_info info) napi_value TaskSignalNExporter::OnCancel(napi_env env, napi_callback_info info) { - HILOGE("OnCancel run."); + HILOGI("tyx::TaskSignalNExporter::OnCancel run."); NFuncArg funcArg(env, info); if (!funcArg.InitArgs(NARG_CNT::ONE)) { HILOGE("Failed to get param when stop."); diff --git a/interfaces/kits/js/src/mod_fs/module.cpp b/interfaces/kits/js/src/mod_fs/module.cpp index 70086e994..65ba67efd 100644 --- a/interfaces/kits/js/src/mod_fs/module.cpp +++ b/interfaces/kits/js/src/mod_fs/module.cpp @@ -24,6 +24,7 @@ #include "class_randomaccessfile/randomaccessfile_n_exporter.h" #include "class_readeriterator/readeriterator_n_exporter.h" #include "class_stream/stream_n_exporter.h" +#include "class_tasksignal/task_signal_n_exporter.h" #include "class_watcher/watcher_n_exporter.h" #endif #include "filemgmt_libhilog.h" @@ -47,6 +48,7 @@ static napi_value Export(napi_env env, napi_value exports) products.emplace_back(make_unique(env, exports)); products.emplace_back(make_unique(env, exports)); products.emplace_back(make_unique(env, exports)); + products.emplace_back(make_unique(env, exports)); #endif for (auto &&product : products) { #ifdef WIN_PLATFORM diff --git a/interfaces/kits/js/src/mod_fs/properties/copy.cpp b/interfaces/kits/js/src/mod_fs/properties/copy.cpp index 1fe1d91a4..3b893790a 100644 --- a/interfaces/kits/js/src/mod_fs/properties/copy.cpp +++ b/interfaces/kits/js/src/mod_fs/properties/copy.cpp @@ -96,12 +96,17 @@ tuple Copy::GetCopySignalFromOptionArg(napi_env env, const NFuncArg { if (funcArg.GetArgc() >= NARG_CNT::THREE) { NVal op(env, funcArg[NARG_POS::THIRD]); - if (op.HasProp("copySignal") && !op.GetProp("copySignal").TypeIs(napi_undefined)) { - if (!op.GetProp("copySignal").TypeIs(napi_object)) { - HILOGE("Illegal options.progressListener type"); - return { false, NVal() }; + if (op.HasProp("copySignal")) { + if (op.HasProp("copySignal") && !op.GetProp("copySignal").TypeIs(napi_undefined)) { + if (!op.GetProp("copySignal").TypeIs(napi_object)) { + HILOGE("tyx::Illegal options.progressListener type"); + return { false, NVal() }; + } + HILOGI("tyx::op.GetProp(\"copySignal\").TypeIs(napi_object)"); + return { true, op.GetProp("copySignal") }; + } else { + HILOGE("tyx::copySignal TypeIs napi_undefined"); } - return { true, op.GetProp("copySignal") }; } } return { true, NVal() }; @@ -173,11 +178,6 @@ int Copy::SendFile(const string &src, const string &dest, std::shared_ptr(infos->env, infos->copySignal.val_); // todo 传入infos->copySignal.val_不应该 - if (!taskSignalEntity) { - HILOGE("Failed to get watcherEntity when stop."); - return EIO; - } if (fileSize <= COPY_CHECKPOINT_BYTES) { HILOGI("tyx::fileSize <= COPY_CHECKPOINT_BYTES, fileSize = %{public}llu", fileSize); if (sendfile(ofd.GetFD(), sfd.GetFD(), nullptr, fileSize) == -1) { @@ -189,14 +189,22 @@ int Copy::SendFile(const string &src, const string &dest, std::shared_ptrcopySignal) { HILOGI("tyx::ready to CheckCancelIfNeed."); // todo copySignal为object类型,napi_unwrap之后,拿到对应的C++对象,再调用CheckCancelIfNeed接口 - taskSignalEntity->taskSignal->CheckCancelIfNeed(src); + infos->taskSignal->CheckCancelIfNeed(src); } } else { + HILOGI("tyx::start to sendfile."); while ((ret = sendfile(ofd.GetFD(), sfd.GetFD(), nullptr, COPY_CHECKPOINT_BYTES)) != -1) { + HILOGI("tyx::sendfile"); if (infos != nullptr && !infos->copySignal) { - taskSignalEntity->taskSignal->CheckCancelIfNeed(src); // todo 根据返回值确认是否中断 + HILOGI("tyx::ready to run CheckCancelIfNeed."); + if (infos->taskSignal->CheckCancelIfNeed(src)) { + HILOGI("tyx::task was canceled, clear something."); + // todo 清理进度监听线程 + return ECANCELED; + } } } + HILOGI("tyx::sendfile end, ret = %{public}d", ret); if (ret == -1) { remove(dest.c_str()); return EIO; @@ -429,6 +437,7 @@ std::shared_ptr Copy::RegisterListener(napi_env env, const std return nullptr; } jsCbMap_.insert({ *infos, callback }); + HILOGI("tyx::RegisterListener end."); return callback; } @@ -503,7 +512,7 @@ uv_work_t *Copy::GetUVwork(std::shared_ptr infos) return nullptr; } auto callback = iter->second; - infos->env = callback->env; +// infos->env = callback->env; entry = new (std::nothrow) UvEntry(iter->second, infos); if (entry == nullptr) { HILOGE("entry ptr is nullptr."); @@ -692,6 +701,7 @@ std::string Copy::ConvertUriToPath(const std::string &uri) tuple> Copy::CreateFileInfos( const std::string &srcUri, const std::string &destUri, NVal &listener, NVal ©Signal) { + HILOGI("tyx::CreateFileInfos in"); auto infos = CreateSharedPtr(); if (infos == nullptr) { HILOGE("Failed to request heap memory."); @@ -700,13 +710,19 @@ tuple> Copy::CreateFileInfos( infos->srcUri = srcUri; infos->destUri = destUri; infos->listener = listener; + infos->env = listener.env_; + HILOGI("tyx::CreateFileInfos in, get infos->copySignal."); infos->copySignal = copySignal; // todo copySignal也要绑定FileInfos,双向绑定,才能在开发者调用cancel时,知道是否绑定了拷贝任务。 +// infos->copySignalRef = NRef(copySignal); infos->srcPath = ConvertUriToPath(infos->srcUri); infos->destPath = ConvertUriToPath(infos->destUri); infos->notifyTime = std::chrono::steady_clock::now() + NOTIFY_PROGRESS_DELAY; if (listener) { infos->hasListener = true; } + HILOGI("tyx::GetEntityOf TaskSignalEntity before."); + auto taskSignalEntity = NClass::GetEntityOf(infos->env, infos->copySignal.val_); + infos->taskSignal = taskSignalEntity->taskSignal; return { ERRNO_NOERR, infos }; } diff --git a/interfaces/kits/js/src/mod_fs/properties/copy.h b/interfaces/kits/js/src/mod_fs/properties/copy.h index 6b6cecfda..47e0a222e 100644 --- a/interfaces/kits/js/src/mod_fs/properties/copy.h +++ b/interfaces/kits/js/src/mod_fs/properties/copy.h @@ -26,6 +26,7 @@ #include "filemgmt_libn.h" #include "n_async/n_ref.h" #include "task_signal.h" +#include "class_tasksignal/task_signal_entity.h" namespace OHOS { namespace FileManagement { @@ -33,6 +34,7 @@ namespace ModuleFileIO { using namespace std; using namespace OHOS::FileManagement::LibN; using namespace OHOS::AppExecFwk; +using namespace DistributedFS::ModuleTaskSignal; struct ReceiveInfo { std::string path; // dir name std::map fileList; // filename, proceededSize @@ -83,7 +85,9 @@ struct FileInfos { bool hasListener = false; napi_env env; NVal listener; - NVal copySignal; + NVal copySignal; // todo 这个删掉 +// NRef copySignalRef; + std::shared_ptr taskSignal = nullptr; std::set filePaths; long checkPoint = 0; int exceptionCode = ERRNO_NOERR; // notify copy thread or listener thread has exceptions. diff --git a/interfaces/kits/native/task_signal/task_signal.cpp b/interfaces/kits/native/task_signal/task_signal.cpp index b23a0ac4a..792c7251d 100644 --- a/interfaces/kits/native/task_signal/task_signal.cpp +++ b/interfaces/kits/native/task_signal/task_signal.cpp @@ -23,6 +23,7 @@ namespace ModuleTaskSignal { using namespace FileManagement; void TaskSignal::Cancel() { + HILOGI("tyx::Cancel in."); needCancel_ = true; } @@ -33,7 +34,7 @@ bool TaskSignal::IsCanceled() void TaskSignal::SetTaskSignalListener(std::shared_ptr signalListener) { - HILOGI("SetTaskSignalListener in."); + HILOGI("tyx::SetTaskSignalListener in."); if (signalListener_ == nullptr) { signalListener_ = signalListener; } @@ -45,14 +46,15 @@ void TaskSignal::OnCancel(const std::string &path) signalListener_->OnCancel(path); } -void TaskSignal::CheckCancelIfNeed(const std::string &path) +bool TaskSignal::CheckCancelIfNeed(const std::string &path) { HILOGI("tyx::CheckCancelIfNeed in."); if (!needCancel_) { HILOGI("tyx::do not need to cancel."); - return; + return false; } OnCancel(path); + return true; } } } // namespace DistributedFS diff --git a/interfaces/kits/native/task_signal/task_signal.h b/interfaces/kits/native/task_signal/task_signal.h index e17f39669..322418ffc 100644 --- a/interfaces/kits/native/task_signal/task_signal.h +++ b/interfaces/kits/native/task_signal/task_signal.h @@ -26,12 +26,12 @@ namespace DistributedFS { namespace ModuleTaskSignal { class TaskSignal { public: - TaskSignal(); - ~TaskSignal(); + TaskSignal() = default; + ~TaskSignal() = default; void Cancel(); bool IsCanceled(); void SetCancelListener(); - void CheckCancelIfNeed(const std::string &path); + bool CheckCancelIfNeed(const std::string &path); void OnCancel(const std::string &path); void SetTaskSignalListener(std::shared_ptr signalListener); bool needCancel_ = false; diff --git a/utils/filemgmt_libn/include/n_class.h b/utils/filemgmt_libn/include/n_class.h index e82bffbe8..935effa5c 100644 --- a/utils/filemgmt_libn/include/n_class.h +++ b/utils/filemgmt_libn/include/n_class.h @@ -43,13 +43,13 @@ public: template static T *GetEntityOf(napi_env env, napi_value objStat) { if (!env || !objStat) { - HILOGE("Empty input: env %d, obj %d", env == nullptr, objStat == nullptr); + HILOGE("Empty input: env %{public}d, obj %{public}d", env == nullptr, objStat == nullptr); return nullptr; } T *t = nullptr; napi_status status = napi_unwrap(env, objStat, (void **)&t); if (status != napi_ok) { - HILOGE("Cannot umwarp for pointer: %d", status); + HILOGE("Cannot umwarp for pointer: %{public}d", status); return nullptr; } return t; diff --git a/utils/filemgmt_libn/src/n_async/n_ref.cpp b/utils/filemgmt_libn/src/n_async/n_ref.cpp index bd5ebc900..300cefafc 100644 --- a/utils/filemgmt_libn/src/n_async/n_ref.cpp +++ b/utils/filemgmt_libn/src/n_async/n_ref.cpp @@ -15,6 +15,8 @@ #include "n_ref.h" +#include "filemgmt_libhilog.h" + namespace OHOS { namespace FileManagement { namespace LibN { -- Gitee From f2159bf3fdd6120d246cd1bc88c17130d9b8c943 Mon Sep 17 00:00:00 2001 From: Hollokin Date: Fri, 19 Jan 2024 10:30:00 +0800 Subject: [PATCH 05/11] =?UTF-8?q?cancel=E6=88=90=E5=8A=9F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Hollokin --- .../task_signal_n_exporter.cpp | 72 ++----------------- .../kits/js/src/mod_fs/properties/copy.cpp | 10 +-- .../kits/native/task_signal/task_signal.cpp | 30 +++++--- .../kits/native/task_signal/task_signal.h | 8 +-- 4 files changed, 38 insertions(+), 82 deletions(-) diff --git a/interfaces/kits/js/src/mod_fs/class_tasksignal/task_signal_n_exporter.cpp b/interfaces/kits/js/src/mod_fs/class_tasksignal/task_signal_n_exporter.cpp index 3624f34f0..bf07bed2f 100644 --- a/interfaces/kits/js/src/mod_fs/class_tasksignal/task_signal_n_exporter.cpp +++ b/interfaces/kits/js/src/mod_fs/class_tasksignal/task_signal_n_exporter.cpp @@ -22,6 +22,7 @@ namespace OHOS::FileManagement::ModuleFileIO { using namespace std; using namespace OHOS::FileManagement::LibN; +using namespace DistributedFS::ModuleTaskSignal; TaskSignalNExporter::TaskSignalNExporter(napi_env env, napi_value exports) : NExporter(env, exports) {} TaskSignalNExporter::~TaskSignalNExporter() {} @@ -47,8 +48,9 @@ napi_value TaskSignalNExporter::Constructor(napi_env env, napi_callback_info inf NError(ENOMEM).ThrowErr(env); return nullptr; } - taskSignalEntity->taskSignal = std::make_shared(); - if (!NClass::SetEntityFor(env, funcArg.GetThisVar(), move(taskSignalEntity))) { + taskSignalEntity->taskSignal = std::make_shared(); +// taskSignalEntity->taskSignal->SetTaskSignalListener(std::move(taskSignalEntity)); + if (!NClass::SetEntityFor(env, funcArg.GetThisVar(), std::move(taskSignalEntity))) { HILOGE("Failed to set watcherEntity."); NError(EIO).ThrowErr(env); return nullptr; @@ -116,74 +118,14 @@ napi_value TaskSignalNExporter::OnCancel(napi_env env, napi_callback_info info) NError(EINVAL).ThrowErr(env); return nullptr; } + std::unique_ptr signal(taskSignalEntity); + taskSignalEntity->taskSignal->SetTaskSignalListener(std::move(signal)); auto callbackContext = std::make_shared(NVal(env, funcArg[0])); // todo 这里需要换成裸指针不? -// JSCallbackContext *callbackContext = new (std::nothrow) JSCallbackContext(funcArg[0]); // todo 换成智能指针 callbackContext->env_ = env; - -// taskSignalEntity->RegisterListener(funcArg[0], callbackContext); // todo 不需要注册,只需要将callbackContext记录下来,作为类成员属性 - // todo 需要再SetEntity进去 + // todo 需要再SetEntity进去? taskSignalEntity->callbackContext = callbackContext; napi_value result = nullptr; napi_get_null(env, &result); return result; } - -//void TaskSignalNExporter::OnCancel(const std::string &path) -//{ -// HILOGI("tyx::OnCancel run in."); -// // todo 不要entity,放在当前类中。 -// // todo 获取到保存的jsCallbackContext, 保存到uv_work_t的data中 -// // todo 给jsCallbackContext的filePath赋值,抛到异步线程给开发者 -// uv_loop_s *loop = nullptr; -// if (!callbackContext) { -// HILOGE("Failed to parse watcher callback"); -// return; -// } -// auto env = callbackContext->env_; // todo callback搞成智能指针 -// callbackContext->filePath = path; -// napi_get_uv_event_loop(env, &loop); -// if (loop == nullptr) { -// HILOGE("Failed to get uv event loop"); -// return; -// } -// uv_work_t *work = new (std::nothrow) uv_work_t; -// if (work == nullptr) { -// HILOGE("Failed to create uv_work_t pointer"); -// return; -// } -// work->data = reinterpret_cast(&callbackContext); -// uv_queue_work_with_qos( -// loop, work, [](uv_work_t *work) {}, -// [](uv_work_t *work, int status) { -// JSCallbackContext *callbackContext = -// reinterpret_cast(work->data); -// if (callbackContext == nullptr) { -// HILOGE("Failed to create context pointer"); -// return; -// } -// if (!callbackContext->ref_) { -// HILOGE("Failed to get nref reference"); -// return; -// } -// napi_handle_scope scope = nullptr; -// napi_status ret = napi_open_handle_scope(callbackContext->env_, &scope); -// if (ret != napi_ok) { -// HILOGE("Failed to open handle scope, ret: %{public}d", ret); -// return; -// } -// napi_env env = callbackContext->env_; -// napi_value jsCallback = callbackContext->ref_.Deref(env).val_; -// napi_value filePath = NVal::CreateUTF8String(env, callbackContext->filePath).val_; -// napi_value retVal = nullptr; -// ret = napi_call_function(env, nullptr, jsCallback, 1, &filePath, &retVal); -// if (ret != napi_ok) { -// HILOGE("Failed to call napi_call_function, ret: %{public}d", ret); -// } -// ret = napi_close_handle_scope(callbackContext->env_, scope); -// if (ret != napi_ok) { -// HILOGE("Failed to close handle scope, ret: %{public}d", ret); -// } -// }, -// uv_qos_user_initiated); -//} } diff --git a/interfaces/kits/js/src/mod_fs/properties/copy.cpp b/interfaces/kits/js/src/mod_fs/properties/copy.cpp index 3b893790a..60cb11d62 100644 --- a/interfaces/kits/js/src/mod_fs/properties/copy.cpp +++ b/interfaces/kits/js/src/mod_fs/properties/copy.cpp @@ -186,17 +186,14 @@ int Copy::SendFile(const string &src, const string &dest, std::shared_ptr= COPY_CHECKPOINT_BYTES时, - if (infos != nullptr && !infos->copySignal) { + if (infos != nullptr && infos->taskSignal != nullptr) { HILOGI("tyx::ready to CheckCancelIfNeed."); - // todo copySignal为object类型,napi_unwrap之后,拿到对应的C++对象,再调用CheckCancelIfNeed接口 infos->taskSignal->CheckCancelIfNeed(src); } } else { HILOGI("tyx::start to sendfile."); while ((ret = sendfile(ofd.GetFD(), sfd.GetFD(), nullptr, COPY_CHECKPOINT_BYTES)) != -1) { - HILOGI("tyx::sendfile"); - if (infos != nullptr && !infos->copySignal) { - HILOGI("tyx::ready to run CheckCancelIfNeed."); + if (infos != nullptr && infos->taskSignal != nullptr) { if (infos->taskSignal->CheckCancelIfNeed(src)) { HILOGI("tyx::task was canceled, clear something."); // todo 清理进度监听线程 @@ -723,6 +720,9 @@ tuple> Copy::CreateFileInfos( HILOGI("tyx::GetEntityOf TaskSignalEntity before."); auto taskSignalEntity = NClass::GetEntityOf(infos->env, infos->copySignal.val_); infos->taskSignal = taskSignalEntity->taskSignal; + if (infos->taskSignal == nullptr) { + HILOGE("tyx::infos->taskSignal == nullptr."); + } return { ERRNO_NOERR, infos }; } diff --git a/interfaces/kits/native/task_signal/task_signal.cpp b/interfaces/kits/native/task_signal/task_signal.cpp index 792c7251d..13b2a64c5 100644 --- a/interfaces/kits/native/task_signal/task_signal.cpp +++ b/interfaces/kits/native/task_signal/task_signal.cpp @@ -21,38 +21,52 @@ namespace OHOS { namespace DistributedFS { namespace ModuleTaskSignal { using namespace FileManagement; +TaskSignal::TaskSignal() +{ + HILOGI("tyx::constructor of TaskSignal in."); +} + +TaskSignal::~TaskSignal() +{ + HILOGI("tyx::destructor of TaskSignal in."); +} + void TaskSignal::Cancel() { HILOGI("tyx::Cancel in."); - needCancel_ = true; + needCancel_.store(true); } bool TaskSignal::IsCanceled() { - return needCancel_; + return needCancel_.load(); } -void TaskSignal::SetTaskSignalListener(std::shared_ptr signalListener) +void TaskSignal::SetTaskSignalListener(std::unique_ptr signalListener) { HILOGI("tyx::SetTaskSignalListener in."); if (signalListener_ == nullptr) { - signalListener_ = signalListener; + signalListener_ = move(signalListener); } } void TaskSignal::OnCancel(const std::string &path) { HILOGI("tyx::OnCancel in."); - signalListener_->OnCancel(path); + if (signalListener_ != nullptr) { + HILOGI("tyx::OnCancel signalListener_ != nullptr."); + signalListener_->OnCancel(path); + } } bool TaskSignal::CheckCancelIfNeed(const std::string &path) { - HILOGI("tyx::CheckCancelIfNeed in."); - if (!needCancel_) { - HILOGI("tyx::do not need to cancel."); +// HILOGI("tyx::CheckCancelIfNeed in."); + if (!needCancel_.load(std::memory_order_release)) { +// HILOGI("tyx::do not need to cancel."); return false; } + HILOGI("tyx::CheckCancelIfNeed need cancel."); OnCancel(path); return true; } diff --git a/interfaces/kits/native/task_signal/task_signal.h b/interfaces/kits/native/task_signal/task_signal.h index 322418ffc..567067f34 100644 --- a/interfaces/kits/native/task_signal/task_signal.h +++ b/interfaces/kits/native/task_signal/task_signal.h @@ -26,15 +26,15 @@ namespace DistributedFS { namespace ModuleTaskSignal { class TaskSignal { public: - TaskSignal() = default; - ~TaskSignal() = default; + TaskSignal(); + ~TaskSignal(); void Cancel(); bool IsCanceled(); void SetCancelListener(); bool CheckCancelIfNeed(const std::string &path); void OnCancel(const std::string &path); - void SetTaskSignalListener(std::shared_ptr signalListener); - bool needCancel_ = false; + void SetTaskSignalListener(std::unique_ptr signalListener); + std::atomic_bool needCancel_{ false }; private: std::shared_ptr signalListener_; -- Gitee From 009e8f0440e98bb6bee62a7065356127b6011926 Mon Sep 17 00:00:00 2001 From: Hollokin Date: Fri, 19 Jan 2024 15:30:13 +0800 Subject: [PATCH 06/11] =?UTF-8?q?=E5=8F=96=E6=B6=88=E6=8B=B7=E8=B4=9D?= =?UTF-8?q?=E5=9B=9E=E8=B0=83=E6=88=90=E5=8A=9F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Hollokin --- .../class_tasksignal/task_signal_entity.cpp | 44 ++++++++++++++----- .../class_tasksignal/task_signal_entity.h | 13 ++++-- .../task_signal_n_exporter.cpp | 4 +- .../kits/js/src/mod_fs/properties/copy.cpp | 6 +-- .../kits/native/task_signal/task_signal.cpp | 2 +- .../kits/native/task_signal/task_signal.h | 2 +- 6 files changed, 48 insertions(+), 23 deletions(-) diff --git a/interfaces/kits/js/src/mod_fs/class_tasksignal/task_signal_entity.cpp b/interfaces/kits/js/src/mod_fs/class_tasksignal/task_signal_entity.cpp index 479dbb642..3d79cc702 100644 --- a/interfaces/kits/js/src/mod_fs/class_tasksignal/task_signal_entity.cpp +++ b/interfaces/kits/js/src/mod_fs/class_tasksignal/task_signal_entity.cpp @@ -18,60 +18,84 @@ #include "task_signal_entity.h" namespace OHOS::FileManagement::ModuleFileIO { +TaskSignalEntity::TaskSignalEntity() +{ + HILOGE("tyx::TaskSignalEntity()"); +} + +TaskSignalEntity::~TaskSignalEntity() +{ + HILOGE("tyx::~TaskSignalEntity()"); +} + void TaskSignalEntity::OnCancel(const std::string &path) { - HILOGI("tyx::OnCancel run in."); + HILOGI("tyx::OnCancel run in. path = %{public}s", path.c_str()); // todo 不要entity,放在当前类中。 // todo 获取到保存的jsCallbackContext, 保存到uv_work_t的data中 // todo 给jsCallbackContext的filePath赋值,抛到异步线程给开发者 uv_loop_s *loop = nullptr; if (!callbackContext) { - HILOGE("Failed to parse watcher callback"); + HILOGE("tyx::Failed to get callback context."); return; } auto env = callbackContext->env_; // todo callback搞成智能指针 + HILOGI("tyx::callbackContext->env_ end."); callbackContext->filePath = path; + HILOGI("tyx::callbackContext->filePath = path end."); napi_get_uv_event_loop(env, &loop); + HILOGI("tyx::napi_get_uv_event_loop end."); if (loop == nullptr) { - HILOGE("Failed to get uv event loop"); + HILOGE("tyx::Failed to get uv event loop"); return; } uv_work_t *work = new (std::nothrow) uv_work_t; + HILOGI("tyx::uv_work_t end."); if (work == nullptr) { - HILOGE("Failed to create uv_work_t pointer"); + HILOGE("tyx::Failed to create uv_work_t pointer"); return; } - work->data = reinterpret_cast(&callbackContext); + work->data = reinterpret_cast(callbackContext.get()); + HILOGI("tyx::work->data end."); uv_queue_work_with_qos( loop, work, [](uv_work_t *work) {}, [](uv_work_t *work, int status) { + HILOGI("tyx::uv_queue_work_with_qos in."); JSCallbackContext *callbackContext = reinterpret_cast(work->data); if (callbackContext == nullptr) { - HILOGE("Failed to create context pointer"); + HILOGE("tyx::Failed to create context pointer"); return; } if (!callbackContext->ref_) { - HILOGE("Failed to get nref reference"); + HILOGE("tyx::Failed to get nref reference"); return; } napi_handle_scope scope = nullptr; + HILOGI("tyx::napi_open_handle_scope before."); napi_status ret = napi_open_handle_scope(callbackContext->env_, &scope); + HILOGI("tyx::napi_open_handle_scope end, ret = %{public}d.", ret); if (ret != napi_ok) { - HILOGE("Failed to open handle scope, ret: %{public}d", ret); + HILOGE("tyx::Failed to open handle scope, ret: %{public}d", ret); return; } napi_env env = callbackContext->env_; + HILOGE("tyx::start to parse jscallback"); napi_value jsCallback = callbackContext->ref_.Deref(env).val_; + HILOGE("tyx::start to parse filePath to napi_value"); napi_value filePath = LibN::NVal::CreateUTF8String(env, callbackContext->filePath).val_; napi_value retVal = nullptr; ret = napi_call_function(env, nullptr, jsCallback, 1, &filePath, &retVal); if (ret != napi_ok) { - HILOGE("Failed to call napi_call_function, ret: %{public}d", ret); + HILOGE("tyx::Failed to call napi_call_function, ret: %{public}d", ret); + } else { + HILOGI("tyx::success to call napi_call_function"); } ret = napi_close_handle_scope(callbackContext->env_, scope); if (ret != napi_ok) { - HILOGE("Failed to close handle scope, ret: %{public}d", ret); + HILOGE("tyx::Failed to close handle scope, ret: %{public}d", ret); + } else { + HILOGI("tyx::success to call napi_close_handle_scope"); } }, uv_qos_user_initiated); diff --git a/interfaces/kits/js/src/mod_fs/class_tasksignal/task_signal_entity.h b/interfaces/kits/js/src/mod_fs/class_tasksignal/task_signal_entity.h index f1ece0f28..9e3061542 100644 --- a/interfaces/kits/js/src/mod_fs/class_tasksignal/task_signal_entity.h +++ b/interfaces/kits/js/src/mod_fs/class_tasksignal/task_signal_entity.h @@ -25,8 +25,13 @@ namespace OHOS::FileManagement::ModuleFileIO { using namespace DistributedFS::ModuleTaskSignal; class JSCallbackContext { public: - explicit JSCallbackContext(LibN::NVal jsVal) : ref_(jsVal) {} - ~JSCallbackContext() {} + explicit JSCallbackContext(LibN::NVal jsVal) : ref_(jsVal) { + HILOGE("tyx::JSCallbackContext()"); + } + + ~JSCallbackContext() { + HILOGE("tyx::~JSCallbackContext()"); + } napi_env env_; LibN::NRef ref_; @@ -37,8 +42,8 @@ public: class TaskSignalEntity: public TaskSignalListener { public: - TaskSignalEntity() = default; - ~TaskSignalEntity() override = default; + TaskSignalEntity(); + ~TaskSignalEntity() override; void OnCancel(const std::string &path) override; std::shared_ptr taskSignal = nullptr; diff --git a/interfaces/kits/js/src/mod_fs/class_tasksignal/task_signal_n_exporter.cpp b/interfaces/kits/js/src/mod_fs/class_tasksignal/task_signal_n_exporter.cpp index bf07bed2f..8d24883d5 100644 --- a/interfaces/kits/js/src/mod_fs/class_tasksignal/task_signal_n_exporter.cpp +++ b/interfaces/kits/js/src/mod_fs/class_tasksignal/task_signal_n_exporter.cpp @@ -118,8 +118,8 @@ napi_value TaskSignalNExporter::OnCancel(napi_env env, napi_callback_info info) NError(EINVAL).ThrowErr(env); return nullptr; } - std::unique_ptr signal(taskSignalEntity); - taskSignalEntity->taskSignal->SetTaskSignalListener(std::move(signal)); + std::shared_ptr signal(taskSignalEntity); + taskSignalEntity->taskSignal->SetTaskSignalListener(signal); auto callbackContext = std::make_shared(NVal(env, funcArg[0])); // todo 这里需要换成裸指针不? callbackContext->env_ = env; // todo 需要再SetEntity进去? diff --git a/interfaces/kits/js/src/mod_fs/properties/copy.cpp b/interfaces/kits/js/src/mod_fs/properties/copy.cpp index 60cb11d62..c29a90b1a 100644 --- a/interfaces/kits/js/src/mod_fs/properties/copy.cpp +++ b/interfaces/kits/js/src/mod_fs/properties/copy.cpp @@ -195,8 +195,7 @@ int Copy::SendFile(const string &src, const string &dest, std::shared_ptrtaskSignal != nullptr) { if (infos->taskSignal->CheckCancelIfNeed(src)) { - HILOGI("tyx::task was canceled, clear something."); - // todo 清理进度监听线程 + HILOGI("tyx::task was canceled, clear something, Operation canceled."); return ECANCELED; } } @@ -698,7 +697,6 @@ std::string Copy::ConvertUriToPath(const std::string &uri) tuple> Copy::CreateFileInfos( const std::string &srcUri, const std::string &destUri, NVal &listener, NVal ©Signal) { - HILOGI("tyx::CreateFileInfos in"); auto infos = CreateSharedPtr(); if (infos == nullptr) { HILOGE("Failed to request heap memory."); @@ -708,9 +706,7 @@ tuple> Copy::CreateFileInfos( infos->destUri = destUri; infos->listener = listener; infos->env = listener.env_; - HILOGI("tyx::CreateFileInfos in, get infos->copySignal."); infos->copySignal = copySignal; // todo copySignal也要绑定FileInfos,双向绑定,才能在开发者调用cancel时,知道是否绑定了拷贝任务。 -// infos->copySignalRef = NRef(copySignal); infos->srcPath = ConvertUriToPath(infos->srcUri); infos->destPath = ConvertUriToPath(infos->destUri); infos->notifyTime = std::chrono::steady_clock::now() + NOTIFY_PROGRESS_DELAY; diff --git a/interfaces/kits/native/task_signal/task_signal.cpp b/interfaces/kits/native/task_signal/task_signal.cpp index 13b2a64c5..b78119477 100644 --- a/interfaces/kits/native/task_signal/task_signal.cpp +++ b/interfaces/kits/native/task_signal/task_signal.cpp @@ -42,7 +42,7 @@ bool TaskSignal::IsCanceled() return needCancel_.load(); } -void TaskSignal::SetTaskSignalListener(std::unique_ptr signalListener) +void TaskSignal::SetTaskSignalListener(std::shared_ptr signalListener) { HILOGI("tyx::SetTaskSignalListener in."); if (signalListener_ == nullptr) { diff --git a/interfaces/kits/native/task_signal/task_signal.h b/interfaces/kits/native/task_signal/task_signal.h index 567067f34..34b80977e 100644 --- a/interfaces/kits/native/task_signal/task_signal.h +++ b/interfaces/kits/native/task_signal/task_signal.h @@ -33,7 +33,7 @@ public: void SetCancelListener(); bool CheckCancelIfNeed(const std::string &path); void OnCancel(const std::string &path); - void SetTaskSignalListener(std::unique_ptr signalListener); + void SetTaskSignalListener(std::shared_ptr signalListener); std::atomic_bool needCancel_{ false }; private: -- Gitee From f283dd6a098d38759e70e2272bd677c14f03bcf4 Mon Sep 17 00:00:00 2001 From: Hollokin Date: Tue, 23 Jan 2024 18:00:03 +0800 Subject: [PATCH 07/11] =?UTF-8?q?=E8=B7=A8=E7=AB=AF=E6=8B=B7=E8=B4=9D?= =?UTF-8?q?=E5=8F=96=E6=B6=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Hollokin --- interfaces/kits/js/BUILD.gn | 1 + .../class_tasksignal/task_signal_entity.cpp | 21 +++--------- .../kits/js/src/mod_fs/properties/copy.cpp | 33 ++++++++++++++----- .../kits/js/src/mod_fs/properties/copy.h | 3 +- .../copy_listener/trans_listener.cpp | 10 ++++-- .../properties/copy_listener/trans_listener.h | 1 + interfaces/kits/native/BUILD.gn | 6 ++++ .../kits/native/task_signal/task_signal.cpp | 33 ++++++++++++++++--- .../kits/native/task_signal/task_signal.h | 7 ++-- utils/filemgmt_libn/src/n_async/n_ref.cpp | 2 -- 10 files changed, 79 insertions(+), 38 deletions(-) diff --git a/interfaces/kits/js/BUILD.gn b/interfaces/kits/js/BUILD.gn index 73f19e358..7ccb25284 100644 --- a/interfaces/kits/js/BUILD.gn +++ b/interfaces/kits/js/BUILD.gn @@ -118,6 +118,7 @@ ohos_shared_library("fs") { include_dirs = [ "${filemanagement_service_path}/distributedfiledaemon/include/ipc", + "${filemanagement_service_path}/distributedfiledaemon/include/common", "${src_path}/common", "${src_path}/common/file_helper", "${src_path}/mod_fs", diff --git a/interfaces/kits/js/src/mod_fs/class_tasksignal/task_signal_entity.cpp b/interfaces/kits/js/src/mod_fs/class_tasksignal/task_signal_entity.cpp index 3d79cc702..f2660b6ca 100644 --- a/interfaces/kits/js/src/mod_fs/class_tasksignal/task_signal_entity.cpp +++ b/interfaces/kits/js/src/mod_fs/class_tasksignal/task_signal_entity.cpp @@ -31,16 +31,12 @@ TaskSignalEntity::~TaskSignalEntity() void TaskSignalEntity::OnCancel(const std::string &path) { HILOGI("tyx::OnCancel run in. path = %{public}s", path.c_str()); - // todo 不要entity,放在当前类中。 - // todo 获取到保存的jsCallbackContext, 保存到uv_work_t的data中 - // todo 给jsCallbackContext的filePath赋值,抛到异步线程给开发者 uv_loop_s *loop = nullptr; if (!callbackContext) { HILOGE("tyx::Failed to get callback context."); return; } - auto env = callbackContext->env_; // todo callback搞成智能指针 - HILOGI("tyx::callbackContext->env_ end."); + auto env = callbackContext->env_; callbackContext->filePath = path; HILOGI("tyx::callbackContext->filePath = path end."); napi_get_uv_event_loop(env, &loop); @@ -50,7 +46,6 @@ void TaskSignalEntity::OnCancel(const std::string &path) return; } uv_work_t *work = new (std::nothrow) uv_work_t; - HILOGI("tyx::uv_work_t end."); if (work == nullptr) { HILOGE("tyx::Failed to create uv_work_t pointer"); return; @@ -72,30 +67,22 @@ void TaskSignalEntity::OnCancel(const std::string &path) return; } napi_handle_scope scope = nullptr; - HILOGI("tyx::napi_open_handle_scope before."); napi_status ret = napi_open_handle_scope(callbackContext->env_, &scope); - HILOGI("tyx::napi_open_handle_scope end, ret = %{public}d.", ret); if (ret != napi_ok) { - HILOGE("tyx::Failed to open handle scope, ret: %{public}d", ret); + HILOGE("Failed to open handle scope, ret: %{public}d", ret); return; } napi_env env = callbackContext->env_; - HILOGE("tyx::start to parse jscallback"); napi_value jsCallback = callbackContext->ref_.Deref(env).val_; - HILOGE("tyx::start to parse filePath to napi_value"); napi_value filePath = LibN::NVal::CreateUTF8String(env, callbackContext->filePath).val_; napi_value retVal = nullptr; ret = napi_call_function(env, nullptr, jsCallback, 1, &filePath, &retVal); if (ret != napi_ok) { - HILOGE("tyx::Failed to call napi_call_function, ret: %{public}d", ret); - } else { - HILOGI("tyx::success to call napi_call_function"); + HILOGE("Failed to call napi_call_function, ret: %{public}d", ret); } ret = napi_close_handle_scope(callbackContext->env_, scope); if (ret != napi_ok) { - HILOGE("tyx::Failed to close handle scope, ret: %{public}d", ret); - } else { - HILOGI("tyx::success to call napi_close_handle_scope"); + HILOGE("Failed to close handle scope, ret: %{public}d", ret); } }, uv_qos_user_initiated); diff --git a/interfaces/kits/js/src/mod_fs/properties/copy.cpp b/interfaces/kits/js/src/mod_fs/properties/copy.cpp index c29a90b1a..fbb41861a 100644 --- a/interfaces/kits/js/src/mod_fs/properties/copy.cpp +++ b/interfaces/kits/js/src/mod_fs/properties/copy.cpp @@ -365,6 +365,7 @@ int Copy::ExecLocal(std::shared_ptr infos, std::shared_ptrdestPath); } if (!infos->hasListener) { + HILOGI("tyx::has no progress listener.."); return ExecCopy(infos); } auto ret = SubscribeLocalListener(infos, callback); @@ -535,7 +536,11 @@ void Copy::OnFileReceive(std::shared_ptr infos) return; } uv_loop_s *loop = nullptr; - napi_get_uv_event_loop(infos->env, &loop); + napi_status status = napi_get_uv_event_loop(infos->env, &loop); + if (status != napi_ok) { + HILOGE("tyx::Failed to get uv event loop, status = %{public}d", status); + return; + } uv_queue_work( loop, work, [](uv_work_t *work) {}, reinterpret_cast(ReceiveComplete)); } @@ -695,7 +700,7 @@ std::string Copy::ConvertUriToPath(const std::string &uri) } tuple> Copy::CreateFileInfos( - const std::string &srcUri, const std::string &destUri, NVal &listener, NVal ©Signal) + const std::string &srcUri, const std::string &destUri, NVal &listener, NVal copySignal) { auto infos = CreateSharedPtr(); if (infos == nullptr) { @@ -714,10 +719,14 @@ tuple> Copy::CreateFileInfos( infos->hasListener = true; } HILOGI("tyx::GetEntityOf TaskSignalEntity before."); - auto taskSignalEntity = NClass::GetEntityOf(infos->env, infos->copySignal.val_); - infos->taskSignal = taskSignalEntity->taskSignal; - if (infos->taskSignal == nullptr) { - HILOGE("tyx::infos->taskSignal == nullptr."); + if (!infos->copySignal) { + auto taskSignalEntity = NClass::GetEntityOf(infos->env, infos->copySignal.val_); + if (taskSignalEntity != nullptr) { + infos->taskSignal = taskSignalEntity->taskSignal; + if (infos->taskSignal == nullptr) { + HILOGE("tyx::infos->taskSignal == nullptr."); + } + } } return { ERRNO_NOERR, infos }; } @@ -736,7 +745,6 @@ int Copy::ExecCopy(std::shared_ptr infos) if (IsFile(infos->srcPath) && IsFile(infos->destPath)) { // copyFile return SendFile(infos->srcPath, infos->destPath, infos); -// return CopyFile(infos->srcPath.c_str(), infos->destPath.c_str()); } if (IsDirectory(infos->srcPath) && IsDirectory(infos->destPath)) { // copyDir @@ -778,7 +786,7 @@ void Copy::WaitNotifyFinished(std::shared_ptr callback) void Copy::CopyComplete(std::shared_ptr infos, std::shared_ptr callback) { - if (callback != nullptr) { + if (callback != nullptr && infos->hasListener) { callback->progressSize = callback->totalSize; OnFileReceive(infos); } @@ -800,9 +808,16 @@ napi_value Copy::Async(napi_env env, napi_callback_info info) } auto cbExec = [infos, callback]() -> NError { if (IsRemoteUri(infos->srcUri)) { - return TransListener::CopyFileFromSoftBus(infos->srcUri, infos->destUri, std::move(callback)); + auto ret = TransListener::CopyFileFromSoftBus( + infos->srcUri, infos->destUri, infos->sessionId, std::move(callback)); + if (infos->taskSignal != nullptr) { + infos->taskSignal->MarkRemoteTask(); + infos->taskSignal->SetSessionIdOfRemoteTask(infos->sessionId); + } + return ret; } auto result = Copy::ExecLocal(infos, callback); + HILOGE("tyx::ExecLocal end."); CloseNotifyFd(infos, callback); infos->run = false; WaitNotifyFinished(callback); diff --git a/interfaces/kits/js/src/mod_fs/properties/copy.h b/interfaces/kits/js/src/mod_fs/properties/copy.h index 47e0a222e..6c2c0b747 100644 --- a/interfaces/kits/js/src/mod_fs/properties/copy.h +++ b/interfaces/kits/js/src/mod_fs/properties/copy.h @@ -86,6 +86,7 @@ struct FileInfos { napi_env env; NVal listener; NVal copySignal; // todo 这个删掉 + int32_t sessionId = -1; // NRef copySignalRef; std::shared_ptr taskSignal = nullptr; std::set filePaths; @@ -156,7 +157,7 @@ private: static int CopySubDir(const string &srcPath, const string &destPath, std::shared_ptr infos); static int CopyDirFunc(const string &src, const string &dest, std::shared_ptr infos); static tuple> CreateFileInfos( - const std::string &srcUri, const std::string &destUri, NVal &listener, NVal ©Signal); + const std::string &srcUri, const std::string &destUri, NVal &listener, NVal copySignal); static int ExecCopy(std::shared_ptr infos); // operator of file size diff --git a/interfaces/kits/js/src/mod_fs/properties/copy_listener/trans_listener.cpp b/interfaces/kits/js/src/mod_fs/properties/copy_listener/trans_listener.cpp index 8c0ecb9da..917d908c2 100644 --- a/interfaces/kits/js/src/mod_fs/properties/copy_listener/trans_listener.cpp +++ b/interfaces/kits/js/src/mod_fs/properties/copy_listener/trans_listener.cpp @@ -16,6 +16,7 @@ #include "trans_listener.h" #include "distributed_file_daemon_manager.h" +#include "hmdfs_info.h" #include "ipc_skeleton.h" #include "uri.h" @@ -26,6 +27,7 @@ const std::string NETWORK_PARA = "?networkid="; NError TransListener::CopyFileFromSoftBus(const std::string &srcUri, const std::string &destUri, + int &sessionId, std::shared_ptr callback) { sptr transListener = new (std::nothrow) TransListener(); @@ -34,13 +36,17 @@ NError TransListener::CopyFileFromSoftBus(const std::string &srcUri, return NError(ENOMEM); } transListener->callback_ = std::move(callback); - auto networkId = GetNetworkIdFromUri(srcUri); + Storage::DistributedFile::HmdfsInfo info{}; + info.srcUri = srcUri; + info.destUri = destUri; + info.destDeviceId = GetNetworkIdFromUri(srcUri); auto ret = Storage::DistributedFile::DistributedFileDaemonManager::GetInstance().PrepareSession( - srcUri, destUri, networkId, transListener); + info, transListener); if (ret != ERRNO_NOERR) { HILOGE("PrepareSession failed, ret = %{public}d.", ret); return NError(ret); } + sessionId = info.sessionId; std::unique_lock lock(transListener->cvMutex_); transListener->cv_.wait(lock, [&transListener]() { return transListener->copyEvent_ == SUCCESS || transListener->copyEvent_ == FAILED; diff --git a/interfaces/kits/js/src/mod_fs/properties/copy_listener/trans_listener.h b/interfaces/kits/js/src/mod_fs/properties/copy_listener/trans_listener.h index 5a4aecdab..5c8185469 100644 --- a/interfaces/kits/js/src/mod_fs/properties/copy_listener/trans_listener.h +++ b/interfaces/kits/js/src/mod_fs/properties/copy_listener/trans_listener.h @@ -34,6 +34,7 @@ public: int32_t OnFailed(const std::string &sessionName) override; static NError CopyFileFromSoftBus(const std::string &srcUri, const std::string &destUri, + int &sessionId, std::shared_ptr callback); static std::string GetNetworkIdFromUri(const std::string &uri); static void CallbackComplete(uv_work_t *work, int stat); diff --git a/interfaces/kits/native/BUILD.gn b/interfaces/kits/native/BUILD.gn index 90cac966d..10aa8b5d2 100644 --- a/interfaces/kits/native/BUILD.gn +++ b/interfaces/kits/native/BUILD.gn @@ -72,6 +72,11 @@ ohos_shared_library("task_signal_native") { } } + include_dirs = [ + "${filemanagement_service_path}/distributedfiledaemon/include/ipc", + "${filemanagement_service_path}/distributedfiledaemon/include/common", + ] + sources = [ "task_signal/task_signal.cpp" ] public_configs = [ ":task_signal_config" ] @@ -82,6 +87,7 @@ ohos_shared_library("task_signal_native") { #"ability_base:zuri", #"access_token:libaccesstoken_sdk", "c_utils:utils", + "dfs_service:distributed_file_daemon_kit_inner", "hilog:libhilog", #"ipc:ipc_core", ] diff --git a/interfaces/kits/native/task_signal/task_signal.cpp b/interfaces/kits/native/task_signal/task_signal.cpp index b78119477..c3394d2dc 100644 --- a/interfaces/kits/native/task_signal/task_signal.cpp +++ b/interfaces/kits/native/task_signal/task_signal.cpp @@ -15,6 +15,7 @@ #include "task_signal.h" +#include "distributed_file_daemon_manager.h" #include "filemgmt_libhilog.h" namespace OHOS { @@ -31,15 +32,26 @@ TaskSignal::~TaskSignal() HILOGI("tyx::destructor of TaskSignal in."); } -void TaskSignal::Cancel() +int32_t TaskSignal::Cancel() { HILOGI("tyx::Cancel in."); + if (remoteTask_.load()) { + if (sessionId_ == -1) { + return -1; // 取消拷贝失败的错误码 + } + auto ret = Storage::DistributedFile::DistributedFileDaemonManager::GetInstance().CancelCopyTask(sessionId_); + if (ret != 0) { // 取消拷贝失败 + HILOGI("tyx::Cancel in.CancelCopyTask failed, ret = %{public}d", ret); + } + return ret; + } needCancel_.store(true); + return 0; } bool TaskSignal::IsCanceled() { - return needCancel_.load(); + return needCancel_.load() || remoteTask_.load(); } void TaskSignal::SetTaskSignalListener(std::shared_ptr signalListener) @@ -61,15 +73,26 @@ void TaskSignal::OnCancel(const std::string &path) bool TaskSignal::CheckCancelIfNeed(const std::string &path) { -// HILOGI("tyx::CheckCancelIfNeed in."); - if (!needCancel_.load(std::memory_order_release)) { -// HILOGI("tyx::do not need to cancel."); + if (!needCancel_.load()) { + HILOGI("tyx::do not need to cancel."); return false; } HILOGI("tyx::CheckCancelIfNeed need cancel."); OnCancel(path); return true; } + +void TaskSignal::MarkRemoteTask() +{ + HILOGI("tyx::MarkRemoteTask in."); + remoteTask_.store(true); +} + +void TaskSignal::SetSessionIdOfRemoteTask(int32_t sessionId) +{ + HILOGI("tyx::SetSessionIdOfRemoteTask in, sessionId = %{public}d", sessionId); + sessionId_ = sessionId; +} } } // namespace DistributedFS } // namespace OHOS diff --git a/interfaces/kits/native/task_signal/task_signal.h b/interfaces/kits/native/task_signal/task_signal.h index 34b80977e..8d0a230c0 100644 --- a/interfaces/kits/native/task_signal/task_signal.h +++ b/interfaces/kits/native/task_signal/task_signal.h @@ -28,13 +28,16 @@ class TaskSignal { public: TaskSignal(); ~TaskSignal(); - void Cancel(); + int32_t Cancel(); bool IsCanceled(); - void SetCancelListener(); bool CheckCancelIfNeed(const std::string &path); void OnCancel(const std::string &path); void SetTaskSignalListener(std::shared_ptr signalListener); + void MarkRemoteTask(); + void SetSessionIdOfRemoteTask(int32_t sessionId); std::atomic_bool needCancel_{ false }; + std::atomic_bool remoteTask_{ false }; + int32_t sessionId_ = -1; private: std::shared_ptr signalListener_; diff --git a/utils/filemgmt_libn/src/n_async/n_ref.cpp b/utils/filemgmt_libn/src/n_async/n_ref.cpp index 300cefafc..bd5ebc900 100644 --- a/utils/filemgmt_libn/src/n_async/n_ref.cpp +++ b/utils/filemgmt_libn/src/n_async/n_ref.cpp @@ -15,8 +15,6 @@ #include "n_ref.h" -#include "filemgmt_libhilog.h" - namespace OHOS { namespace FileManagement { namespace LibN { -- Gitee From 5b25b12a202ce0f4d5304f55866f405889153048 Mon Sep 17 00:00:00 2001 From: Hollokin Date: Wed, 24 Jan 2024 09:54:24 +0800 Subject: [PATCH 08/11] =?UTF-8?q?=E6=B7=BB=E5=8A=A0TDD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Hollokin --- .../task_signal_n_exporter.cpp | 6 +- .../kits/js/src/mod_fs/properties/copy.cpp | 17 +-- .../kits/js/src/mod_fs/properties/copy.h | 1 - interfaces/test/unittest/BUILD.gn | 1 + interfaces/test/unittest/task_signal/BUILD.gn | 42 ++++++ .../unittest/task_signal/task_signal_test.cpp | 138 ++++++++++++++++++ 6 files changed, 184 insertions(+), 21 deletions(-) create mode 100644 interfaces/test/unittest/task_signal/BUILD.gn create mode 100644 interfaces/test/unittest/task_signal/task_signal_test.cpp diff --git a/interfaces/kits/js/src/mod_fs/class_tasksignal/task_signal_n_exporter.cpp b/interfaces/kits/js/src/mod_fs/class_tasksignal/task_signal_n_exporter.cpp index 8d24883d5..0791e185d 100644 --- a/interfaces/kits/js/src/mod_fs/class_tasksignal/task_signal_n_exporter.cpp +++ b/interfaces/kits/js/src/mod_fs/class_tasksignal/task_signal_n_exporter.cpp @@ -49,7 +49,6 @@ napi_value TaskSignalNExporter::Constructor(napi_env env, napi_callback_info inf return nullptr; } taskSignalEntity->taskSignal = std::make_shared(); -// taskSignalEntity->taskSignal->SetTaskSignalListener(std::move(taskSignalEntity)); if (!NClass::SetEntityFor(env, funcArg.GetThisVar(), std::move(taskSignalEntity))) { HILOGE("Failed to set watcherEntity."); NError(EIO).ThrowErr(env); @@ -112,7 +111,7 @@ napi_value TaskSignalNExporter::OnCancel(napi_env env, napi_callback_info info) NError(EINVAL).ThrowErr(env); return nullptr; } - auto taskSignalEntity = NClass::GetEntityOf(env, funcArg.GetThisVar()); // todo entity是否应该是当前类的成员属性??这个不能是单例的 + auto taskSignalEntity = NClass::GetEntityOf(env, funcArg.GetThisVar()); if (!taskSignalEntity) { HILOGE("Failed to get watcherEntity when stop."); NError(EINVAL).ThrowErr(env); @@ -120,9 +119,8 @@ napi_value TaskSignalNExporter::OnCancel(napi_env env, napi_callback_info info) } std::shared_ptr signal(taskSignalEntity); taskSignalEntity->taskSignal->SetTaskSignalListener(signal); - auto callbackContext = std::make_shared(NVal(env, funcArg[0])); // todo 这里需要换成裸指针不? + auto callbackContext = std::make_shared(NVal(env, funcArg[0])); callbackContext->env_ = env; - // todo 需要再SetEntity进去? taskSignalEntity->callbackContext = callbackContext; napi_value result = nullptr; napi_get_null(env, &result); diff --git a/interfaces/kits/js/src/mod_fs/properties/copy.cpp b/interfaces/kits/js/src/mod_fs/properties/copy.cpp index fbb41861a..5f832c404 100644 --- a/interfaces/kits/js/src/mod_fs/properties/copy.cpp +++ b/interfaces/kits/js/src/mod_fs/properties/copy.cpp @@ -185,7 +185,6 @@ int Copy::SendFile(const string &src, const string &dest, std::shared_ptr= COPY_CHECKPOINT_BYTES时, if (infos != nullptr && infos->taskSignal != nullptr) { HILOGI("tyx::ready to CheckCancelIfNeed."); infos->taskSignal->CheckCancelIfNeed(src); @@ -209,19 +208,6 @@ int Copy::SendFile(const string &src, const string &dest, std::shared_ptrfilePaths.insert(dest); auto res = SendFile(src, dest, infos); -// auto res = CopyFile(src, dest); if (res != ERRNO_NOERR) { return res; } @@ -762,7 +747,7 @@ int Copy::ParseJsParam(napi_env env, NFuncArg &funcArg, std::shared_ptr infos); static tuple GetFileSize(const std::string &path); static uint64_t GetDirSize(std::shared_ptr infos, std::string path); - static int CopyFile(const string &src, const string &dest); static int SendFile(const string &src, const string &dest, std::shared_ptr infos); static int MakeDir(const string &path); static int CopySubDir(const string &srcPath, const string &destPath, std::shared_ptr infos); diff --git a/interfaces/test/unittest/BUILD.gn b/interfaces/test/unittest/BUILD.gn index 341f35269..95f924b84 100644 --- a/interfaces/test/unittest/BUILD.gn +++ b/interfaces/test/unittest/BUILD.gn @@ -17,5 +17,6 @@ group("unittest") { "class_file:class_file_test", "filemgmt_libn_test:filemgmt_libn_test", "remote_uri:remote_uri_test", + "task_signal:task_signal_test", ] } diff --git a/interfaces/test/unittest/task_signal/BUILD.gn b/interfaces/test/unittest/task_signal/BUILD.gn new file mode 100644 index 000000000..710c41e77 --- /dev/null +++ b/interfaces/test/unittest/task_signal/BUILD.gn @@ -0,0 +1,42 @@ +# Copyright (c) 2024 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. + +import("//build/test.gni") +import("//foundation/filemanagement/file_api/file_api.gni") + +ohos_unittest("task_signal_test") { + module_out_path = "filemanagement/file_api" + + resource_config_file = "../resource/ohos_test.xml" + + sources = [ "task_signal_test.cpp" ] + + include_dirs = [ + "include", + "${file_api_path}/interfaces/kits/native/task_signal", + ] + + deps = [ + "${file_api_path}/interfaces/kits/native:task_signal_native", + "//third_party/googletest:gtest_main", + "${utils_path}/filemgmt_libhilog:filemgmt_libhilog" + ] + + external_deps = [ + #"access_token:libaccesstoken_sdk", + "c_utils:utils", + "hilog:libhilog", + #"c_utils:utilsbase", + #"ipc:ipc_core", + ] +} diff --git a/interfaces/test/unittest/task_signal/task_signal_test.cpp b/interfaces/test/unittest/task_signal/task_signal_test.cpp new file mode 100644 index 000000000..5fc194d3a --- /dev/null +++ b/interfaces/test/unittest/task_signal/task_signal_test.cpp @@ -0,0 +1,138 @@ +/* + * Copyright (c) 2024 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 "task_signal.h" + +#include +#include +#include +#include + +#include "filemgmt_libhilog.h" +#include "task_signal_listener.h" + +namespace OHOS { +namespace DistributedFS { +using namespace std; +using namespace OHOS::DistributedFS::ModuleTaskSignal; +using namespace FileManagement; +constexpr uint32_t DEALY_TIME = 1; + +class TaskSignalTest : public testing::Test { +public: + static void SetUpTestCase(void){}; + static void TearDownTestCase(){}; + void SetUp(){}; + void TearDown(){}; + + static std::condition_variable taskListenerCv_; + static std::mutex taskListenerCallbackLock_; + static std::string canceledFilePath_; +}; + +std::condition_variable TaskSignalTest::taskListenerCv_; +std::mutex TaskSignalTest::taskListenerCallbackLock_; +std::string TaskSignalTest::canceledFilePath_; + +class TaskSignalListenerTestImpl : public TaskSignalListener { +public: + ~TaskSignalListenerTestImpl() = default; + void OnCancel(const std::string &path) + { + TaskSignalTest::canceledFilePath_ = path; + TaskSignalTest::taskListenerCv_.notify_one(); + HILOGI("tyx::OnCancel in. path = %{public}s", path.c_str()); + } +}; + +/** + * @tc.name: Task_Signal_Cancel_0000 + * @tc.desc: Test function of Cancel() interface for SUCCESS. + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + * @tc.require: NAN + */ +HWTEST_F(TaskSignalTest, Task_Signal_Cancel_0000, testing::ext::TestSize.Level1) +{ + GTEST_LOG_(INFO) << "TaskSignalTest-begin Task_Signal_Cancel_0000"; + auto signal = std::make_shared(); + auto ret = signal->Cancel(); + EXPECT_TRUE(ret == 0); +} + +/** + * @tc.name: Task_Signal_IsCancel_0000 + * @tc.desc: Test function of IsCanceled() interface + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + * @tc.require: NAN + */ +HWTEST_F(TaskSignalTest, Task_Signal_IsCancel_0000, testing::ext::TestSize.Level1) +{ + GTEST_LOG_(INFO) << "TaskSignalTest-begin Task_Signal_IsCancel_0000"; + auto signal = std::make_shared(); + auto isCanceled = signal->IsCanceled(); + EXPECT_TRUE(!isCanceled); + + auto ret = signal->Cancel(); + EXPECT_TRUE(ret == 0); + isCanceled = signal->IsCanceled(); + EXPECT_TRUE(isCanceled); +} + +/** + * @tc.name: Task_Signal_SetTaskSignalListener_0000 + * @tc.desc: Test function of SetTaskSignalListener() interface for SUCCESS. + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + * @tc.require: NAN + */ +HWTEST_F(TaskSignalTest, Task_Signal_SetTaskSignalListener_0000, testing::ext::TestSize.Level1) +{ + GTEST_LOG_(INFO) << "TaskSignalTest-begin Task_Signal_SetTaskSignalListener_0000"; + std::unique_lock lock(TaskSignalTest::taskListenerCallbackLock_); + auto signal = std::make_shared(); + auto listener = std::make_shared(); + signal->SetTaskSignalListener(listener); + std::string filePath = "aaa"; + signal->CheckCancelIfNeed(filePath); + auto cvStatus = taskListenerCv_.wait_for(lock, std::chrono::seconds(DEALY_TIME)); + EXPECT_NE(cvStatus, std::cv_status::timeout); + EXPECT_EQ(TaskSignalTest::canceledFilePath_, filePath); +} + +/** + * @tc.name: Task_Signal_MarkRemoteTask_0000 + * @tc.desc: Test function of SetTaskSignalListener() interface for SUCCESS. + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + * @tc.require: NAN + */ +HWTEST_F(TaskSignalTest, Task_Signal_MarkRemoteTask_0000, testing::ext::TestSize.Level1) +{ + GTEST_LOG_(INFO) << "TaskSignalTest-begin Task_Signal_MarkRemoteTask_0000"; + auto signal = std::make_shared(); + signal->MarkRemoteTask(); + int sessionId = 10; + signal->SetSessionIdOfRemoteTask(sessionId); + auto ret = signal->Cancel(); + EXPECT_EQ(ret, -1); +} +} // namespace DistributedFS +} // namespace OHOS \ No newline at end of file -- Gitee From 0f5a74c0276a529fb5063ba570f55c57849df819 Mon Sep 17 00:00:00 2001 From: Hollokin Date: Wed, 24 Jan 2024 10:49:25 +0800 Subject: [PATCH 09/11] =?UTF-8?q?=E6=8B=B7=E8=B4=9D=E6=88=90=E5=8A=9F?= =?UTF-8?q?=EF=BC=8C=E5=8F=96=E6=B6=88=E6=8B=B7=E8=B4=9D=E5=9B=9E=E8=B0=83?= =?UTF-8?q?=E6=88=90=E5=8A=9F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Hollokin --- .../task_signal_n_exporter.cpp | 2 +- .../kits/js/src/mod_fs/properties/copy.cpp | 23 +++++++++++++++---- .../kits/native/task_signal/task_signal.cpp | 2 +- 3 files changed, 21 insertions(+), 6 deletions(-) diff --git a/interfaces/kits/js/src/mod_fs/class_tasksignal/task_signal_n_exporter.cpp b/interfaces/kits/js/src/mod_fs/class_tasksignal/task_signal_n_exporter.cpp index 0791e185d..e8b2e4283 100644 --- a/interfaces/kits/js/src/mod_fs/class_tasksignal/task_signal_n_exporter.cpp +++ b/interfaces/kits/js/src/mod_fs/class_tasksignal/task_signal_n_exporter.cpp @@ -74,7 +74,7 @@ bool TaskSignalNExporter::Export() } succ = NClass::SaveClass(exports_.env_, className, classValue); - HILOGI("tyx::TaskSignalNExporter::SaveClass end, className = %{public}s.", className.c_str()); +// HILOGI("tyx::TaskSignalNExporter::SaveClass end, className = %{public}s.", className.c_str()); if (!succ) { HILOGE("Failed to SaveClass"); NError(EIO).ThrowErr(exports_.env_); diff --git a/interfaces/kits/js/src/mod_fs/properties/copy.cpp b/interfaces/kits/js/src/mod_fs/properties/copy.cpp index 5f832c404..11c6e3654 100644 --- a/interfaces/kits/js/src/mod_fs/properties/copy.cpp +++ b/interfaces/kits/js/src/mod_fs/properties/copy.cpp @@ -102,7 +102,7 @@ tuple Copy::GetCopySignalFromOptionArg(napi_env env, const NFuncArg HILOGE("tyx::Illegal options.progressListener type"); return { false, NVal() }; } - HILOGI("tyx::op.GetProp(\"copySignal\").TypeIs(napi_object)"); +// HILOGI("tyx::op.GetProp(\"copySignal\").TypeIs(napi_object)"); return { true, op.GetProp("copySignal") }; } else { HILOGE("tyx::copySignal TypeIs napi_undefined"); @@ -190,14 +190,25 @@ int Copy::SendFile(const string &src, const string &dest, std::shared_ptrtaskSignal->CheckCancelIfNeed(src); } } else { - HILOGI("tyx::start to sendfile."); - while ((ret = sendfile(ofd.GetFD(), sfd.GetFD(), nullptr, COPY_CHECKPOINT_BYTES)) != -1) { + HILOGI("tyx::start to sendfile.infos != nullptr: %{public}d, infos->taskSignal != nullptr: %{public}d", + infos != nullptr, infos->taskSignal != nullptr); + off_t offset = 0; + while ((ret = sendfile(ofd.GetFD(), sfd.GetFD(), &offset, COPY_CHECKPOINT_BYTES)) != -1) { +// HILOGI("tyx::sendfile."); if (infos != nullptr && infos->taskSignal != nullptr) { if (infos->taskSignal->CheckCancelIfNeed(src)) { HILOGI("tyx::task was canceled, clear something, Operation canceled."); return ECANCELED; } } + if (ret == 0) { + if (offset < fileSize) { + HILOGI("tyx::sendfile end, ret = %{public}d", ret); + return EIO; + } + return ERRNO_NOERR; + } + offset += ret; } HILOGI("tyx::sendfile end, ret = %{public}d", ret); if (ret == -1) { @@ -704,15 +715,19 @@ tuple> Copy::CreateFileInfos( infos->hasListener = true; } HILOGI("tyx::GetEntityOf TaskSignalEntity before."); - if (!infos->copySignal) { + if (infos->copySignal) { + HILOGI("tyx:copySignal is exist."); auto taskSignalEntity = NClass::GetEntityOf(infos->env, infos->copySignal.val_); if (taskSignalEntity != nullptr) { infos->taskSignal = taskSignalEntity->taskSignal; if (infos->taskSignal == nullptr) { HILOGE("tyx::infos->taskSignal == nullptr."); + } else { + HILOGI("tyx::infos->taskSignal != nullptr."); } } } + HILOGE("tyx:copySignal is not exist."); return { ERRNO_NOERR, infos }; } diff --git a/interfaces/kits/native/task_signal/task_signal.cpp b/interfaces/kits/native/task_signal/task_signal.cpp index c3394d2dc..ad00ea0e3 100644 --- a/interfaces/kits/native/task_signal/task_signal.cpp +++ b/interfaces/kits/native/task_signal/task_signal.cpp @@ -74,7 +74,7 @@ void TaskSignal::OnCancel(const std::string &path) bool TaskSignal::CheckCancelIfNeed(const std::string &path) { if (!needCancel_.load()) { - HILOGI("tyx::do not need to cancel."); +// HILOGI("tyx::do not need to cancel."); return false; } HILOGI("tyx::CheckCancelIfNeed need cancel."); -- Gitee From c6c1e9de18525a37d1c8eba2e7068a72c937f391 Mon Sep 17 00:00:00 2001 From: Hollokin Date: Wed, 24 Jan 2024 14:30:03 +0800 Subject: [PATCH 10/11] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E6=8B=B7=E8=B4=9D?= =?UTF-8?q?=E7=9B=AE=E5=BD=95=E5=A4=B1=E8=B4=A5=E7=9A=84=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Hollokin --- .../class_tasksignal/task_signal_entity.cpp | 36 +++------- .../class_tasksignal/task_signal_entity.h | 18 ++--- .../task_signal_n_exporter.cpp | 18 +++-- .../class_tasksignal/task_signal_n_exporter.h | 4 -- .../kits/js/src/mod_fs/properties/copy.cpp | 69 ++++++++----------- .../kits/js/src/mod_fs/properties/copy.h | 3 +- .../kits/native/task_signal/task_signal.cpp | 29 +++----- .../kits/native/task_signal/task_signal.h | 4 +- utils/filemgmt_libn/include/n_error.h | 11 ++- 9 files changed, 80 insertions(+), 112 deletions(-) diff --git a/interfaces/kits/js/src/mod_fs/class_tasksignal/task_signal_entity.cpp b/interfaces/kits/js/src/mod_fs/class_tasksignal/task_signal_entity.cpp index f2660b6ca..aeb23baf0 100644 --- a/interfaces/kits/js/src/mod_fs/class_tasksignal/task_signal_entity.cpp +++ b/interfaces/kits/js/src/mod_fs/class_tasksignal/task_signal_entity.cpp @@ -13,57 +13,43 @@ * limitations under the License. */ -#include - #include "task_signal_entity.h" +#include namespace OHOS::FileManagement::ModuleFileIO { -TaskSignalEntity::TaskSignalEntity() -{ - HILOGE("tyx::TaskSignalEntity()"); -} - -TaskSignalEntity::~TaskSignalEntity() -{ - HILOGE("tyx::~TaskSignalEntity()"); -} +TaskSignalEntity::~TaskSignalEntity() {} void TaskSignalEntity::OnCancel(const std::string &path) { - HILOGI("tyx::OnCancel run in. path = %{public}s", path.c_str()); + HILOGI("OnCancel run in. path = %{public}s", path.c_str()); uv_loop_s *loop = nullptr; if (!callbackContext) { - HILOGE("tyx::Failed to get callback context."); + HILOGE("Failed to get callback context."); return; } auto env = callbackContext->env_; callbackContext->filePath = path; - HILOGI("tyx::callbackContext->filePath = path end."); napi_get_uv_event_loop(env, &loop); - HILOGI("tyx::napi_get_uv_event_loop end."); if (loop == nullptr) { - HILOGE("tyx::Failed to get uv event loop"); + HILOGE("Failed to get uv event loop"); return; } uv_work_t *work = new (std::nothrow) uv_work_t; if (work == nullptr) { - HILOGE("tyx::Failed to create uv_work_t pointer"); + HILOGE("Failed to create uv_work_t pointer"); return; } work->data = reinterpret_cast(callbackContext.get()); - HILOGI("tyx::work->data end."); uv_queue_work_with_qos( loop, work, [](uv_work_t *work) {}, [](uv_work_t *work, int status) { - HILOGI("tyx::uv_queue_work_with_qos in."); - JSCallbackContext *callbackContext = - reinterpret_cast(work->data); + JSCallbackContext *callbackContext = reinterpret_cast(work->data); if (callbackContext == nullptr) { - HILOGE("tyx::Failed to create context pointer"); + HILOGE("Failed to create context pointer"); return; } if (!callbackContext->ref_) { - HILOGE("tyx::Failed to get nref reference"); + HILOGE("Failed to get nref reference"); return; } napi_handle_scope scope = nullptr; @@ -74,7 +60,7 @@ void TaskSignalEntity::OnCancel(const std::string &path) } napi_env env = callbackContext->env_; napi_value jsCallback = callbackContext->ref_.Deref(env).val_; - napi_value filePath = LibN::NVal::CreateUTF8String(env, callbackContext->filePath).val_; + napi_value filePath = LibN::NVal::CreateUTF8String(env, callbackContext->filePath).val_; napi_value retVal = nullptr; ret = napi_call_function(env, nullptr, jsCallback, 1, &filePath, &retVal); if (ret != napi_ok) { @@ -87,4 +73,4 @@ void TaskSignalEntity::OnCancel(const std::string &path) }, uv_qos_user_initiated); } -} +} // namespace OHOS::FileManagement::ModuleFileIO diff --git a/interfaces/kits/js/src/mod_fs/class_tasksignal/task_signal_entity.h b/interfaces/kits/js/src/mod_fs/class_tasksignal/task_signal_entity.h index 9e3061542..6ceda7548 100644 --- a/interfaces/kits/js/src/mod_fs/class_tasksignal/task_signal_entity.h +++ b/interfaces/kits/js/src/mod_fs/class_tasksignal/task_signal_entity.h @@ -16,33 +16,25 @@ #ifndef FILEMANAGEMENT_FILE_API_TASK_SIGNAL_ENTITY_H #define FILEMANAGEMENT_FILE_API_TASK_SIGNAL_ENTITY_H -#include "task_signal.h" - #include "filemgmt_libn.h" +#include "task_signal.h" #include "task_signal_listener.h" namespace OHOS::FileManagement::ModuleFileIO { using namespace DistributedFS::ModuleTaskSignal; class JSCallbackContext { public: - explicit JSCallbackContext(LibN::NVal jsVal) : ref_(jsVal) { - HILOGE("tyx::JSCallbackContext()"); - } - - ~JSCallbackContext() { - HILOGE("tyx::~JSCallbackContext()"); - } + explicit JSCallbackContext(LibN::NVal jsVal) : ref_(jsVal) {} + ~JSCallbackContext() = default; napi_env env_; LibN::NRef ref_; std::string filePath; - uint32_t event_ = 0; - uint32_t cookie_ = 0; }; -class TaskSignalEntity: public TaskSignalListener { +class TaskSignalEntity : public TaskSignalListener { public: - TaskSignalEntity(); + TaskSignalEntity() = default; ~TaskSignalEntity() override; void OnCancel(const std::string &path) override; diff --git a/interfaces/kits/js/src/mod_fs/class_tasksignal/task_signal_n_exporter.cpp b/interfaces/kits/js/src/mod_fs/class_tasksignal/task_signal_n_exporter.cpp index e8b2e4283..1feb1bcff 100644 --- a/interfaces/kits/js/src/mod_fs/class_tasksignal/task_signal_n_exporter.cpp +++ b/interfaces/kits/js/src/mod_fs/class_tasksignal/task_signal_n_exporter.cpp @@ -15,14 +15,16 @@ #include "task_signal_n_exporter.h" +#include "file_utils.h" #include "task_signal.h" #include "task_signal_entity.h" -#include "file_utils.h" namespace OHOS::FileManagement::ModuleFileIO { using namespace std; using namespace OHOS::FileManagement::LibN; using namespace DistributedFS::ModuleTaskSignal; +constexpr int NO_ERROR = 0; +constexpr int CANCEL_ERR = -3; TaskSignalNExporter::TaskSignalNExporter(napi_env env, napi_value exports) : NExporter(env, exports) {} TaskSignalNExporter::~TaskSignalNExporter() {} @@ -34,7 +36,6 @@ string TaskSignalNExporter::GetClassName() napi_value TaskSignalNExporter::Constructor(napi_env env, napi_callback_info info) { - HILOGI("tyx::run in JsConstructor"); NFuncArg funcArg(env, info); if (!funcArg.InitArgs(NARG_CNT::ZERO)) { HILOGE("Failed to get param."); @@ -54,7 +55,6 @@ napi_value TaskSignalNExporter::Constructor(napi_env env, napi_callback_info inf NError(EIO).ThrowErr(env); return nullptr; } - HILOGI("tyx::JsConstructor end."); return funcArg.GetThisVar(); } @@ -74,7 +74,6 @@ bool TaskSignalNExporter::Export() } succ = NClass::SaveClass(exports_.env_, className, classValue); -// HILOGI("tyx::TaskSignalNExporter::SaveClass end, className = %{public}s.", className.c_str()); if (!succ) { HILOGE("Failed to SaveClass"); NError(EIO).ThrowErr(exports_.env_); @@ -98,13 +97,18 @@ napi_value TaskSignalNExporter::Cancel(napi_env env, napi_callback_info info) NError(EINVAL).ThrowErr(env); return nullptr; } - taskSignalEntity->taskSignal->Cancel(); + auto ret = taskSignalEntity->taskSignal->Cancel(); + if (ret != NO_ERROR) { + HILOGE("Failed to cancel the task."); + NError(CANCEL_ERR).ThrowErr(env); + return nullptr; + } return NVal::CreateUndefined(env).val_; } napi_value TaskSignalNExporter::OnCancel(napi_env env, napi_callback_info info) { - HILOGI("tyx::TaskSignalNExporter::OnCancel run."); + HILOGI("Run in."); NFuncArg funcArg(env, info); if (!funcArg.InitArgs(NARG_CNT::ONE)) { HILOGE("Failed to get param when stop."); @@ -126,4 +130,4 @@ napi_value TaskSignalNExporter::OnCancel(napi_env env, napi_callback_info info) napi_get_null(env, &result); return result; } -} +} // namespace OHOS::FileManagement::ModuleFileIO diff --git a/interfaces/kits/js/src/mod_fs/class_tasksignal/task_signal_n_exporter.h b/interfaces/kits/js/src/mod_fs/class_tasksignal/task_signal_n_exporter.h index f83123b46..b3bc50e0e 100644 --- a/interfaces/kits/js/src/mod_fs/class_tasksignal/task_signal_n_exporter.h +++ b/interfaces/kits/js/src/mod_fs/class_tasksignal/task_signal_n_exporter.h @@ -19,14 +19,12 @@ #include #include "filemgmt_libn.h" -//#include "task_signal_listener.h" #include "task_signal_entity.h" namespace OHOS::FileManagement::ModuleFileIO { class TaskSignalNExporter final : public LibN::NExporter { public: inline static const std::string className_ = "TaskSignal"; -// DistributedFS::ModuleTaskSignal::TaskSignal taskSignal_; bool Export() override; std::string GetClassName() override; @@ -34,11 +32,9 @@ public: static napi_value Constructor(napi_env env, napi_callback_info info); static napi_value Cancel(napi_env env, napi_callback_info info); static napi_value OnCancel(napi_env env, napi_callback_info info); -// void OnCancel(const std::string &path) override; TaskSignalNExporter(napi_env env, napi_value exports); ~TaskSignalNExporter() override; -// std::shared_ptr callbackContext_ = nullptr; }; } // namespace OHOS::FileManagement::ModuleFileIO diff --git a/interfaces/kits/js/src/mod_fs/properties/copy.cpp b/interfaces/kits/js/src/mod_fs/properties/copy.cpp index 11c6e3654..389b7937e 100644 --- a/interfaces/kits/js/src/mod_fs/properties/copy.cpp +++ b/interfaces/kits/js/src/mod_fs/properties/copy.cpp @@ -33,6 +33,8 @@ #include #include +#include "../../common/file_helper/fd_guard.h" +#include "../class_tasksignal/task_signal_n_exporter.h" #include "file_uri.h" #include "file_utils.h" #include "filemgmt_libhilog.h" @@ -40,8 +42,6 @@ #include "iservice_registry.h" #include "system_ability_definition.h" #include "trans_listener.h" -#include "../../common/file_helper/fd_guard.h" -#include "../class_tasksignal/task_signal_n_exporter.h" namespace OHOS { namespace FileManagement { @@ -102,7 +102,6 @@ tuple Copy::GetCopySignalFromOptionArg(napi_env env, const NFuncArg HILOGE("tyx::Illegal options.progressListener type"); return { false, NVal() }; } -// HILOGI("tyx::op.GetProp(\"copySignal\").TypeIs(napi_object)"); return { true, op.GetProp("copySignal") }; } else { HILOGE("tyx::copySignal TypeIs napi_undefined"); @@ -131,7 +130,8 @@ bool Copy::IsDirectory(const std::string &path) bool Copy::IsFile(const std::string &path) { - struct stat buf {}; + struct stat buf { + }; int ret = stat(path.c_str(), &buf); if (ret == -1) { HILOGI("stat failed, errno is %{public}d, ", errno); @@ -163,13 +163,13 @@ void Copy::CheckOrCreatePath(const std::string &destPath) int Copy::SendFile(const string &src, const string &dest, std::shared_ptr infos) { - HILOGI("tyx::SendFile in, src = %{public}s, dest = %{public}s", src.c_str(), dest.c_str()); + HILOGI("SendFile in, src = %{public}s, dest = %{public}s", src.c_str(), dest.c_str()); auto [err, fileSize] = GetFileSize(src); DistributedFS::FDGuard sfd; DistributedFS::FDGuard ofd; struct stat attrSrc; if (stat(src.c_str(), &attrSrc) == FAILED) { - HILOGE("tyx::stat failed, src = %{public}s, errno = %{public}d", src.c_str(), errno); + HILOGE("Stat failed, src = %{public}s, errno = %{public}d", src.c_str(), errno); return EIO; } sfd.SetFD(open(src.c_str(), O_RDONLY)); @@ -179,38 +179,34 @@ int Copy::SendFile(const string &src, const string &dest, std::shared_ptrtaskSignal != nullptr) { - HILOGI("tyx::ready to CheckCancelIfNeed."); infos->taskSignal->CheckCancelIfNeed(src); } } else { - HILOGI("tyx::start to sendfile.infos != nullptr: %{public}d, infos->taskSignal != nullptr: %{public}d", + HILOGI("Start to sendfile.infos != nullptr: %{public}d, infos->taskSignal != nullptr: %{public}d", infos != nullptr, infos->taskSignal != nullptr); off_t offset = 0; while ((ret = sendfile(ofd.GetFD(), sfd.GetFD(), &offset, COPY_CHECKPOINT_BYTES)) != -1) { -// HILOGI("tyx::sendfile."); if (infos != nullptr && infos->taskSignal != nullptr) { if (infos->taskSignal->CheckCancelIfNeed(src)) { - HILOGI("tyx::task was canceled, clear something, Operation canceled."); + HILOGE("Task was canceled."); return ECANCELED; } } if (ret == 0) { if (offset < fileSize) { - HILOGI("tyx::sendfile end, ret = %{public}d", ret); + HILOGI("Sendfile end, ret = %{public}d", ret); return EIO; } return ERRNO_NOERR; } offset += ret; } - HILOGI("tyx::sendfile end, ret = %{public}d", ret); if (ret == -1) { remove(dest.c_str()); return EIO; @@ -300,13 +296,14 @@ uint64_t Copy::GetDirSize(std::shared_ptr infos, std::string path) continue; } if ((pNameList->namelist[i])->d_type == DT_DIR) { - return size += GetDirSize(infos, dest); - } - struct stat st {}; - if (stat(dest.c_str(), &st) == -1) { - return size; + size += GetDirSize(infos, dest); + } else { + struct stat st {}; + if (stat(dest.c_str(), &st) == -1) { + return size; + } + size += st.st_size; } - size += st.st_size; } return size; } @@ -328,12 +325,16 @@ int Copy::RecurCopyDir(const string &srcPath, const string &destPath, std::share continue; } if ((pNameList->namelist[i])->d_type == DT_DIR) { - return CopySubDir(src, dest, infos); - } - infos->filePaths.insert(dest); - auto res = SendFile(src, dest, infos); - if (res != ERRNO_NOERR) { - return res; + auto ret = CopySubDir(src, dest, infos); + if (ret != ERRNO_NOERR) { + return ret; + } + } else { + infos->filePaths.insert(dest); + auto res = SendFile(src, dest, infos); + if (res != ERRNO_NOERR) { + return res; + } } } return ERRNO_NOERR; @@ -361,7 +362,7 @@ int Copy::ExecLocal(std::shared_ptr infos, std::shared_ptrdestPath); } if (!infos->hasListener) { - HILOGI("tyx::has no progress listener.."); + HILOGI("No progress listener.."); return ExecCopy(infos); } auto ret = SubscribeLocalListener(infos, callback); @@ -373,8 +374,7 @@ int Copy::ExecLocal(std::shared_ptr infos, std::shared_ptr infos, - std::shared_ptr callback) +int Copy::SubscribeLocalListener(std::shared_ptr infos, std::shared_ptr callback) { infos->notifyFd = inotify_init(); if (infos->notifyFd < 0) { @@ -430,7 +430,7 @@ std::shared_ptr Copy::RegisterListener(napi_env env, const std return nullptr; } jsCbMap_.insert({ *infos, callback }); - HILOGI("tyx::RegisterListener end."); + HILOGD("RegisterListener end."); return callback; } @@ -505,7 +505,6 @@ uv_work_t *Copy::GetUVwork(std::shared_ptr infos) return nullptr; } auto callback = iter->second; -// infos->env = callback->env; entry = new (std::nothrow) UvEntry(iter->second, infos); if (entry == nullptr) { HILOGE("entry ptr is nullptr."); @@ -714,20 +713,13 @@ tuple> Copy::CreateFileInfos( if (listener) { infos->hasListener = true; } - HILOGI("tyx::GetEntityOf TaskSignalEntity before."); if (infos->copySignal) { - HILOGI("tyx:copySignal is exist."); + HILOGI("Has copySignal."); auto taskSignalEntity = NClass::GetEntityOf(infos->env, infos->copySignal.val_); if (taskSignalEntity != nullptr) { infos->taskSignal = taskSignalEntity->taskSignal; - if (infos->taskSignal == nullptr) { - HILOGE("tyx::infos->taskSignal == nullptr."); - } else { - HILOGI("tyx::infos->taskSignal != nullptr."); - } } } - HILOGE("tyx:copySignal is not exist."); return { ERRNO_NOERR, infos }; } @@ -817,7 +809,6 @@ napi_value Copy::Async(napi_env env, napi_callback_info info) return ret; } auto result = Copy::ExecLocal(infos, callback); - HILOGE("tyx::ExecLocal end."); CloseNotifyFd(infos, callback); infos->run = false; WaitNotifyFinished(callback); diff --git a/interfaces/kits/js/src/mod_fs/properties/copy.h b/interfaces/kits/js/src/mod_fs/properties/copy.h index 32b21d894..c93ebd3cf 100644 --- a/interfaces/kits/js/src/mod_fs/properties/copy.h +++ b/interfaces/kits/js/src/mod_fs/properties/copy.h @@ -85,9 +85,8 @@ struct FileInfos { bool hasListener = false; napi_env env; NVal listener; - NVal copySignal; // todo 这个删掉 + NVal copySignal; int32_t sessionId = -1; -// NRef copySignalRef; std::shared_ptr taskSignal = nullptr; std::set filePaths; long checkPoint = 0; diff --git a/interfaces/kits/native/task_signal/task_signal.cpp b/interfaces/kits/native/task_signal/task_signal.cpp index ad00ea0e3..a76e6e78c 100644 --- a/interfaces/kits/native/task_signal/task_signal.cpp +++ b/interfaces/kits/native/task_signal/task_signal.cpp @@ -22,26 +22,17 @@ namespace OHOS { namespace DistributedFS { namespace ModuleTaskSignal { using namespace FileManagement; -TaskSignal::TaskSignal() -{ - HILOGI("tyx::constructor of TaskSignal in."); -} - -TaskSignal::~TaskSignal() -{ - HILOGI("tyx::destructor of TaskSignal in."); -} int32_t TaskSignal::Cancel() { - HILOGI("tyx::Cancel in."); + HILOGI("Cancel in."); if (remoteTask_.load()) { if (sessionId_ == -1) { return -1; // 取消拷贝失败的错误码 } auto ret = Storage::DistributedFile::DistributedFileDaemonManager::GetInstance().CancelCopyTask(sessionId_); if (ret != 0) { // 取消拷贝失败 - HILOGI("tyx::Cancel in.CancelCopyTask failed, ret = %{public}d", ret); + HILOGI("CancelCopyTask failed, ret = %{public}d", ret); } return ret; } @@ -56,7 +47,7 @@ bool TaskSignal::IsCanceled() void TaskSignal::SetTaskSignalListener(std::shared_ptr signalListener) { - HILOGI("tyx::SetTaskSignalListener in."); + HILOGI("SetTaskSignalListener in."); if (signalListener_ == nullptr) { signalListener_ = move(signalListener); } @@ -64,9 +55,9 @@ void TaskSignal::SetTaskSignalListener(std::shared_ptr signa void TaskSignal::OnCancel(const std::string &path) { - HILOGI("tyx::OnCancel in."); + HILOGI("OnCancel in."); if (signalListener_ != nullptr) { - HILOGI("tyx::OnCancel signalListener_ != nullptr."); + HILOGI("OnCancel signalListener_ != nullptr."); signalListener_->OnCancel(path); } } @@ -74,25 +65,25 @@ void TaskSignal::OnCancel(const std::string &path) bool TaskSignal::CheckCancelIfNeed(const std::string &path) { if (!needCancel_.load()) { -// HILOGI("tyx::do not need to cancel."); + HILOGI("Do not need to cancel."); return false; } - HILOGI("tyx::CheckCancelIfNeed need cancel."); + HILOGI("CheckCancelIfNeed need cancel."); OnCancel(path); return true; } void TaskSignal::MarkRemoteTask() { - HILOGI("tyx::MarkRemoteTask in."); + HILOGI("MarkRemoteTask in."); remoteTask_.store(true); } void TaskSignal::SetSessionIdOfRemoteTask(int32_t sessionId) { - HILOGI("tyx::SetSessionIdOfRemoteTask in, sessionId = %{public}d", sessionId); + HILOGI("SetSessionIdOfRemoteTask in, sessionId = %{public}d", sessionId); sessionId_ = sessionId; } -} +} // namespace ModuleTaskSignal } // namespace DistributedFS } // namespace OHOS diff --git a/interfaces/kits/native/task_signal/task_signal.h b/interfaces/kits/native/task_signal/task_signal.h index 8d0a230c0..e7307cec4 100644 --- a/interfaces/kits/native/task_signal/task_signal.h +++ b/interfaces/kits/native/task_signal/task_signal.h @@ -26,8 +26,8 @@ namespace DistributedFS { namespace ModuleTaskSignal { class TaskSignal { public: - TaskSignal(); - ~TaskSignal(); + TaskSignal() = default; + ~TaskSignal() = default; int32_t Cancel(); bool IsCanceled(); bool CheckCancelIfNeed(const std::string &path); diff --git a/utils/filemgmt_libn/include/n_error.h b/utils/filemgmt_libn/include/n_error.h index a82c07111..c25b1968b 100644 --- a/utils/filemgmt_libn/include/n_error.h +++ b/utils/filemgmt_libn/include/n_error.h @@ -36,6 +36,8 @@ constexpr int ERESTART = 85; constexpr int EDQUOT = 122; #endif constexpr int UNKROWN_ERR = -1; +constexpr int NO_TASK_ERR = -2; +constexpr int CANCEL_ERR = -3; constexpr int ERRNO_NOERR = 0; constexpr int STORAGE_SERVICE_SYS_CAP_TAG = 13600000; constexpr int FILEIO_SYS_CAP_TAG = 13900000; @@ -88,7 +90,10 @@ enum ErrCodeSuffixOfFileIO { E_RESTART, E_DQUOT, E_UKERR, - E_NOLCK + E_NOLCK, + E_NOTASK, + E_UNCANCELED, + E_CANCELED, }; enum ErrCodeSuffixOfUserFileManager { @@ -195,6 +200,7 @@ static inline std::unordered_map uvCode2ErrCodeTable { { "EBADFD", EBADFD }, { "ERESTART", ERESTART }, { "EDQUOT", EDQUOT }, + { "ECANCELED", ECANCELED }, }; static inline std::unordered_map> errCodeTable { @@ -241,6 +247,9 @@ static inline std::unordered_map> errCodeTa { ERESTART, { FILEIO_SYS_CAP_TAG + E_RESTART, "Interrupted system call should be restarted" } }, { EDQUOT, { FILEIO_SYS_CAP_TAG + E_DQUOT, "Quota exceeded" } }, { UNKROWN_ERR, { FILEIO_SYS_CAP_TAG + E_UKERR, "Unknown error" } }, + { NO_TASK_ERR, { FILEIO_SYS_CAP_TAG + E_NOTASK, "No task can be canceled" } }, + { CANCEL_ERR, { FILEIO_SYS_CAP_TAG + E_UNCANCELED, "Failed to cancel" } }, + { ECANCELED, { FILEIO_SYS_CAP_TAG + E_CANCELED, "Operation canceled" } }, { ENOLCK, { FILEIO_SYS_CAP_TAG + E_NOLCK, "No record locks available" } }, { FILEIO_SYS_CAP_TAG + E_PERM, { FILEIO_SYS_CAP_TAG + E_PERM, "Operation not permitted" } }, { FILEIO_SYS_CAP_TAG + E_NOENT, { FILEIO_SYS_CAP_TAG + E_NOENT, "No such file or directory" } }, -- Gitee From 878af2d28b3c76d632042f8b4b89bf5df3dcc7aa Mon Sep 17 00:00:00 2001 From: Hollokin Date: Wed, 24 Jan 2024 20:01:44 +0800 Subject: [PATCH 11/11] =?UTF-8?q?=E5=8E=BB=E6=8E=89=E5=A4=9A=E4=BD=99?= =?UTF-8?q?=E6=97=A5=E5=BF=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Hollokin --- .../kits/js/src/mod_fs/properties/copy.cpp | 118 +++++++++--------- 1 file changed, 60 insertions(+), 58 deletions(-) diff --git a/interfaces/kits/js/src/mod_fs/properties/copy.cpp b/interfaces/kits/js/src/mod_fs/properties/copy.cpp index 3433de1d5..f7e757d22 100644 --- a/interfaces/kits/js/src/mod_fs/properties/copy.cpp +++ b/interfaces/kits/js/src/mod_fs/properties/copy.cpp @@ -94,16 +94,12 @@ tuple Copy::GetCopySignalFromOptionArg(napi_env env, const NFuncArg { if (funcArg.GetArgc() >= NARG_CNT::THREE) { NVal op(env, funcArg[NARG_POS::THIRD]); - if (op.HasProp("copySignal")) { - if (op.HasProp("copySignal") && !op.GetProp("copySignal").TypeIs(napi_undefined)) { - if (!op.GetProp("copySignal").TypeIs(napi_object)) { - HILOGE("tyx::Illegal options.progressListener type"); - return { false, NVal() }; - } - return { true, op.GetProp("copySignal") }; - } else { - HILOGE("tyx::copySignal TypeIs napi_undefined"); + if (op.HasProp("copySignal") && !op.GetProp("copySignal").TypeIs(napi_undefined)) { + if (!op.GetProp("copySignal").TypeIs(napi_object)) { + HILOGE("Illegal options.progressListener type"); + return { false, NVal() }; } + return { true, op.GetProp("copySignal") }; } } return { true, NVal() }; @@ -128,8 +124,7 @@ bool Copy::IsDirectory(const std::string &path) bool Copy::IsFile(const std::string &path) { - struct stat buf { - }; + struct stat buf {}; int ret = stat(path.c_str(), &buf); if (ret == -1) { HILOGI("stat failed, errno is %{public}d, ", errno); @@ -164,46 +159,55 @@ void Copy::CheckOrCreatePath(const std::string &destPath) int Copy::SendFile(const string &src, const string &dest, std::shared_ptr infos) { HILOGD("src = %{public}s, dest = %{public}s", src.c_str(), dest.c_str()); - auto srcFd = open(src.c_str(), O_RDONLY); - auto destFd = open(dest.c_str(), O_RDWR | O_CREAT, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP); - if (srcFd < 0 || destFd < 0) { - HILOGE("Error opening file descriptor. errno = %{public}d", errno); - close(srcFd); - close(destFd); - return errno; - } - auto srcFdg = CreateUniquePtr(srcFd, true); - auto destFdg = CreateUniquePtr(destFd, true); - std::unique_ptr sendFileReq = { - new (nothrow) uv_fs_t, CommonFunc::fs_req_cleanup }; - if (sendFileReq == nullptr) { - HILOGE("Failed to request heap memory."); - return ENOMEM; - } - int64_t offset = 0; - struct stat srcStat{}; - if (fstat(srcFdg->GetFD(), &srcStat) < 0) { - HILOGE("Failed to get stat of file by fd: %{public}d ,errno = %{public}d", srcFdg->GetFD(), errno); - return errno; - } - int64_t size = static_cast(srcStat.st_size); - int ret = 0; - while (size > 0) { - ret = uv_fs_sendfile(nullptr, sendFileReq.get(), destFdg->GetFD(), srcFdg->GetFD(), - offset, MAX_SIZE, nullptr); - if (ret < 0) { - HILOGE("Failed to sendfile by errno : %{public}d", errno); - return errno; + DistributedFS::FDGuard sfd; + DistributedFS::FDGuard ofd; + struct stat attrSrc; + if (stat(src.c_str(), &attrSrc) == FAILED) { + HILOGE("Stat failed, src = %{public}s, errno = %{public}d", src.c_str(), errno); + return EIO; + } + sfd.SetFD(open(src.c_str(), O_RDONLY)); + ofd.SetFD(open(dest.c_str(), O_WRONLY | O_CREAT, attrSrc.st_mode)); + if (sfd.GetFD() == FAILED || ofd.GetFD() == FAILED) { + return EIO; + } + int ret = EIO; + auto fileSize = attrSrc.st_size; + if (fileSize <= COPY_CHECKPOINT_BYTES) { + if (sendfile(ofd.GetFD(), sfd.GetFD(), nullptr, fileSize) == -1) { + HILOGE("Sendfile failed, errno = %{public}d", errno); + remove(dest.c_str()); + return EIO; } - offset += static_cast(ret); - size -= static_cast(ret); - if (ret == 0) { - break; + if (infos != nullptr && infos->taskSignal != nullptr) { + if (infos->taskSignal->CheckCancelIfNeed(src)) { + HILOGE("Operation canceled."); + return ECANCELED; + } + } + } else { + HILOGI("Start to sendfile.infos != nullptr: %{public}d, infos->taskSignal != nullptr: %{public}d", + infos != nullptr, infos->taskSignal != nullptr); + off_t offset = 0; + while ((ret = sendfile(ofd.GetFD(), sfd.GetFD(), &offset, COPY_CHECKPOINT_BYTES)) != -1) { + if (infos != nullptr && infos->taskSignal != nullptr) { + if (infos->taskSignal->CheckCancelIfNeed(src)) { + HILOGE("Operation canceled."); + return ECANCELED; + } + } + if (ret == 0) { + if (offset < fileSize) { + return EIO; + } + return ERRNO_NOERR; + } + offset += ret; + } + if (ret == -1) { + remove(dest.c_str()); + return EIO; } - } - if (size != 0) { - HILOGE("The execution of the sendfile task was terminated, remaining file size %{public}" PRIu64, size); - return E_IO; } return ERRNO_NOERR; } @@ -317,17 +321,15 @@ int Copy::RecurCopyDir(const string &srcPath, const string &destPath, std::share if ((pNameList->namelist[i])->d_type == DT_LNK) { continue; } + int ret = ERRNO_NOERR; if ((pNameList->namelist[i])->d_type == DT_DIR) { - auto ret = CopySubDir(src, dest, infos); - if (ret != ERRNO_NOERR) { - return ret; - } + ret = CopySubDir(src, dest, infos); } else { infos->filePaths.insert(dest); - auto res = SendFile(src, dest, infos); - if (res != ERRNO_NOERR) { - return res; - } + ret = SendFile(src, dest, infos); + } + if (ret != ERRNO_NOERR) { + return ret; } } return ERRNO_NOERR; @@ -526,7 +528,7 @@ void Copy::OnFileReceive(std::shared_ptr infos) uv_loop_s *loop = nullptr; napi_status status = napi_get_uv_event_loop(infos->env, &loop); if (status != napi_ok) { - HILOGE("tyx::Failed to get uv event loop, status = %{public}d", status); + HILOGE("Failed to get uv event loop, status = %{public}d", status); return; } uv_queue_work( -- Gitee