diff --git a/driver/js/src/js_driver_utils.cc b/driver/js/src/js_driver_utils.cc index e3b91d4d746..ae43abaaad8 100644 --- a/driver/js/src/js_driver_utils.cc +++ b/driver/js/src/js_driver_utils.cc @@ -80,6 +80,8 @@ constexpr char kGlobalKey[] = "global"; constexpr char kHippyKey[] = "Hippy"; constexpr char kNativeGlobalKey[] = "__HIPPYNATIVEGLOBAL__"; constexpr char kCallHostKey[] = "hippyCallNatives"; +constexpr char kCodeCacheFailCountFilePostfix[] = "_fail_count"; +const uint8_t kCodeCacheMaxFailCount = 3; #if defined(JS_V8) && defined(ENABLE_INSPECTOR) && !defined(V8_WITHOUT_INSPECTOR) using V8InspectorClientImpl = hippy::inspector::V8InspectorClientImpl; @@ -91,6 +93,7 @@ using DevtoolsDataSource = hippy::devtools::DevtoolsDataSource; static std::unordered_map, uint32_t>> reuse_engine_map; static std::mutex engine_mutex; +static std::mutex code_cache_file_mutex; void AsyncInitializeEngine(const std::shared_ptr& engine, const std::shared_ptr& task_runner, @@ -269,6 +272,39 @@ void JsDriverUtils::InitInstance( }); } +// Code cache file corruption prevention strategy: +// Record count before RunScript, clean count after RunScript, and if only start recording three times in a row, clean the code cache file. +bool CheckUseCodeCacheBeforeRunScript(const string_view& code_cache_path) { + string_view fail_count_path = code_cache_path + string_view(kCodeCacheFailCountFilePostfix); + u8string content; + HippyFile::ReadFile(fail_count_path, content, false); + if (content.length() == 1) { + uint8_t count = content[0]; + if (count >= kCodeCacheMaxFailCount) { + FOOTSTONE_LOG(INFO) << "Check code cache, count >= 3"; + // need to remove code cache file + return false; + } else { + FOOTSTONE_LOG(INFO) << "Check code cache, count = " << static_cast(count); + ++count; + std::string saveContent; + saveContent.push_back(count); + HippyFile::SaveFile(fail_count_path, saveContent); + } + } else { + FOOTSTONE_LOG(INFO) << "Check code cache, no count"; + std::string saveContent; + saveContent.push_back(1); + HippyFile::SaveFile(fail_count_path, saveContent); + } + return true; +} + +void CheckUseCodeCacheAfterRunScript(const string_view& code_cache_path) { + string_view fail_count_path = code_cache_path + string_view(kCodeCacheFailCountFilePostfix); + HippyFile::RmFile(fail_count_path); +} + bool JsDriverUtils::RunScript(const std::shared_ptr& scope, const string_view& file_name, bool is_use_code_cache, @@ -298,6 +334,7 @@ bool JsDriverUtils::RunScript(const std::shared_ptr& scope, auto engine = scope->GetEngine().lock(); FOOTSTONE_CHECK(engine); auto func = hippy::base::MakeCopyable([p = std::move(read_file_promise), code_cache_path, code_cache_dir]() mutable { + std::lock_guard lock(code_cache_file_mutex); u8string content; HippyFile::ReadFile(code_cache_path, content, true); if (content.empty()) { @@ -307,6 +344,12 @@ bool JsDriverUtils::RunScript(const std::shared_ptr& scope, FOOTSTONE_USE(ret); } else { FOOTSTONE_DLOG(INFO) << "Read code cache succ"; + if (!CheckUseCodeCacheBeforeRunScript(code_cache_path)) { + int ret = HippyFile::RmFullPath(code_cache_dir); + FOOTSTONE_DLOG(INFO) << "RmFullPath on check, ret = " << ret; + FOOTSTONE_USE(ret); + content.clear(); + } } p.set_value(std::move(content)); }); @@ -332,6 +375,10 @@ bool JsDriverUtils::RunScript(const std::shared_ptr& scope, if (!read_script_flag || StringViewUtils::IsEmpty(script_content)) { FOOTSTONE_LOG(WARNING) << "read_script_flag = " << read_script_flag << ", script content empty, uri = " << uri; + if (is_use_code_cache) { + std::lock_guard lock(code_cache_file_mutex); + CheckUseCodeCacheAfterRunScript(code_cache_path); + } return false; } @@ -345,6 +392,7 @@ bool JsDriverUtils::RunScript(const std::shared_ptr& scope, if (is_use_code_cache) { if (!StringViewUtils::IsEmpty(code_cache_content)) { auto func = [code_cache_path, code_cache_dir, code_cache_content] { + std::lock_guard lock(code_cache_file_mutex); int check_dir_ret = HippyFile::CheckDir(code_cache_dir, F_OK); FOOTSTONE_DLOG(INFO) << "check_parent_dir_ret = " << check_dir_ret; if (check_dir_ret) { @@ -364,6 +412,8 @@ bool JsDriverUtils::RunScript(const std::shared_ptr& scope, bool save_file_ret = HippyFile::SaveFile(code_cache_path, u8_code_cache_content); FOOTSTONE_LOG(INFO) << "code cache save_file_ret = " << save_file_ret; FOOTSTONE_USE(save_file_ret); + + CheckUseCodeCacheAfterRunScript(code_cache_path); }; auto engine = scope->GetEngine().lock(); FOOTSTONE_CHECK(engine); diff --git a/modules/vfs/native/include/vfs/file.h b/modules/vfs/native/include/vfs/file.h index 98ab2941910..fd3088a31df 100644 --- a/modules/vfs/native/include/vfs/file.h +++ b/modules/vfs/native/include/vfs/file.h @@ -46,6 +46,7 @@ class HippyFile { std::ios::openmode mode = std::ios::out | std::ios::binary | std::ios::trunc); + static int RmFile(const string_view& file_path); static int RmFullPath(const string_view& dir_full_path); static int CreateDir(const string_view& dir_path, mode_t mode); static int CheckDir(const string_view& dir_path, int mode); diff --git a/modules/vfs/native/src/file.cc b/modules/vfs/native/src/file.cc index 7f51040f271..b2b99ab3c36 100644 --- a/modules/vfs/native/src/file.cc +++ b/modules/vfs/native/src/file.cc @@ -51,6 +51,15 @@ bool HippyFile::SaveFile(const string_view& file_path, } } +int HippyFile::RmFile(const string_view& file_path) { + FOOTSTONE_DLOG(INFO) << "RmFile file_path = " << file_path; + auto path_str = StringViewUtils::ConvertEncoding(file_path, + string_view::Encoding::Utf8).utf8_value(); + auto path = reinterpret_cast(path_str.c_str()); + unlink(path); + return 0; +} + int HippyFile::RmFullPath(const string_view& dir_full_path) { FOOTSTONE_DLOG(INFO) << "RmFullPath dir_full_path = " << dir_full_path; auto path_str = StringViewUtils::ConvertEncoding(dir_full_path,