diff --git a/1.diff b/1.diff new file mode 100644 index 0000000000000000000000000000000000000000..3f69a25cc17680c7a38c08e1f8172e525df98dfd --- /dev/null +++ b/1.diff @@ -0,0 +1,341 @@ +From edb2ba303425d2964c48700570c12da1fb3a4217 Mon Sep 17 00:00:00 2001 +From: Wang Luyao +Date: Thu, 15 Aug 2024 02:29:29 +0800 +Subject: [PATCH] =?UTF-8?q?=E4=B8=BAstream=E6=B5=81=E5=8A=A0=E9=94=81?= + =?UTF-8?q?=E9=98=B2=E6=AD=A2crash?= +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Signed-off-by: Wang Luyao +--- + interfaces/kits/js/BUILD.gn | 1 + + .../kits/js/src/mod_fs/class_stream/flush.cpp | 15 +++- + .../src/mod_fs/class_stream/stream_entity.cpp | 43 ++++++++++ + .../src/mod_fs/class_stream/stream_entity.h | 8 ++ + .../mod_fs/class_stream/stream_n_exporter.cpp | 81 ++++++++++++++----- + .../mod_fs/class_stream/stream_n_exporter.h | 2 + + 6 files changed, 127 insertions(+), 23 deletions(-) + create mode 100644 interfaces/kits/js/src/mod_fs/class_stream/stream_entity.cpp + +diff --git a/interfaces/kits/js/BUILD.gn b/interfaces/kits/js/BUILD.gn +index c98a406b..2a2a8312 100644 +--- a/interfaces/kits/js/BUILD.gn ++++ b/interfaces/kits/js/BUILD.gn +@@ -216,6 +216,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_stream/stream_entity.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", +diff --git a/interfaces/kits/js/src/mod_fs/class_stream/flush.cpp b/interfaces/kits/js/src/mod_fs/class_stream/flush.cpp +index 105eab7b..35f7a033 100755 +--- a/interfaces/kits/js/src/mod_fs/class_stream/flush.cpp ++++ b/interfaces/kits/js/src/mod_fs/class_stream/flush.cpp +@@ -20,6 +20,7 @@ + #include "class_stat/stat_entity.h" + #include "class_stat/stat_n_exporter.h" + #include "filemgmt_libhilog.h" ++#include "n_error.h" + #include "stream_entity.h" + + namespace OHOS { +@@ -28,6 +29,16 @@ namespace ModuleFileIO { + using namespace std; + using namespace OHOS::FileManagement::LibN; + ++static int32_t FlushCore(StreamEntity *streamEntity) ++{ ++ int32_t ret = 0; ++ if (streamEntity->ExecuteStart()) { ++ ret = fflush(streamEntity->fp.get()); ++ streamEntity->ExecuteEnd(); ++ } ++ return ret; ++} ++ + napi_value Flush::Sync(napi_env env, napi_callback_info info) + { + NFuncArg funcArg(env, info); +@@ -43,8 +54,8 @@ napi_value Flush::Sync(napi_env env, napi_callback_info info) + NError(EIO).ThrowErr(env); + return nullptr; + } ++ int32_t ret = FlushCore(streamEntity); + +- int ret = fflush(streamEntity->fp.get()); + if (ret < 0) { + HILOGE("Failed to fflush file in the stream, ret: %{public}d", ret); + NError(errno).ThrowErr(env); +@@ -74,7 +85,7 @@ napi_value Flush::Async(napi_env env, napi_callback_info info) + HILOGE("Stream has been closed in flush cbExec possibly"); + return NError(EIO); + } +- int ret = fflush(streamEntity->fp.get()); ++ int32_t ret = FlushCore(streamEntity); + if (ret < 0) { + HILOGE("Failed to fflush file in the stream"); + return NError(errno); +diff --git a/interfaces/kits/js/src/mod_fs/class_stream/stream_entity.cpp b/interfaces/kits/js/src/mod_fs/class_stream/stream_entity.cpp +new file mode 100644 +index 00000000..ed8fb276 +--- /dev/null ++++ b/interfaces/kits/js/src/mod_fs/class_stream/stream_entity.cpp +@@ -0,0 +1,43 @@ ++#include "stream_entity.h" ++#include "filemgmt_libhilog.h" ++#include ++ ++namespace OHOS { ++namespace FileManagement { ++namespace ModuleFileIO { ++ StreamEntity::~StreamEntity() { ++ HILOGE("~StreamEntity"); ++ std::unique_lock lock(mutex); ++ if (count > 0) { ++ HILOGE("count is %{public}d", count); ++ cv.wait_for(lock, std::chrono::seconds(30), [&]() { ++ HILOGE("count is %{public}d", count); ++ return count == 0; ++ }); ++ } else { ++ HILOGE("count is 0"); ++ } ++ } ++ bool StreamEntity::ExecuteStart() { ++ std::lock_guard lock(mutex); ++ if (isClose) { ++ return false; ++ } ++ count++; ++ HILOGE("count is %{public}d", count); ++ return true; ++ } ++ ++ void StreamEntity::ExecuteEnd() { ++ std::lock_guard lock(mutex); ++ count--; ++ HILOGE("count is %{public}d", count); ++ if (count == 0 && isClose) { ++ fp.reset(); ++ HILOGE("count is 0, do notify"); ++ cv.notify_all(); ++ } ++ } ++} ++} ++} +\ No newline at end of file +diff --git a/interfaces/kits/js/src/mod_fs/class_stream/stream_entity.h b/interfaces/kits/js/src/mod_fs/class_stream/stream_entity.h +index 11cdae1d..60ed185a 100755 +--- a/interfaces/kits/js/src/mod_fs/class_stream/stream_entity.h ++++ b/interfaces/kits/js/src/mod_fs/class_stream/stream_entity.h +@@ -16,11 +16,19 @@ + #ifndef INTERFACES_KITS_JS_SRC_MOD_FILEIO_CLASS_STREAM_STREAM_ENTITY_H + #define INTERFACES_KITS_JS_SRC_MOD_FILEIO_CLASS_STREAM_STREAM_ENTITY_H + ++#include + namespace OHOS { + namespace FileManagement { + namespace ModuleFileIO { + struct StreamEntity { ++ uint32_t count = 0; ++ bool isClose = false; ++ std::mutex mutex; ++ std::condition_variable cv; + std::unique_ptr fp = { nullptr, fclose }; ++ ~StreamEntity(); ++ bool ExecuteStart(); ++ void ExecuteEnd(); + }; + + } // namespace ModuleFileIO +diff --git a/interfaces/kits/js/src/mod_fs/class_stream/stream_n_exporter.cpp b/interfaces/kits/js/src/mod_fs/class_stream/stream_n_exporter.cpp +index d220521a..062b8a73 100644 +--- a/interfaces/kits/js/src/mod_fs/class_stream/stream_n_exporter.cpp ++++ b/interfaces/kits/js/src/mod_fs/class_stream/stream_n_exporter.cpp +@@ -37,6 +37,42 @@ namespace ModuleFileIO { + using namespace std; + using namespace OHOS::FileManagement::LibN; + ++static int32_t FseekCore(StreamEntity *streamEntity, long offset) { ++ int ret = 0; ++ if (streamEntity->ExecuteStart()) { ++ ret = fseek(streamEntity->fp.get(), offset, SEEK_SET); ++ streamEntity->ExecuteEnd(); ++ } ++ return ret; ++} ++ ++static size_t WriteCore(StreamEntity *streamEntity, void * buf, int32_t len) { ++ size_t writeLen = 0; ++ if (streamEntity->ExecuteStart()) { ++ writeLen = fwrite(buf, 1, len, streamEntity->fp.get()); ++ streamEntity->ExecuteEnd(); ++ } ++ return writeLen; ++} ++ ++static size_t ReadCore(StreamEntity *streamEntity, void * buf, int32_t len) { ++ size_t readLen = 0; ++ if (streamEntity->ExecuteStart()) { ++ readLen = fread(buf, 1, len, streamEntity->fp.get()); ++ streamEntity->ExecuteEnd(); ++ } ++ return readLen; ++} ++ ++static int32_t FtellCore(StreamEntity *streamEntity) ++{ ++ int32_t ret = 0; ++ if (streamEntity->ExecuteStart()) { ++ ret = ftell(streamEntity->fp.get()); ++ streamEntity->ExecuteEnd(); ++ } ++ return ret; ++} + napi_value StreamNExporter::ReadSync(napi_env env, napi_callback_info cbInfo) + { + NFuncArg funcArg(env, cbInfo); +@@ -63,7 +99,7 @@ napi_value StreamNExporter::ReadSync(napi_env env, napi_callback_info cbInfo) + } + + if (offset >= 0) { +- int ret = fseek(filp, static_cast(offset), SEEK_SET); ++ int32_t ret = FseekCore(streamEntity, offset); + if (ret < 0) { + HILOGE("Failed to set the offset location of the file stream pointer, ret: %{public}d", ret); + NError(errno).ThrowErr(env); +@@ -71,7 +107,7 @@ napi_value StreamNExporter::ReadSync(napi_env env, napi_callback_info cbInfo) + } + } + +- size_t actLen = fread(buf, 1, len, filp); ++ size_t actLen = ReadCore(streamEntity, buf, len); + if ((actLen != static_cast(len) && !feof(filp)) || ferror(filp)) { + HILOGE("Invalid buffer size and pointer, actlen: %{public}zu", actLen); + NError(EIO).ThrowErr(env); +@@ -96,9 +132,13 @@ napi_value StreamNExporter::CloseSync(napi_env env, napi_callback_info cbInfo) + NError(EIO).ThrowErr(env); + return nullptr; + } +- streamEntity->fp.reset(); +- (void)NClass::RemoveEntityOfFinal(env, funcArg.GetThisVar()); +- ++ { ++ std::lock_guard lock(streamEntity->mutex); ++ streamEntity->isClose = true; ++ if (streamEntity->count == 0) { ++ streamEntity->fp.reset(); ++ } ++ } + return NVal::CreateUndefined(env).val_; + } + +@@ -126,8 +166,9 @@ napi_value StreamNExporter::WriteSync(napi_env env, napi_callback_info cbInfo) + HILOGE("Failed to resolve buf and options"); + return nullptr; + } ++ + if (offset >= 0) { +- int ret = fseek(filp, static_cast(offset), SEEK_SET); ++ int32_t ret = FseekCore(streamEntity, offset); + if (ret < 0) { + HILOGE("Failed to set the offset location of the file stream pointer, ret: %{public}d", ret); + NError(errno).ThrowErr(env); +@@ -135,7 +176,7 @@ napi_value StreamNExporter::WriteSync(napi_env env, napi_callback_info cbInfo) + } + } + +- size_t writeLen = fwrite(buf, 1, len, filp); ++ size_t writeLen = WriteCore(streamEntity, buf, len); + if ((writeLen == 0) && (writeLen != len)) { + HILOGE("Failed to fwrite stream"); + NError(EIO).ThrowErr(env); +@@ -166,13 +207,13 @@ static napi_value WriteExec(napi_env env, NFuncArg &funcArg, StreamEntity *strea + return NError(EIO); + } + if (offset >= 0) { +- int ret = fseek(streamEntity->fp.get(), static_cast(offset), SEEK_SET); ++ int ret = FseekCore(streamEntity, offset); + if (ret < 0) { + HILOGE("Failed to set the offset location of the file stream pointer, ret: %{public}d", ret); + return NError(errno); + } + } +- arg->actLen = fwrite(buf, 1, len, streamEntity->fp.get()); ++ arg->actLen = WriteCore(streamEntity, buf, len); + if ((arg->actLen == 0) && (arg->actLen != len)) { + HILOGE("Failed to fwrite stream"); + return NError(EIO); +@@ -238,12 +279,12 @@ static napi_value ReadExec(napi_env env, NFuncArg &funcArg, StreamEntity *stream + return NError(EIO); + } + if (offset >= 0) { +- if (fseek(streamEntity->fp.get(), static_cast(offset), SEEK_SET) < 0) { ++ if (FseekCore(streamEntity, offset) < 0) { + HILOGE("Failed to set the offset location of the file stream pointer"); + return NError(errno); + } + } +- size_t actLen = fread(buf, 1, len, streamEntity->fp.get()); ++ size_t actLen = ReadCore(streamEntity, buf, len); + if ((actLen != static_cast(len) && !feof(streamEntity->fp.get())) || ferror(streamEntity->fp.get())) { + HILOGE("Invalid buffer size and pointer, actlen: %{public}zu", actLen); + return NError(EIO); +@@ -304,14 +345,12 @@ napi_value StreamNExporter::Close(napi_env env, napi_callback_info cbInfo) + NError(EIO).ThrowErr(env); + return nullptr; + } +- +- auto fp = NClass::RemoveEntityOfFinal(env, funcArg.GetThisVar()); +- if (!fp) { +- NError(EINVAL).ThrowErr(env); +- return nullptr; +- } +- +- auto cbExec = []() -> NError { ++ auto cbExec = [streamEntity]() -> NError { ++ std::lock_guard lock(streamEntity->mutex); ++ streamEntity->isClose = true; ++ if (streamEntity->count == 0) { ++ streamEntity->fp.reset(); ++ } + return NError(ERRNO_NOERR); + }; + +@@ -367,14 +406,14 @@ napi_value StreamNExporter::Seek(napi_env env, napi_callback_info cbInfo) + } + + if (offset >= 0) { +- int ret = fseek(streamEntity->fp.get(), static_cast(offset), whence); ++ int ret = FseekCore(streamEntity, offset); + if (ret < 0) { + HILOGE("Failed to set the offset location of the file stream pointer, ret: %{public}d", ret); + NError(errno).ThrowErr(env); + return nullptr; + } + } +- int64_t res = ftell(streamEntity->fp.get()); ++ int64_t res = FtellCore(streamEntity); + if (res < 0) { + HILOGE("Failed to tell, error:%{public}d", errno); + NError(errno).ThrowErr(env); +diff --git a/interfaces/kits/js/src/mod_fs/class_stream/stream_n_exporter.h b/interfaces/kits/js/src/mod_fs/class_stream/stream_n_exporter.h +index fb7f0fb3..5dcf62e1 100644 +--- a/interfaces/kits/js/src/mod_fs/class_stream/stream_n_exporter.h ++++ b/interfaces/kits/js/src/mod_fs/class_stream/stream_n_exporter.h +@@ -44,6 +44,8 @@ public: + ~StreamNExporter() override; + }; + ++ ++ + struct AsyncReadArg { + size_t lenRead = 0; + NRef refReadBuf; +-- +Gitee + diff --git a/interfaces/kits/js/BUILD.gn b/interfaces/kits/js/BUILD.gn index c98a406bb5488209c9abbf2ab2f5b24a0c018fc3..2a2a831213e245f8440c81b1663bab067e2593ed 100644 --- a/interfaces/kits/js/BUILD.gn +++ b/interfaces/kits/js/BUILD.gn @@ -216,6 +216,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_stream/stream_entity.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", diff --git a/interfaces/kits/js/src/mod_fs/class_stream/flush.cpp b/interfaces/kits/js/src/mod_fs/class_stream/flush.cpp index 105eab7bae4f85d7b8704967f58955742d78fcd5..325ad248aae174cf2d17eb04bff329dad29308f9 100755 --- a/interfaces/kits/js/src/mod_fs/class_stream/flush.cpp +++ b/interfaces/kits/js/src/mod_fs/class_stream/flush.cpp @@ -28,6 +28,16 @@ namespace ModuleFileIO { using namespace std; using namespace OHOS::FileManagement::LibN; +static int32_t FlushCore(StreamEntity *streamEntity) +{ + int32_t ret = 0; + if (streamEntity->ExecuteStart()) { + ret = fflush(streamEntity->fp.get()); + streamEntity->ExecuteEnd(); + } + return ret; +} + napi_value Flush::Sync(napi_env env, napi_callback_info info) { NFuncArg funcArg(env, info); @@ -43,8 +53,8 @@ napi_value Flush::Sync(napi_env env, napi_callback_info info) NError(EIO).ThrowErr(env); return nullptr; } + int32_t ret = FlushCore(streamEntity); - int ret = fflush(streamEntity->fp.get()); if (ret < 0) { HILOGE("Failed to fflush file in the stream, ret: %{public}d", ret); NError(errno).ThrowErr(env); @@ -74,7 +84,7 @@ napi_value Flush::Async(napi_env env, napi_callback_info info) HILOGE("Stream has been closed in flush cbExec possibly"); return NError(EIO); } - int ret = fflush(streamEntity->fp.get()); + int32_t ret = FlushCore(streamEntity); if (ret < 0) { HILOGE("Failed to fflush file in the stream"); return NError(errno); diff --git a/interfaces/kits/js/src/mod_fs/class_stream/stream_entity.cpp b/interfaces/kits/js/src/mod_fs/class_stream/stream_entity.cpp new file mode 100644 index 0000000000000000000000000000000000000000..2c424bc6a43f3d200ac38540cda40c436d1948f0 --- /dev/null +++ b/interfaces/kits/js/src/mod_fs/class_stream/stream_entity.cpp @@ -0,0 +1,31 @@ +#include "stream_entity.h" +#include "filemgmt_libhilog.h" +#include + +namespace OHOS { +namespace FileManagement { +namespace ModuleFileIO { + StreamEntity::~StreamEntity() { + if (count > 0) { + HILOGE("count is %{public}d", count); + } + } + bool StreamEntity::ExecuteStart() { + std::lock_guard lock(mutex); + if (isClose) { + return false; + } + count++; + return true; + } + + void StreamEntity::ExecuteEnd() { + std::lock_guard lock(mutex); + count--; + if (count == 0 && isClose) { + fp.reset(); + } + } +} +} +} \ No newline at end of file diff --git a/interfaces/kits/js/src/mod_fs/class_stream/stream_entity.h b/interfaces/kits/js/src/mod_fs/class_stream/stream_entity.h index 11cdae1dc8c70fa34f5804158e6b4c575a94ac5e..60ed185ae614ffa9c14d3425affbe9a58368816d 100755 --- a/interfaces/kits/js/src/mod_fs/class_stream/stream_entity.h +++ b/interfaces/kits/js/src/mod_fs/class_stream/stream_entity.h @@ -16,11 +16,19 @@ #ifndef INTERFACES_KITS_JS_SRC_MOD_FILEIO_CLASS_STREAM_STREAM_ENTITY_H #define INTERFACES_KITS_JS_SRC_MOD_FILEIO_CLASS_STREAM_STREAM_ENTITY_H +#include namespace OHOS { namespace FileManagement { namespace ModuleFileIO { struct StreamEntity { + uint32_t count = 0; + bool isClose = false; + std::mutex mutex; + std::condition_variable cv; std::unique_ptr fp = { nullptr, fclose }; + ~StreamEntity(); + bool ExecuteStart(); + void ExecuteEnd(); }; } // namespace ModuleFileIO diff --git a/interfaces/kits/js/src/mod_fs/class_stream/stream_n_exporter.cpp b/interfaces/kits/js/src/mod_fs/class_stream/stream_n_exporter.cpp index d220521a95c116b27a5d64c3156a2effa5280bce..a3af81d1f8783e3fd324854e7f118d64ff61b635 100644 --- a/interfaces/kits/js/src/mod_fs/class_stream/stream_n_exporter.cpp +++ b/interfaces/kits/js/src/mod_fs/class_stream/stream_n_exporter.cpp @@ -37,6 +37,42 @@ namespace ModuleFileIO { using namespace std; using namespace OHOS::FileManagement::LibN; +static int32_t FseekCore(StreamEntity *streamEntity, long offset) { + int ret = 0; + if (streamEntity->ExecuteStart()) { + ret = fseek(streamEntity->fp.get(), offset, SEEK_SET); + streamEntity->ExecuteEnd(); + } + return ret; +} + +static size_t WriteCore(StreamEntity *streamEntity, void * buf, int32_t len) { + size_t writeLen = 0; + if (streamEntity->ExecuteStart()) { + writeLen = fwrite(buf, 1, len, streamEntity->fp.get()); + streamEntity->ExecuteEnd(); + } + return writeLen; +} + +static size_t ReadCore(StreamEntity *streamEntity, void * buf, int32_t len) { + size_t readLen = 0; + if (streamEntity->ExecuteStart()) { + readLen = fread(buf, 1, len, streamEntity->fp.get()); + streamEntity->ExecuteEnd(); + } + return readLen; +} + +static int32_t FtellCore(StreamEntity *streamEntity) +{ + int32_t ret = 0; + if (streamEntity->ExecuteStart()) { + ret = ftell(streamEntity->fp.get()); + streamEntity->ExecuteEnd(); + } + return ret; +} napi_value StreamNExporter::ReadSync(napi_env env, napi_callback_info cbInfo) { NFuncArg funcArg(env, cbInfo); @@ -63,7 +99,7 @@ napi_value StreamNExporter::ReadSync(napi_env env, napi_callback_info cbInfo) } if (offset >= 0) { - int ret = fseek(filp, static_cast(offset), SEEK_SET); + int32_t ret = FseekCore(streamEntity, offset); if (ret < 0) { HILOGE("Failed to set the offset location of the file stream pointer, ret: %{public}d", ret); NError(errno).ThrowErr(env); @@ -71,7 +107,7 @@ napi_value StreamNExporter::ReadSync(napi_env env, napi_callback_info cbInfo) } } - size_t actLen = fread(buf, 1, len, filp); + size_t actLen = ReadCore(streamEntity, buf, len); if ((actLen != static_cast(len) && !feof(filp)) || ferror(filp)) { HILOGE("Invalid buffer size and pointer, actlen: %{public}zu", actLen); NError(EIO).ThrowErr(env); @@ -96,9 +132,14 @@ napi_value StreamNExporter::CloseSync(napi_env env, napi_callback_info cbInfo) NError(EIO).ThrowErr(env); return nullptr; } - streamEntity->fp.reset(); - (void)NClass::RemoveEntityOfFinal(env, funcArg.GetThisVar()); - + { + std::lock_guard lock(streamEntity->mutex); + streamEntity->isClose = true; + if (streamEntity->count == 0) { + streamEntity->fp.reset(); + (void)NClass::RemoveEntityOfFinal(env, funcArg.GetThisVar()); + } + } return NVal::CreateUndefined(env).val_; } @@ -127,7 +168,7 @@ napi_value StreamNExporter::WriteSync(napi_env env, napi_callback_info cbInfo) return nullptr; } if (offset >= 0) { - int ret = fseek(filp, static_cast(offset), SEEK_SET); + int32_t ret = FseekCore(streamEntity, offset); if (ret < 0) { HILOGE("Failed to set the offset location of the file stream pointer, ret: %{public}d", ret); NError(errno).ThrowErr(env); @@ -135,7 +176,7 @@ napi_value StreamNExporter::WriteSync(napi_env env, napi_callback_info cbInfo) } } - size_t writeLen = fwrite(buf, 1, len, filp); + size_t writeLen = WriteCore(streamEntity, buf, len); if ((writeLen == 0) && (writeLen != len)) { HILOGE("Failed to fwrite stream"); NError(EIO).ThrowErr(env); @@ -166,13 +207,13 @@ static napi_value WriteExec(napi_env env, NFuncArg &funcArg, StreamEntity *strea return NError(EIO); } if (offset >= 0) { - int ret = fseek(streamEntity->fp.get(), static_cast(offset), SEEK_SET); + int ret = FseekCore(streamEntity, offset); if (ret < 0) { HILOGE("Failed to set the offset location of the file stream pointer, ret: %{public}d", ret); return NError(errno); } } - arg->actLen = fwrite(buf, 1, len, streamEntity->fp.get()); + arg->actLen = WriteCore(streamEntity, buf, len); if ((arg->actLen == 0) && (arg->actLen != len)) { HILOGE("Failed to fwrite stream"); return NError(EIO); @@ -238,12 +279,12 @@ static napi_value ReadExec(napi_env env, NFuncArg &funcArg, StreamEntity *stream return NError(EIO); } if (offset >= 0) { - if (fseek(streamEntity->fp.get(), static_cast(offset), SEEK_SET) < 0) { + if (FseekCore(streamEntity, offset) < 0) { HILOGE("Failed to set the offset location of the file stream pointer"); return NError(errno); } } - size_t actLen = fread(buf, 1, len, streamEntity->fp.get()); + size_t actLen = ReadCore(streamEntity, buf, len); if ((actLen != static_cast(len) && !feof(streamEntity->fp.get())) || ferror(streamEntity->fp.get())) { HILOGE("Invalid buffer size and pointer, actlen: %{public}zu", actLen); return NError(EIO); @@ -304,14 +345,12 @@ napi_value StreamNExporter::Close(napi_env env, napi_callback_info cbInfo) NError(EIO).ThrowErr(env); return nullptr; } - - auto fp = NClass::RemoveEntityOfFinal(env, funcArg.GetThisVar()); - if (!fp) { - NError(EINVAL).ThrowErr(env); - return nullptr; - } - - auto cbExec = []() -> NError { + auto cbExec = [streamEntity, env, var = funcArg.GetThisVar()]() -> NError { + std::lock_guard lock(streamEntity->mutex); + streamEntity->isClose = true; + if (streamEntity->count == 0) { + streamEntity->fp.reset(); + } return NError(ERRNO_NOERR); }; @@ -367,14 +406,14 @@ napi_value StreamNExporter::Seek(napi_env env, napi_callback_info cbInfo) } if (offset >= 0) { - int ret = fseek(streamEntity->fp.get(), static_cast(offset), whence); + int ret = FseekCore(streamEntity, offset); if (ret < 0) { HILOGE("Failed to set the offset location of the file stream pointer, ret: %{public}d", ret); NError(errno).ThrowErr(env); return nullptr; } } - int64_t res = ftell(streamEntity->fp.get()); + int64_t res = FtellCore(streamEntity); if (res < 0) { HILOGE("Failed to tell, error:%{public}d", errno); NError(errno).ThrowErr(env);