From 18e96595f9193723b827c7d2dc3ae764510a18b6 Mon Sep 17 00:00:00 2001 From: Cao Chuan Date: Fri, 2 Jun 2023 13:43:27 +0800 Subject: [PATCH 01/27] Modify work style of file watcher Signed-off-by: Cao Chuan --- .../mod_fs/class_watcher/watcher_entity.cpp | 174 +++++++++++++++--- .../src/mod_fs/class_watcher/watcher_entity.h | 57 ++++-- .../class_watcher/watcher_n_exporter.cpp | 12 +- .../kits/js/src/mod_fs/properties/watcher.cpp | 47 ++--- 4 files changed, 213 insertions(+), 77 deletions(-) diff --git a/interfaces/kits/js/src/mod_fs/class_watcher/watcher_entity.cpp b/interfaces/kits/js/src/mod_fs/class_watcher/watcher_entity.cpp index 1500dfcfd..b810c681c 100644 --- a/interfaces/kits/js/src/mod_fs/class_watcher/watcher_entity.cpp +++ b/interfaces/kits/js/src/mod_fs/class_watcher/watcher_entity.cpp @@ -19,80 +19,194 @@ #include "filemgmt_libhilog.h" #include "uv.h" +namespace { + constexpr int32_t STOPPING_WAIT_TIMEOUT_MS = 5000; + constexpr int64_t SELECT_TIME_OUT_US = 100000; +} // namespace + namespace OHOS::FileManagement::ModuleFileIO { using namespace OHOS::FileManagement::LibN; -FileWatcher::FileWatcher() {} +using namespace std; + +shared_ptr FileWatcher::instance_ = nullptr; +mutex FileWatcher::mutex_; + +shared_ptr FileWatcher::GetInstance() +{ + if (instance_ == nullptr) { + lock_guard lock(mutex_); + if (instance_ == nullptr) { + instance_ = shared_ptr(new FileWatcher()); + } + } + return instance_; +} -FileWatcher::~FileWatcher() {} +int32_t FileWatcher::GetNotifyId() +{ + return notifyFd_; +} -bool FileWatcher::InitNotify(int &fd) +bool FileWatcher::InitNotify() { - fd = inotify_init(); - if (fd < 0) { + notifyFd_ = inotify_init(); + if (notifyFd_ < 0) { HILOGE("Failed to init notify fail errCode:%{public}d", errno); return false; } return true; } -bool FileWatcher::StartNotify(WatcherInfoArg &arg) +bool FileWatcher::StartNotify(shared_ptr &arg) { - int wd = inotify_add_watch(arg.fd, arg.filename.c_str(), arg.events); + if (notifyFd_ < 0) { + HILOGE("Failed to start notify fail notifyFd_:%{public}d", notifyFd_); + return false; + } + int wd = inotify_add_watch(notifyFd_, arg->filename.c_str(), arg->events); if (wd < 0) { - HILOGE("Failed to start notify fail errCode:%{public}d", errno); + HILOGE("Failed to start notify1 fail errCode:%{public}d", errno); return false; } - arg.wd = wd; - run_ = true; + arg->wd = wd; return true; } -bool FileWatcher::StopNotify(const WatcherInfoArg &arg) +bool FileWatcher::StopNotify(const shared_ptr &arg) { - run_ = false; - if (arg.events == IN_DELETE_SELF) { - close(arg.fd); - return true; + HILOGE("FileWatcher::StopNotify!"); + if (notifyFd_ < 0) { + HILOGE("Failed to stop notify fail notifyFd_:%{public}d", notifyFd_); + return false; } - if (inotify_rm_watch(arg.fd, arg.wd) == -1) { + + // if (arg.events == IN_DELETE_SELF) { + // close(arg.fd); + // return true; + // } + + if (inotify_rm_watch(notifyFd_, arg->wd) == -1) { HILOGE("Failed to stop notify fail errCode:%{public}d", errno); return false; } - close(arg.fd); - return true; + HILOGE("FileWatcher::remove before!"); + watcherCallbacks_.Remove(arg->wd); + if (watcherCallbacks_.Size() == 0) { + close(notifyFd_); + notifyFd_ = -1; + run_ = false; + if (!WaitForStop()) { + HILOGE("Wait for stop timeout!"); + } else { + HILOGE("Stopped!~!!"); + } + return true; + } + return false; } -void FileWatcher::HandleEvent(WatcherInfoArg &arg, const struct inotify_event *event, WatcherCallback callback) +void FileWatcher::HandleEvent(const struct inotify_event *event) { - if (event->wd != arg.wd) { + HILOGE("FileWatcher::HandleEvent!"); + auto iter = watcherCallbacks_.Get(event->wd); + if (watcherCallbacks_.IsEnd(iter)) { return; } - std::string fileName = arg.filename; + HILOGE("FileWatcher::HandleEvent find callback!"); + shared_ptr arg = iter->second.first; + string fileName = arg->filename; if (event->len > 0) { - fileName.append(std::string("/")); - fileName.append(std::string(event->name)); + fileName.append(string("/")); + fileName.append(string(event->name)); } - callback(arg.env, arg.nRef, fileName, event->mask, event->cookie); + + auto callback = iter->second.second; + callback(arg->env, arg->nRef, fileName, event->mask, event->cookie); } -void FileWatcher::GetNotifyEvent(WatcherInfoArg &arg, WatcherCallback callback) +void FileWatcher::GetNotifyEvent(shared_ptr &arg, WatcherCallback callback) { + watcherCallbacks_.Add(arg, callback); + + if (run_) { + HILOGE("Listener Thread has started and do nothing!"); + return; + } + + run_ =true; char buf[BUF_SIZE] = {0}; struct inotify_event *event = nullptr; while (run_) { - int fd = arg.fd; + if (notifyFd_ < 0) { + HILOGE("Failed to run Listener Thread because notifyFd_:%{public}d", notifyFd_); + break; + } fd_set fds; FD_ZERO(&fds); - FD_SET(fd, &fds); - if (select(fd + 1, &fds, nullptr, nullptr, nullptr) > 0) { + FD_SET(notifyFd_, &fds); + timeval timeout{.tv_sec = 0, .tv_usec = SELECT_TIME_OUT_US}; + if (select(notifyFd_ + 1, &fds, nullptr, nullptr, &timeout) > 0) { int len, index = 0; - while (((len = read(fd, &buf, sizeof(buf))) < 0) && (errno == EINTR)) {}; + while (((len = read(notifyFd_, &buf, sizeof(buf))) < 0) && (errno == EINTR)) {}; while (index < len) { event = reinterpret_cast(buf + index); - HandleEvent(arg, event, callback); + HandleEvent(event); index += sizeof(struct inotify_event) + event->len; } } + if (!run_) { + NotifyStopped(); + } } + HILOGE("Listener Thread has stopped!"); +} +bool FileWatcher::WaitForStop() +{ + std::unique_lock lock(stoppingMutex_); + auto status = stoppingLock_.wait_for(lock, std::chrono::milliseconds(STOPPING_WAIT_TIMEOUT_MS)); + return status != std::cv_status::timeout; +} +void FileWatcher::NotifyStopped() +{ + std::unique_lock lock(stoppingMutex_); + stoppingLock_.notify_one(); } + +void WatcherCallbackContext::Add(std::shared_ptr &arg, WatcherCallback callback) +{ + lock_guard lock(contextMutex_); + pair, WatcherCallback> callbackVal = make_pair(arg, callback); + map_[arg->wd] = callbackVal; +} +WatcherCallbackMap::iterator WatcherCallbackContext::Get(const int &fd) +{ + lock_guard lock(contextMutex_); + return UnSafeGet(fd); +} +bool WatcherCallbackContext::IsEnd(WatcherCallbackMap::iterator &iter) +{ + return iter == map_.end(); +} +void WatcherCallbackContext::Remove(int &fd) +{ + lock_guard lock(contextMutex_); + auto iter = UnSafeGet(fd); + if (IsEnd(iter)) { + return true; + } + map_.erase(iter); +} +size_t WatcherCallbackContext::Size() +{ + lock_guard lock(contextMutex_); + return map_.size(); +} +WatcherCallbackMap::iterator WatcherCallbackContext::UnSafeGet(const int &fd) +{ + if (map_.size() == 0) { + return map_.end(); + } + return map_.find(fd); +} + } // namespace OHOS::FileManagement::ModuleFileIO diff --git a/interfaces/kits/js/src/mod_fs/class_watcher/watcher_entity.h b/interfaces/kits/js/src/mod_fs/class_watcher/watcher_entity.h index fad6ec27a..e0219bbf0 100644 --- a/interfaces/kits/js/src/mod_fs/class_watcher/watcher_entity.h +++ b/interfaces/kits/js/src/mod_fs/class_watcher/watcher_entity.h @@ -17,6 +17,7 @@ #include #include #include +#include #include #include "filemgmt_libn.h" @@ -30,32 +31,64 @@ constexpr int BUF_SIZE = 1024; struct WatcherInfoArg { std::string filename = ""; uint32_t events = 0; - int fd = -1; int wd = -1; napi_env env = nullptr; LibN::NRef nRef; explicit WatcherInfoArg(LibN::NVal jsVal) : nRef(jsVal) {} ~WatcherInfoArg() = default; }; - +using WatcherCallbackMap = std::unordered_map, WatcherCallback>>; +// using WatcherCallbackMapIter = std::unordered_map, WatcherCallback>>::iterator; +class WatcherCallbackContext { +public: + WatcherCallbackContext() = default; + ~WatcherCallbackContext() { + map_.clear(); + } + void Add(std::shared_ptr &arg, WatcherCallback callback); + WatcherCallbackMap::iterator Get(const int &fd); + bool IsEnd(WatcherCallbackMap::iterator &iter); + void Remove(int &fd); + size_t Size(); +private: + WatcherCallbackMap::iterator UnSafeGet(const int &fd); + std::mutex contextMutex_; + WatcherCallbackMap map_; +}; class FileWatcher { public: - FileWatcher(); - ~FileWatcher(); - bool InitNotify(int &fd); - bool StartNotify(WatcherInfoArg &arg); - bool StopNotify(const WatcherInfoArg &arg); - void GetNotifyEvent(WatcherInfoArg &arg, WatcherCallback callback); + virtual ~FileWatcher() = default; + + static std::shared_ptr GetInstance(); + int32_t GetNotifyId(); + bool InitNotify(); + bool StartNotify(std::shared_ptr &arg); + bool StopNotify(const std::shared_ptr &arg); + void GetNotifyEvent(std::shared_ptr &arg, WatcherCallback callback); + +private: + FileWatcher() = default; + void HandleEvent(const struct inotify_event *event); + bool WaitForStop(); + void NotifyStopped(); + void AddWatcher(std::shared_ptr &arg, WatcherCallback callback); + WatcherCallbackMap::iterator GetWatcher(int &fd); + bool IsVailedWatcherIter(WatcherCallbackMap::iterator &iter); + void RemoveWatcher(int &fd); + size_t WatcherSize(); private: - void HandleEvent(WatcherInfoArg &arg, const struct inotify_event *event, - WatcherCallback callback); + static std::mutex mutex_; + static std::shared_ptr instance_; bool run_ = false; + int32_t notifyFd_ = -1; + WatcherCallbackContext watcherCallbacks_; + std::mutex stoppingMutex_; + std::condition_variable stoppingLock_; }; struct WatcherEntity { - std::unique_ptr data_; - std::shared_ptr watcherPtr_; + std::shared_ptr data_; }; } // namespace OHOS::FileManagement::ModuleFileIO namespace OHOS #endif diff --git a/interfaces/kits/js/src/mod_fs/class_watcher/watcher_n_exporter.cpp b/interfaces/kits/js/src/mod_fs/class_watcher/watcher_n_exporter.cpp index a1988cbeb..9a87ccbef 100644 --- a/interfaces/kits/js/src/mod_fs/class_watcher/watcher_n_exporter.cpp +++ b/interfaces/kits/js/src/mod_fs/class_watcher/watcher_n_exporter.cpp @@ -64,7 +64,9 @@ napi_value WatcherNExporter::Stop(napi_env env, napi_callback_info info) NError(EINVAL).ThrowErr(env); return nullptr; } - if (!watchEntity->watcherPtr_->StopNotify(*(watchEntity->data_))) { +HILOGE("WatcherNExporter::Stop notifyFd_: %{public}d", FileWatcher::GetInstance()->GetNotifyId()); +HILOGE("WatcherNExporter::Stop wd: %{public}d", watchEntity->data_->wd); + if (!FileWatcher::GetInstance()->StopNotify(watchEntity->data_)) { NError(errno).ThrowErr(env); return nullptr; } @@ -85,14 +87,16 @@ napi_value WatcherNExporter::Start(napi_env env, napi_callback_info info) NError(EINVAL).ThrowErr(env); return nullptr; } - - if (!watchEntity->watcherPtr_->StartNotify(*(watchEntity->data_))) { +HILOGE("WatcherNExporter::Start notifyFd_: %{public}d", FileWatcher::GetInstance()->GetNotifyId()); + if (!FileWatcher::GetInstance()->StartNotify(watchEntity->data_)) { NError(errno).ThrowErr(env); return nullptr; } +HILOGE("WatcherNExporter::Start filename: %{public}s", watchEntity->data_->filename.c_str()); auto cbExec = [watchEntity]() -> NError { - watchEntity->watcherPtr_->GetNotifyEvent(*(watchEntity->data_), WatcherCallback); +HILOGE("WatcherNExporter::Start GetNotifyEvent wd: %{public}d", watchEntity->data_->wd); + FileWatcher::GetInstance()->GetNotifyEvent(watchEntity->data_, WatcherCallback); return NError(ERRNO_NOERR); }; diff --git a/interfaces/kits/js/src/mod_fs/properties/watcher.cpp b/interfaces/kits/js/src/mod_fs/properties/watcher.cpp index 8d3fa0341..8a03b72b1 100644 --- a/interfaces/kits/js/src/mod_fs/properties/watcher.cpp +++ b/interfaces/kits/js/src/mod_fs/properties/watcher.cpp @@ -31,7 +31,7 @@ using namespace std; using namespace OHOS::FileManagement::LibN; namespace { - const std::string STORAGE_DATA_PATH = "/data"; + const string STORAGE_DATA_PATH = "/data"; bool IsSystemApp() { uint64_t fullTokenId = OHOS::IPCSkeleton::GetCallingFullTokenID(); @@ -39,23 +39,6 @@ namespace { } } -static tuple, napi_value, NError> CreateAndCheckForWatcherEntity(napi_env env, int& fd) -{ - auto watcherPtr = CreateSharedPtr(); - if (watcherPtr == nullptr) { - HILOGE("Failed to request heap memory."); - return {nullptr, nullptr, NError(ENOMEM)}; - } - if (!watcherPtr->InitNotify(fd)) { - return {watcherPtr, nullptr, NError(errno)}; - } - napi_value objWatcher = NClass::InstantiateClass(env, WatcherNExporter::className_, {}); - if (!objWatcher) { - return {watcherPtr, nullptr, NError(EINVAL)}; - } - return {watcherPtr, objWatcher, NError(ERRNO_NOERR)}; -} - napi_value Watcher::CreateWatcher(napi_env env, napi_callback_info info) { if (!IsSystemApp()) { @@ -81,10 +64,16 @@ napi_value Watcher::CreateWatcher(napi_env env, napi_callback_info info) return nullptr; } - int fd = -1; - auto [watcherPtr, objWatcher, err] = CreateAndCheckForWatcherEntity(env, fd); - if (watcherPtr == nullptr || !objWatcher) { - err.ThrowErr(env); +HILOGE("CreateWatcher notifyFd_1: %{public}d", FileWatcher::GetInstance()->GetNotifyId()); + if (FileWatcher::GetInstance()->GetNotifyId() < 0 && !FileWatcher::GetInstance()->InitNotify()) { + NError(errno).ThrowErr(env); + return nullptr; + } +HILOGE("CreateWatcher notifyFd_2: %{public}d", FileWatcher::GetInstance()->GetNotifyId()); + + napi_value objWatcher = NClass::InstantiateClass(env, WatcherNExporter::className_, {}); + if (!objWatcher) { + NError(EINVAL).ThrowErr(env); return nullptr; } @@ -98,19 +87,15 @@ napi_value Watcher::CreateWatcher(napi_env env, napi_callback_info info) NError(EINVAL).ThrowErr(env); return nullptr; } - watcherEntity->data_ = CreateUniquePtr(NVal(env, funcArg[NARG_POS::THIRD])); - if (watcherEntity->data_ == nullptr) { - HILOGE("Failed to request heap memory."); - NError(ENOMEM).ThrowErr(env); - return nullptr; - } + + watcherEntity->data_ = make_shared(NVal(env, funcArg[NARG_POS::THIRD])); watcherEntity->data_->events = events; watcherEntity->data_->env = env; watcherEntity->data_->filename = string(filename.get()); - watcherEntity->data_->fd = fd; + // watcherEntity->data_->fd = fd; + + // watcherEntity->watcherPtr_ = watcherPtr_; - watcherEntity->watcherPtr_ = watcherPtr; - return objWatcher; } } // namespace OHOS::FileManagement::ModuleFileIO -- Gitee From 1043cb756e1ec8e1610232df463708ac3cf43ab5 Mon Sep 17 00:00:00 2001 From: Cao Chuan Date: Fri, 2 Jun 2023 17:26:13 +0800 Subject: [PATCH 02/27] Add JS callback list Signed-off-by: Cao Chuan --- .../js/src/mod_fs/class_watcher/watcher_entity.cpp | 13 +++++++++++++ .../js/src/mod_fs/class_watcher/watcher_entity.h | 14 ++++++++++---- .../mod_fs/class_watcher/watcher_n_exporter.cpp | 2 +- 3 files changed, 24 insertions(+), 5 deletions(-) diff --git a/interfaces/kits/js/src/mod_fs/class_watcher/watcher_entity.cpp b/interfaces/kits/js/src/mod_fs/class_watcher/watcher_entity.cpp index b810c681c..ace12f24a 100644 --- a/interfaces/kits/js/src/mod_fs/class_watcher/watcher_entity.cpp +++ b/interfaces/kits/js/src/mod_fs/class_watcher/watcher_entity.cpp @@ -172,6 +172,19 @@ void FileWatcher::NotifyStopped() stoppingLock_.notify_one(); } +void FileWatcher::AddJSWatcherCallbacks(const string & fileName, NVal jsCallbackVal, uint32_t events) +{ + pair jsCallbackPair = make_pair(jsCallbackVal, events); + if (jsWatcherCallbackMap_.find(fileName) == jsWatcherCallbackMap_.end()) { + vector> jsCallbackVec; + jsCallbackVec.push_back(jsCallbackPair); + jsWatcherCallbackMap_[fileName] = jsCallbackVec; + } else { + // TODO + } + // jsWatcherCallbackMap_ +} + void WatcherCallbackContext::Add(std::shared_ptr &arg, WatcherCallback callback) { lock_guard lock(contextMutex_); diff --git a/interfaces/kits/js/src/mod_fs/class_watcher/watcher_entity.h b/interfaces/kits/js/src/mod_fs/class_watcher/watcher_entity.h index e0219bbf0..6439fc3d0 100644 --- a/interfaces/kits/js/src/mod_fs/class_watcher/watcher_entity.h +++ b/interfaces/kits/js/src/mod_fs/class_watcher/watcher_entity.h @@ -23,7 +23,8 @@ #include "filemgmt_libn.h" namespace OHOS::FileManagement::ModuleFileIO { using WatcherCallback = void (*)(napi_env env, - LibN::NRef &callback, + // LibN::NRef &callback, + LibN::NVal callbackVal const std::string &filename, const uint32_t &event, const uint32_t &cookie); @@ -33,12 +34,15 @@ struct WatcherInfoArg { uint32_t events = 0; int wd = -1; napi_env env = nullptr; - LibN::NRef nRef; - explicit WatcherInfoArg(LibN::NVal jsVal) : nRef(jsVal) {} - ~WatcherInfoArg() = default; + // LibN::NRef nRef; + LibN::NVal jsCallbackVal = nullptr; + // explicit WatcherInfoArg(LibN::NVal jsVal) : nRef(jsVal) {} + // ~WatcherInfoArg() = default; }; + using WatcherCallbackMap = std::unordered_map, WatcherCallback>>; // using WatcherCallbackMapIter = std::unordered_map, WatcherCallback>>::iterator; +using JSWatcherCallbackMap = std::unordered_map>; class WatcherCallbackContext { public: WatcherCallbackContext() = default; @@ -65,6 +69,7 @@ public: bool StartNotify(std::shared_ptr &arg); bool StopNotify(const std::shared_ptr &arg); void GetNotifyEvent(std::shared_ptr &arg, WatcherCallback callback); + void AddJSWatcherCallbacks(const std::string & fileName, LibN::NVal jsCallbackVal, uint32_t events); private: FileWatcher() = default; @@ -85,6 +90,7 @@ private: WatcherCallbackContext watcherCallbacks_; std::mutex stoppingMutex_; std::condition_variable stoppingLock_; + JSWatcherCallbackMap jsWatcherCallbackMap_; }; struct WatcherEntity { diff --git a/interfaces/kits/js/src/mod_fs/class_watcher/watcher_n_exporter.cpp b/interfaces/kits/js/src/mod_fs/class_watcher/watcher_n_exporter.cpp index 9a87ccbef..1036ad6f4 100644 --- a/interfaces/kits/js/src/mod_fs/class_watcher/watcher_n_exporter.cpp +++ b/interfaces/kits/js/src/mod_fs/class_watcher/watcher_n_exporter.cpp @@ -156,7 +156,7 @@ static void WatcherCallbackComplete(uv_work_t *work, int stat) delete work; } -void WatcherNExporter::WatcherCallback(napi_env env, NRef &callback, const std::string &fileName, +void WatcherNExporter::WatcherCallback(napi_env env, NVal callbackVal, const std::string &fileName, const uint32_t &event, const uint32_t &cookie) { uv_loop_s *loop = nullptr; -- Gitee From df4a9057407afb271c63bd2c8a579f689a4d7690 Mon Sep 17 00:00:00 2001 From: Cao Chuan Date: Sat, 3 Jun 2023 17:47:35 +0800 Subject: [PATCH 03/27] modify callback Signed-off-by: Cao Chuan --- .../mod_fs/class_watcher/watcher_entity.cpp | 165 ++++++++++++++++-- .../src/mod_fs/class_watcher/watcher_entity.h | 21 ++- 2 files changed, 171 insertions(+), 15 deletions(-) diff --git a/interfaces/kits/js/src/mod_fs/class_watcher/watcher_entity.cpp b/interfaces/kits/js/src/mod_fs/class_watcher/watcher_entity.cpp index ace12f24a..04e6512a4 100644 --- a/interfaces/kits/js/src/mod_fs/class_watcher/watcher_entity.cpp +++ b/interfaces/kits/js/src/mod_fs/class_watcher/watcher_entity.cpp @@ -15,6 +15,8 @@ #include "watcher_entity.h" #include +#include +#include #include #include "filemgmt_libhilog.h" @@ -63,12 +65,15 @@ bool FileWatcher::StartNotify(shared_ptr &arg) HILOGE("Failed to start notify fail notifyFd_:%{public}d", notifyFd_); return false; } - int wd = inotify_add_watch(notifyFd_, arg->filename.c_str(), arg->events); + + uint32_t event = ParseEvent(arg->filename.c_str(), arg->events); + int wd = inotify_add_watch(notifyFd_, arg->filename.c_str(), event); if (wd < 0) { HILOGE("Failed to start notify1 fail errCode:%{public}d", errno); return false; } arg->wd = wd; + AddWatcherWdFileNameMap(wd, arg->filename); return true; } @@ -85,13 +90,16 @@ bool FileWatcher::StopNotify(const shared_ptr &arg) // return true; // } - if (inotify_rm_watch(notifyFd_, arg->wd) == -1) { - HILOGE("Failed to stop notify fail errCode:%{public}d", errno); - return false; + //todo 删除callback + RemoveJSWatcherCallback(arg->wd, arg->events, ); + if (GetJSWatcherCallbackSize(arg->wd) == 0) { + if (inotify_rm_watch(notifyFd_, arg->wd) == -1) { + HILOGE("Failed to stop notify fail errCode:%{public}d", errno); + return false; + } } HILOGE("FileWatcher::remove before!"); - watcherCallbacks_.Remove(arg->wd); - if (watcherCallbacks_.Size() == 0) { + if (jsWatcherCallbackMap_.Size() == 0) { close(notifyFd_); notifyFd_ = -1; run_ = false; @@ -166,31 +174,164 @@ bool FileWatcher::WaitForStop() auto status = stoppingLock_.wait_for(lock, std::chrono::milliseconds(STOPPING_WAIT_TIMEOUT_MS)); return status != std::cv_status::timeout; } + void FileWatcher::NotifyStopped() { std::unique_lock lock(stoppingMutex_); stoppingLock_.notify_one(); } +//todo add begin +void FileWatcher::AddSelfEvent(uint32_t &event) +{ + if (!(event & IN_MOVE_SELF)) { + event |= IN_MOVE_SELF; + } + if (!(event & IN_DELETE_SELF)) { + event |= IN_DELETE_SELF; + } + if (!(event & IN_IGNORED)) { + event |= IN_IGNORED; + } +} + +bool FileWatcher::CheckIncludeEvent(const uint32_t &allEvent, const uint32_t &event) +{ + if (allEvent & event) { + return true; + } + return false; +} + +uint32_t FileWatcher::ParseEvent(const std::string &fileName, const uint32_t &watcherEvent) +{ + uint32_t event = watcherEvent; + lock_guard lock(fileNameEventMutex_); + auto iter = fileNameEventMap_.find(fileName); + if (iter == fileNameEventMap_.end()) { + fileNameEventMap_[fileName] = event; + return event; + } else { + if (!CheckIncludeEvent(iter->second, event)) { + event |= iter->second; + fileNameEventMap_[fileName] = event; + return event; + } + } +} + void FileWatcher::AddJSWatcherCallbacks(const string & fileName, NVal jsCallbackVal, uint32_t events) { + lock_guard lock(jsWatcherCallbackMutex_); pair jsCallbackPair = make_pair(jsCallbackVal, events); - if (jsWatcherCallbackMap_.find(fileName) == jsWatcherCallbackMap_.end()) { - vector> jsCallbackVec; - jsCallbackVec.push_back(jsCallbackPair); - jsWatcherCallbackMap_[fileName] = jsCallbackVec; + auto iter = jsWatcherCallbackMap_.find(fileName); + if (iter != jsWatcherCallbackMap_.end()) { + iter->second.push_back(jsCallbackPair); } else { - // TODO + vector> callbacks; + callbacks.push_back(jsCallbackPair); + jsWatcherCallbackMap_[fileName] = callbacks; } - // jsWatcherCallbackMap_ } +bool FileWatcher::CheckSameJSCallback(const LibN::NVal &jsCallbackVal, const LibN::NVal &pairCallback) +{ + //todo 判断是否是同一个callback + return true; +} + +void FileWatcher::RemoveJSWatcherCallback(const int &wd, const uint32_t &watcherEvents, const LibN::NVal jsCallbackVal) +{ + lock_guard lock(jsWatcherCallbackMutex_); + auto fileNameIter = wdFileNameMap_.find(event->wd); + if (fileNameIter == wdFileNameMap_.end()) { + return; + } + string fileName = fileNameIter->second; + auto callbackIter = jsWatcherCallbackMap_.find(fileName); + if (callbackIter == jsWatcherCallbackMap_.end()) { + return; + } + auto callbackPairs = callbackIter->second; + for (auto callbackPair: callbackPairs) { + if (callbackPair->second = watcherEvents) { + if (CheckSameJSCallback(jsCallbackVal, callbackPair->first)) { + jsWatcherCallbackMap_.erase(callbackIter); + } + } + } +} + +int32_t FileWatcher::GetJSWatcherCallbackSize(const int &wd) +{ + lock_guard lock(jsWatcherCallbackMutex_); + auto fileNameIter = wdFileNameMap_(wd); + if (fileNameIter == wdFileNameMap_.end()) { + return 0; + } + string fileName = fileNameIter->second; + auto callbackIter = jsWatcherCallbackMap_.find(fileName); + if (callbackIter == jsWatcherCallbackMap_.end()) { + return 0; + } + return callbackIter->second.size(); +} + +void FileWatcher::NotifyEvent(const struct inotify_event *event) +{ + auto fileNameIter = wdFileNameMap_.find(event->wd); + if (fileNameIter == wdFileNameMap_.end()) { + return; + } + + string fileName = fileNameIter->second; + auto callbackIter = jsWatcherCallbackMap_.find(fileName); + if (callbackIter == jsWatcherCallbackMap_.find()) { + return; + } + + vector> pairs = callbackIter->second; + for (auto pair : pairs) { + uint32_t watchEvent = pair->second; + if (CheckIncludeEvent(event->mask, watchEvent)) { + if (event->len > 0) { + fileName.append(string("/")); + fileName.append(string(event->name)); + } + // todo callback + } + } +} + +void FileWatcher::AddWatcherWdFileNameMap(const int &wd, const string &fileName) +{ + lock_guard lock(watcherWdFiledNameMutex_); + auto it = wdFileNameMap_.find(wd); + if (it == wdFileNameMap_.end()) { + wdFileNameMap_.insert(pair(wd, path)); + } +} + +void FileWatcher::RemoveWatcherWdFileNameMap(const int &wd) +{ + lock_guard lock(watcherWdFiledNameMutex_); + auto pathIter = wdFileNameMap_.find(wd); + if(pathIter != wdFileNameMap_.end()) { + string fileName = pathIter->second; + auto callbackIter = jsWatcherCallbackMap_.find(fileName); + if (callbackIter == jsWatcherCallbackMap_.end()) { + wdFileNameMap_.erase(pathIter); + } + } +} +//todo add end void WatcherCallbackContext::Add(std::shared_ptr &arg, WatcherCallback callback) { lock_guard lock(contextMutex_); pair, WatcherCallback> callbackVal = make_pair(arg, callback); map_[arg->wd] = callbackVal; } + WatcherCallbackMap::iterator WatcherCallbackContext::Get(const int &fd) { lock_guard lock(contextMutex_); diff --git a/interfaces/kits/js/src/mod_fs/class_watcher/watcher_entity.h b/interfaces/kits/js/src/mod_fs/class_watcher/watcher_entity.h index 6439fc3d0..96b538fed 100644 --- a/interfaces/kits/js/src/mod_fs/class_watcher/watcher_entity.h +++ b/interfaces/kits/js/src/mod_fs/class_watcher/watcher_entity.h @@ -15,11 +15,13 @@ #ifndef INTERFACES_KITS_JS_SRC_MOD_FILEIO_CLASS_WATCHER_WATCHER_ENTITY_H #define INTERFACES_KITS_JS_SRC_MOD_FILEIO_CLASS_WATCHER_WATCHER_ENTITY_H #include +#include #include #include #include +#include #include - +#include #include "filemgmt_libn.h" namespace OHOS::FileManagement::ModuleFileIO { using WatcherCallback = void (*)(napi_env env, @@ -42,7 +44,7 @@ struct WatcherInfoArg { using WatcherCallbackMap = std::unordered_map, WatcherCallback>>; // using WatcherCallbackMapIter = std::unordered_map, WatcherCallback>>::iterator; -using JSWatcherCallbackMap = std::unordered_map>; +using JSWatcherCallbackMap = std::map>>; class WatcherCallbackContext { public: WatcherCallbackContext() = default; @@ -81,7 +83,15 @@ private: bool IsVailedWatcherIter(WatcherCallbackMap::iterator &iter); void RemoveWatcher(int &fd); size_t WatcherSize(); - + void AddWatcherWdFileNameMap(const int &wd, const std::string &fileName); + void RemoveWatcherWdFileNameMap(const int &wd); + void RemoveJSWatcherCallback(const int &wd, const uint32_t &watcherEvents, const LibN::NVal jsCallbackVal); + int32_t GetJSWatcherCallbackSize(const int &wd); + void AddSelfEvent(uint32_t &event); + bool CheckIncludeEvent(const uint32_t &allEvent, const uint32_t &event); + uint32_t ParseEvent(const std::string &fileName, const uint32_t &watcherEvent); + void NotifyEvent(const int &wd, const uint32_t &event); + bool CheckSameJSCallback(const LibN::NVal &jsCallbackVal, const LibN::NVal &pairCallback); private: static std::mutex mutex_; static std::shared_ptr instance_; @@ -91,6 +101,11 @@ private: std::mutex stoppingMutex_; std::condition_variable stoppingLock_; JSWatcherCallbackMap jsWatcherCallbackMap_; + std::map wdFileNameMap_; + std::map fileNameEventMap_; + std::mutex watcherWdMutex_; + std::mutex jsWatcherCallbackMutex_; + std::mutex fileNameEventMutex_; }; struct WatcherEntity { -- Gitee From 86d59a6b86c1068b5f4efb6e1275d389ced22e01 Mon Sep 17 00:00:00 2001 From: Cao Chuan Date: Mon, 5 Jun 2023 17:31:27 +0800 Subject: [PATCH 04/27] modify stop Signed-off-by: Cao Chuan --- .../mod_fs/class_watcher/watcher_entity.cpp | 190 +++++++++++++----- .../src/mod_fs/class_watcher/watcher_entity.h | 15 +- 2 files changed, 142 insertions(+), 63 deletions(-) diff --git a/interfaces/kits/js/src/mod_fs/class_watcher/watcher_entity.cpp b/interfaces/kits/js/src/mod_fs/class_watcher/watcher_entity.cpp index 04e6512a4..326259338 100644 --- a/interfaces/kits/js/src/mod_fs/class_watcher/watcher_entity.cpp +++ b/interfaces/kits/js/src/mod_fs/class_watcher/watcher_entity.cpp @@ -14,16 +14,20 @@ */ #include "watcher_entity.h" +#include #include #include #include #include +#include #include "filemgmt_libhilog.h" #include "uv.h" namespace { constexpr int32_t STOPPING_WAIT_TIMEOUT_MS = 5000; constexpr int64_t SELECT_TIME_OUT_US = 100000; + const std::vector EVENT_LIST = {IN_ACCESS, IN_MODIFY, IN_ATTRIB, IN_CLOSE_WRITE, + IN_CLOSE_NOWRITE, IN_CLOSE, IN_OPEN, IN_MOVED_FROM, IN_MOVED_TO, IN_MOVE, IN_CREATE, IN_DELETE, IN_DELETE_SELF, IN_MOVE_SELF}; } // namespace namespace OHOS::FileManagement::ModuleFileIO { @@ -33,6 +37,7 @@ using namespace std; shared_ptr FileWatcher::instance_ = nullptr; mutex FileWatcher::mutex_; + shared_ptr FileWatcher::GetInstance() { if (instance_ == nullptr) { @@ -59,15 +64,57 @@ bool FileWatcher::InitNotify() return true; } +vector GetEvents(uint32_t watchEvent) { + vector list; + for (auto event: EVENT_LIST) { + if (watchEvent & event) { + list.push_back(event); + } + } + return list; +} + +vector FindNotWatchedEvent(const uint32_t &allEvent, const uint32_t &event) +{ + vector notWatchedEvents; + vector allEvents = GetEvents(allEvent); + vector watchEvents = GetEvents(event); + for (auto event: watchEvents) { + auto iter = find(allEvents.begin(), allEvents.end(), event); + if (iter == allEvents.end()) { + notWatchedEvents.push_back(event); + } + } + return notWatchedEvents; +} + +bool FileWatcher::CheckEventWatched(const string &fileName, const uint32_t &event) +{ + std::unique_lock lock(fileNameEventMutex_); + auto iter = fileNameEventMap_.find(fileName); + if (iter == fileNameEventMap_.end()) { + return false; + } + uint32_t allEvent = iter->second; + vector notWatchedEvents = FindNotWatchedEvent(allEvent, event); + if (notWatchedEvents.size() == 0) { + return true; + } + + return false; +} + bool FileWatcher::StartNotify(shared_ptr &arg) { if (notifyFd_ < 0) { HILOGE("Failed to start notify fail notifyFd_:%{public}d", notifyFd_); return false; } - - uint32_t event = ParseEvent(arg->filename.c_str(), arg->events); - int wd = inotify_add_watch(notifyFd_, arg->filename.c_str(), event); + if (CheckEventWatched(arg->filename, arg->events)) { + return true; + } + uint32_t watchEvent = ParseEvent(arg->filename.c_str(), arg->events); + int wd = inotify_add_watch(notifyFd_, arg->filename.c_str(), watchEvent); if (wd < 0) { HILOGE("Failed to start notify1 fail errCode:%{public}d", errno); return false; @@ -77,6 +124,39 @@ bool FileWatcher::StartNotify(shared_ptr &arg) return true; } +bool FileWatcher::NotifyToWatchNewEvents(int &wd) +{ + std::unique_lock lock(watchNewEventMutex_); + auto fileNameIter = wdFileNameMap_.find(wd); + if (fileNameIter == wdFileNameMap_.end()) { + return true; + } + string fileName = fileNameIter->second; + auto callbackIter = jsWatcherCallbackMap_.find(fileName); + if (callbackIter == jsWatcherCallbackMap_.end()) { + return true; + } + vector> callbacks = callbackIter->second; + uint32_t events = 0; + for (auto callback: callbacks) { + events |= callback->second; + } + auto eventIter = fileNameEventMap_.find(fileName); + if (eventIter == fileNameEventMap_.end()) { + return true; + } + fileNameEventMap_.erase(eventIter); + uint32_t watchEvent = ParseEvent(fileName.c_str(), events); + wd = inotify_add_watch(notifyFd_, fileName.c_str(), watchEvent); + if (wd < 0) { + HILOGE("Failed to start notify1 fail errCode:%{public}d", errno); + return false; + } else { + AddWatcherWdFileNameMap(wd, fileName); + return true; + } +} + bool FileWatcher::StopNotify(const shared_ptr &arg) { HILOGE("FileWatcher::StopNotify!"); @@ -85,21 +165,25 @@ bool FileWatcher::StopNotify(const shared_ptr &arg) return false; } - // if (arg.events == IN_DELETE_SELF) { - // close(arg.fd); - // return true; - // } - - //todo 删除callback - RemoveJSWatcherCallback(arg->wd, arg->events, ); + RemoveJSWatcherCallback(arg->wd, arg->events, arg->jsCallbackVal); + bool ret = NotifyToWatchNewEvents(arg->wd); + if (!ret) { + HILOGE("Failed to notify watch new event notifyFd_:%{public}d", notifyFd_); + return false; + } if (GetJSWatcherCallbackSize(arg->wd) == 0) { if (inotify_rm_watch(notifyFd_, arg->wd) == -1) { - HILOGE("Failed to stop notify fail errCode:%{public}d", errno); - return false; + auto iter = wdFileNameMap_.find(arg->wd); + it (iter == wdFileNameMap_.end()) { + return false; + } + string filename = iter->second; + if (access(filename.c_str(), F_OK) == 0) { + HILOGE("Failed to stop notify fail errCode:%{public}d", errno); + return false; + } } - } - HILOGE("FileWatcher::remove before!"); - if (jsWatcherCallbackMap_.Size() == 0) { + close(notifyFd_); notifyFd_ = -1; run_ = false; @@ -110,7 +194,7 @@ bool FileWatcher::StopNotify(const shared_ptr &arg) } return true; } - return false; + return true; } void FileWatcher::HandleEvent(const struct inotify_event *event) @@ -134,8 +218,6 @@ void FileWatcher::HandleEvent(const struct inotify_event *event) void FileWatcher::GetNotifyEvent(shared_ptr &arg, WatcherCallback callback) { - watcherCallbacks_.Add(arg, callback); - if (run_) { HILOGE("Listener Thread has started and do nothing!"); return; @@ -168,6 +250,7 @@ void FileWatcher::GetNotifyEvent(shared_ptr &arg, WatcherCallbac } HILOGE("Listener Thread has stopped!"); } + bool FileWatcher::WaitForStop() { std::unique_lock lock(stoppingMutex_); @@ -182,40 +265,24 @@ void FileWatcher::NotifyStopped() } //todo add begin -void FileWatcher::AddSelfEvent(uint32_t &event) -{ - if (!(event & IN_MOVE_SELF)) { - event |= IN_MOVE_SELF; - } - if (!(event & IN_DELETE_SELF)) { - event |= IN_DELETE_SELF; - } - if (!(event & IN_IGNORED)) { - event |= IN_IGNORED; - } -} - -bool FileWatcher::CheckIncludeEvent(const uint32_t &allEvent, const uint32_t &event) -{ - if (allEvent & event) { - return true; - } - return false; -} - uint32_t FileWatcher::ParseEvent(const std::string &fileName, const uint32_t &watcherEvent) { - uint32_t event = watcherEvent; lock_guard lock(fileNameEventMutex_); + uint32_t event = watcherEvent; auto iter = fileNameEventMap_.find(fileName); if (iter == fileNameEventMap_.end()) { fileNameEventMap_[fileName] = event; return event; } else { - if (!CheckIncludeEvent(iter->second, event)) { - event |= iter->second; + vector notWatchedEvents = FindNotWatchedEvent(iter->second, event); + if (notWatchedEvents.size() > 0) { + for (auto notWatchedEvent: notWatchedEvents) { + event |= iter->notWatchedEvent; + } fileNameEventMap_[fileName] = event; return event; + } else { + return iter->second; } } } @@ -234,13 +301,13 @@ void FileWatcher::AddJSWatcherCallbacks(const string & fileName, NVal jsCallback } } -bool FileWatcher::CheckSameJSCallback(const LibN::NVal &jsCallbackVal, const LibN::NVal &pairCallback) +bool FileWatcher::CheckSameJSCallback(const NVal &jsCallbackVal, const NVal &pairCallback) { //todo 判断是否是同一个callback return true; } -void FileWatcher::RemoveJSWatcherCallback(const int &wd, const uint32_t &watcherEvents, const LibN::NVal jsCallbackVal) +void FileWatcher::RemoveJSWatcherCallback(const int &wd, const uint32_t &watcherEvent, const NVal jsCallbackVal) { lock_guard lock(jsWatcherCallbackMutex_); auto fileNameIter = wdFileNameMap_.find(event->wd); @@ -254,7 +321,7 @@ void FileWatcher::RemoveJSWatcherCallback(const int &wd, const uint32_t &watcher } auto callbackPairs = callbackIter->second; for (auto callbackPair: callbackPairs) { - if (callbackPair->second = watcherEvents) { + if (callbackPair->second == watcherEvent) { if (CheckSameJSCallback(jsCallbackVal, callbackPair->first)) { jsWatcherCallbackMap_.erase(callbackIter); } @@ -265,7 +332,7 @@ void FileWatcher::RemoveJSWatcherCallback(const int &wd, const uint32_t &watcher int32_t FileWatcher::GetJSWatcherCallbackSize(const int &wd) { lock_guard lock(jsWatcherCallbackMutex_); - auto fileNameIter = wdFileNameMap_(wd); + auto fileNameIter = wdFileNameMap_.find(wd); if (fileNameIter == wdFileNameMap_.end()) { return 0; } @@ -277,8 +344,20 @@ int32_t FileWatcher::GetJSWatcherCallbackSize(const int &wd) return callbackIter->second.size(); } +bool CheckIncludeEvent(const uint32_t &allEvent, const uint32_t &event) +{ + vector events = GetEvents(); + for (auto event : events) { + if (allEvent & event) { + return true; + } + } + return false; +} + void FileWatcher::NotifyEvent(const struct inotify_event *event) { + lock_guard lock(notifyMutex_); auto fileNameIter = wdFileNameMap_.find(event->wd); if (fileNameIter == wdFileNameMap_.end()) { return; @@ -286,20 +365,21 @@ void FileWatcher::NotifyEvent(const struct inotify_event *event) string fileName = fileNameIter->second; auto callbackIter = jsWatcherCallbackMap_.find(fileName); - if (callbackIter == jsWatcherCallbackMap_.find()) { + if (callbackIter == jsWatcherCallbackMap_.end()) { return; } - vector> pairs = callbackIter->second; + vector> pairs = callbackIter->second; for (auto pair : pairs) { uint32_t watchEvent = pair->second; - if (CheckIncludeEvent(event->mask, watchEvent)) { - if (event->len > 0) { - fileName.append(string("/")); - fileName.append(string(event->name)); - } - // todo callback + if (!CheckIncludeEvent(event->mask, watchEvent)) { + return; + } + if (event->len > 0) { + fileName.append(string("/")); + fileName.append(string(event->name)); } + // todo callback } } @@ -308,7 +388,7 @@ void FileWatcher::AddWatcherWdFileNameMap(const int &wd, const string &fileName) lock_guard lock(watcherWdFiledNameMutex_); auto it = wdFileNameMap_.find(wd); if (it == wdFileNameMap_.end()) { - wdFileNameMap_.insert(pair(wd, path)); + wdFileNameMap_.insert(pair(wd, path));0 } } diff --git a/interfaces/kits/js/src/mod_fs/class_watcher/watcher_entity.h b/interfaces/kits/js/src/mod_fs/class_watcher/watcher_entity.h index 96b538fed..26c17b899 100644 --- a/interfaces/kits/js/src/mod_fs/class_watcher/watcher_entity.h +++ b/interfaces/kits/js/src/mod_fs/class_watcher/watcher_entity.h @@ -79,19 +79,16 @@ private: bool WaitForStop(); void NotifyStopped(); void AddWatcher(std::shared_ptr &arg, WatcherCallback callback); - WatcherCallbackMap::iterator GetWatcher(int &fd); - bool IsVailedWatcherIter(WatcherCallbackMap::iterator &iter); - void RemoveWatcher(int &fd); - size_t WatcherSize(); void AddWatcherWdFileNameMap(const int &wd, const std::string &fileName); void RemoveWatcherWdFileNameMap(const int &wd); - void RemoveJSWatcherCallback(const int &wd, const uint32_t &watcherEvents, const LibN::NVal jsCallbackVal); + void RemoveJSWatcherCallback(const int &wd, const uint32_t &watcherEvent, const LibN::NVal jsCallbackVal); int32_t GetJSWatcherCallbackSize(const int &wd); - void AddSelfEvent(uint32_t &event); - bool CheckIncludeEvent(const uint32_t &allEvent, const uint32_t &event); + bool CheckEventWatched(const std::string &fileName, const uint32_t &event); uint32_t ParseEvent(const std::string &fileName, const uint32_t &watcherEvent); void NotifyEvent(const int &wd, const uint32_t &event); bool CheckSameJSCallback(const LibN::NVal &jsCallbackVal, const LibN::NVal &pairCallback); + bool NotifyToWatchNewEvents(int &wd); + bool AddWatchEvent(const std::string &fileName, const uint32_t &events, int &watchWd); private: static std::mutex mutex_; static std::shared_ptr instance_; @@ -103,9 +100,11 @@ private: JSWatcherCallbackMap jsWatcherCallbackMap_; std::map wdFileNameMap_; std::map fileNameEventMap_; - std::mutex watcherWdMutex_; + std::mutex watcherWdFiledNameMutex_; std::mutex jsWatcherCallbackMutex_; std::mutex fileNameEventMutex_; + std::mutex notifyMutex_; + std::mutex watchNewEventMutex_; }; struct WatcherEntity { -- Gitee From a2ab40e9b96c8cb8a9d5112e08ee4a9a3ffec17b Mon Sep 17 00:00:00 2001 From: Cao Chuan Date: Tue, 6 Jun 2023 08:32:25 +0800 Subject: [PATCH 05/27] modify 0 error Signed-off-by: Cao Chuan --- interfaces/kits/js/src/mod_fs/class_watcher/watcher_entity.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interfaces/kits/js/src/mod_fs/class_watcher/watcher_entity.cpp b/interfaces/kits/js/src/mod_fs/class_watcher/watcher_entity.cpp index 326259338..0da474a9c 100644 --- a/interfaces/kits/js/src/mod_fs/class_watcher/watcher_entity.cpp +++ b/interfaces/kits/js/src/mod_fs/class_watcher/watcher_entity.cpp @@ -388,7 +388,7 @@ void FileWatcher::AddWatcherWdFileNameMap(const int &wd, const string &fileName) lock_guard lock(watcherWdFiledNameMutex_); auto it = wdFileNameMap_.find(wd); if (it == wdFileNameMap_.end()) { - wdFileNameMap_.insert(pair(wd, path));0 + wdFileNameMap_.insert(pair(wd, path)); } } -- Gitee From 924593ca660616a9932c82e44500cc4ceef4186b Mon Sep 17 00:00:00 2001 From: Cao Chuan Date: Tue, 6 Jun 2023 15:51:33 +0800 Subject: [PATCH 06/27] Add JS callback list in watcher Signed-off-by: Cao Chuan --- .../mod_fs/class_watcher/watcher_entity.cpp | 22 ++++++++++++++++++- .../src/mod_fs/class_watcher/watcher_entity.h | 8 +++---- .../class_watcher/watcher_n_exporter.cpp | 2 +- .../kits/js/src/mod_fs/properties/watcher.cpp | 6 ++++- utils/filemgmt_libn/include/n_val.h | 14 ++++++++++++ 5 files changed, 45 insertions(+), 7 deletions(-) diff --git a/interfaces/kits/js/src/mod_fs/class_watcher/watcher_entity.cpp b/interfaces/kits/js/src/mod_fs/class_watcher/watcher_entity.cpp index 0da474a9c..2c41fd011 100644 --- a/interfaces/kits/js/src/mod_fs/class_watcher/watcher_entity.cpp +++ b/interfaces/kits/js/src/mod_fs/class_watcher/watcher_entity.cpp @@ -213,7 +213,8 @@ void FileWatcher::HandleEvent(const struct inotify_event *event) } auto callback = iter->second.second; - callback(arg->env, arg->nRef, fileName, event->mask, event->cookie); + NRef nRef(arg->jsCallbackVal); + callback(arg->env, nRef, fileName, event->mask, event->cookie); } void FileWatcher::GetNotifyEvent(shared_ptr &arg, WatcherCallback callback) @@ -264,6 +265,25 @@ void FileWatcher::NotifyStopped() stoppingLock_.notify_one(); } +void FileWatcher::AddJsCbList(const string &fileName, NVal jsCallbackVal, uint32_t events) +{ + unique_lock lock(jsCbsLock_); + JSWatcherCallbackMap::iterator it = jsWatcherCallbackMap_.find(fileName); + if (it == jsWatcherCallbackMap_.end()) { + vector> jsCallbackVec = { make_pair(jsCallbackVal, events) }; + jsWatcherCallbackMap_[fileName] = jsCallbackVec; + return; + } + + auto jsCallbacks = it->second; + for (auto &callback : jsCallbacks) { + if (jsCallbackVal == callback.first && events == callback.second) { + return; + } + } + it->second.push_back(make_pair(jsCallbackVal, events)); +} + //todo add begin uint32_t FileWatcher::ParseEvent(const std::string &fileName, const uint32_t &watcherEvent) { diff --git a/interfaces/kits/js/src/mod_fs/class_watcher/watcher_entity.h b/interfaces/kits/js/src/mod_fs/class_watcher/watcher_entity.h index 26c17b899..deb127cde 100644 --- a/interfaces/kits/js/src/mod_fs/class_watcher/watcher_entity.h +++ b/interfaces/kits/js/src/mod_fs/class_watcher/watcher_entity.h @@ -25,8 +25,7 @@ #include "filemgmt_libn.h" namespace OHOS::FileManagement::ModuleFileIO { using WatcherCallback = void (*)(napi_env env, - // LibN::NRef &callback, - LibN::NVal callbackVal + LibN::NRef &callback, const std::string &filename, const uint32_t &event, const uint32_t &cookie); @@ -37,7 +36,7 @@ struct WatcherInfoArg { int wd = -1; napi_env env = nullptr; // LibN::NRef nRef; - LibN::NVal jsCallbackVal = nullptr; + LibN::NVal jsCallbackVal; // explicit WatcherInfoArg(LibN::NVal jsVal) : nRef(jsVal) {} // ~WatcherInfoArg() = default; }; @@ -71,7 +70,7 @@ public: bool StartNotify(std::shared_ptr &arg); bool StopNotify(const std::shared_ptr &arg); void GetNotifyEvent(std::shared_ptr &arg, WatcherCallback callback); - void AddJSWatcherCallbacks(const std::string & fileName, LibN::NVal jsCallbackVal, uint32_t events); + void AddJsCbList(const std::string & fileName, LibN::NVal jsCallbackVal, uint32_t events); private: FileWatcher() = default; @@ -97,6 +96,7 @@ private: WatcherCallbackContext watcherCallbacks_; std::mutex stoppingMutex_; std::condition_variable stoppingLock_; + std::mutex jsCbsLock_; JSWatcherCallbackMap jsWatcherCallbackMap_; std::map wdFileNameMap_; std::map fileNameEventMap_; diff --git a/interfaces/kits/js/src/mod_fs/class_watcher/watcher_n_exporter.cpp b/interfaces/kits/js/src/mod_fs/class_watcher/watcher_n_exporter.cpp index 1036ad6f4..9a87ccbef 100644 --- a/interfaces/kits/js/src/mod_fs/class_watcher/watcher_n_exporter.cpp +++ b/interfaces/kits/js/src/mod_fs/class_watcher/watcher_n_exporter.cpp @@ -156,7 +156,7 @@ static void WatcherCallbackComplete(uv_work_t *work, int stat) delete work; } -void WatcherNExporter::WatcherCallback(napi_env env, NVal callbackVal, const std::string &fileName, +void WatcherNExporter::WatcherCallback(napi_env env, NRef &callback, const std::string &fileName, const uint32_t &event, const uint32_t &cookie) { uv_loop_s *loop = nullptr; diff --git a/interfaces/kits/js/src/mod_fs/properties/watcher.cpp b/interfaces/kits/js/src/mod_fs/properties/watcher.cpp index 8a03b72b1..83fa38ad6 100644 --- a/interfaces/kits/js/src/mod_fs/properties/watcher.cpp +++ b/interfaces/kits/js/src/mod_fs/properties/watcher.cpp @@ -88,14 +88,18 @@ HILOGE("CreateWatcher notifyFd_2: %{public}d", FileWatcher::GetInstance()->GetNo return nullptr; } - watcherEntity->data_ = make_shared(NVal(env, funcArg[NARG_POS::THIRD])); + // watcherEntity->data_ = make_shared(NVal(env, funcArg[NARG_POS::THIRD])); + watcherEntity->data_ = make_shared(); watcherEntity->data_->events = events; watcherEntity->data_->env = env; watcherEntity->data_->filename = string(filename.get()); + watcherEntity->data_->jsCallbackVal = NVal(env, funcArg[NARG_POS::THIRD]); // watcherEntity->data_->fd = fd; // watcherEntity->watcherPtr_ = watcherPtr_; + FileWatcher::GetInstance()->AddJsCbList(string(filename.get()), NVal(env, funcArg[NARG_POS::THIRD]), events); + return objWatcher; } } // namespace OHOS::FileManagement::ModuleFileIO diff --git a/utils/filemgmt_libn/include/n_val.h b/utils/filemgmt_libn/include/n_val.h index 02e98b18e..3ff6d32df 100644 --- a/utils/filemgmt_libn/include/n_val.h +++ b/utils/filemgmt_libn/include/n_val.h @@ -32,6 +32,20 @@ public: NVal(napi_env nEnv, napi_value nVal); NVal(const NVal &) = default; NVal &operator=(const NVal &) = default; + bool operator==(const NVal &nVal) const + { + if (!*this) { + return false; + } + + if (nVal.env_ == nullptr) { + return false; + } + + bool res = false; + napi_strict_equals(env_, val_, nVal.val_, &res); + return res; + } virtual ~NVal() = default; /* NOTE! env_ and val_ is LIKELY to be null */ -- Gitee From d70119452d92f4ec51751ae747197c3982d70d21 Mon Sep 17 00:00:00 2001 From: Cao Chuan Date: Wed, 7 Jun 2023 10:31:48 +0800 Subject: [PATCH 07/27] Change js callback list style Signed-off-by: Cao Chuan --- .../mod_fs/class_watcher/watcher_entity.cpp | 46 ++++++++++--------- .../src/mod_fs/class_watcher/watcher_entity.h | 15 +++--- .../kits/js/src/mod_fs/properties/watcher.cpp | 17 +++---- utils/filemgmt_libn/include/n_val.h | 14 ------ 4 files changed, 37 insertions(+), 55 deletions(-) diff --git a/interfaces/kits/js/src/mod_fs/class_watcher/watcher_entity.cpp b/interfaces/kits/js/src/mod_fs/class_watcher/watcher_entity.cpp index 2c41fd011..84e5612a4 100644 --- a/interfaces/kits/js/src/mod_fs/class_watcher/watcher_entity.cpp +++ b/interfaces/kits/js/src/mod_fs/class_watcher/watcher_entity.cpp @@ -26,7 +26,7 @@ namespace { constexpr int32_t STOPPING_WAIT_TIMEOUT_MS = 5000; constexpr int64_t SELECT_TIME_OUT_US = 100000; - const std::vector EVENT_LIST = {IN_ACCESS, IN_MODIFY, IN_ATTRIB, IN_CLOSE_WRITE, + const vector EVENT_LIST = {IN_ACCESS, IN_MODIFY, IN_ATTRIB, IN_CLOSE_WRITE, IN_CLOSE_NOWRITE, IN_CLOSE, IN_OPEN, IN_MOVED_FROM, IN_MOVED_TO, IN_MOVE, IN_CREATE, IN_DELETE, IN_DELETE_SELF, IN_MOVE_SELF}; } // namespace @@ -90,7 +90,7 @@ vector FindNotWatchedEvent(const uint32_t &allEvent, const uint32_t &e bool FileWatcher::CheckEventWatched(const string &fileName, const uint32_t &event) { - std::unique_lock lock(fileNameEventMutex_); + unique_lock lock(fileNameEventMutex_); auto iter = fileNameEventMap_.find(fileName); if (iter == fileNameEventMap_.end()) { return false; @@ -126,7 +126,7 @@ bool FileWatcher::StartNotify(shared_ptr &arg) bool FileWatcher::NotifyToWatchNewEvents(int &wd) { - std::unique_lock lock(watchNewEventMutex_); + unique_lock lock(watchNewEventMutex_); auto fileNameIter = wdFileNameMap_.find(wd); if (fileNameIter == wdFileNameMap_.end()) { return true; @@ -213,8 +213,7 @@ void FileWatcher::HandleEvent(const struct inotify_event *event) } auto callback = iter->second.second; - NRef nRef(arg->jsCallbackVal); - callback(arg->env, nRef, fileName, event->mask, event->cookie); + callback(arg->env, arg->nRef, fileName, event->mask, event->cookie); } void FileWatcher::GetNotifyEvent(shared_ptr &arg, WatcherCallback callback) @@ -254,38 +253,41 @@ void FileWatcher::GetNotifyEvent(shared_ptr &arg, WatcherCallbac bool FileWatcher::WaitForStop() { - std::unique_lock lock(stoppingMutex_); - auto status = stoppingLock_.wait_for(lock, std::chrono::milliseconds(STOPPING_WAIT_TIMEOUT_MS)); - return status != std::cv_status::timeout; + unique_lock lock(stoppingMutex_); + auto status = stoppingLock_.wait_for(lock, chrono::milliseconds(STOPPING_WAIT_TIMEOUT_MS)); + return status != cv_status::timeout; } void FileWatcher::NotifyStopped() { - std::unique_lock lock(stoppingMutex_); + unique_lock lock(stoppingMutex_); stoppingLock_.notify_one(); } -void FileWatcher::AddJsCbList(const string &fileName, NVal jsCallbackVal, uint32_t events) +void FileWatcher::AddWatcherInfoList(const string &fileName, const shared_ptr &arg) { - unique_lock lock(jsCbsLock_); - JSWatcherCallbackMap::iterator it = jsWatcherCallbackMap_.find(fileName); - if (it == jsWatcherCallbackMap_.end()) { - vector> jsCallbackVec = { make_pair(jsCallbackVal, events) }; - jsWatcherCallbackMap_[fileName] = jsCallbackVec; + unique_lock lock(watcherInfosLock_); + WatcherInfoList::iterator it = watcherInfoList_.find(fileName); + if (it == watcherInfoList_.end()) { + vector> watcherInfoVec = { arg }; + watcherInfoList_[fileName] = watcherInfoVec; return; } - auto jsCallbacks = it->second; - for (auto &callback : jsCallbacks) { - if (jsCallbackVal == callback.first && events == callback.second) { + auto watcherInfos = it->second; + for (auto &info : watcherInfos) { + bool isSame = false; + napi_strict_equals(info->env, info->nRef.Deref(info->env).val_, arg->nRef.Deref(arg->env).val_, &isSame); +HILOGE("AddWatcherInfoList isSame: %{public}d", isSame); + if (isSame && info->events == arg->events) { return; } } - it->second.push_back(make_pair(jsCallbackVal, events)); + it->second.push_back(arg); } //todo add begin -uint32_t FileWatcher::ParseEvent(const std::string &fileName, const uint32_t &watcherEvent) +uint32_t FileWatcher::ParseEvent(const string &fileName, const uint32_t &watcherEvent) { lock_guard lock(fileNameEventMutex_); uint32_t event = watcherEvent; @@ -389,7 +391,7 @@ void FileWatcher::NotifyEvent(const struct inotify_event *event) return; } - vector> pairs = callbackIter->second; + vector> pairs = callbackIter->second; for (auto pair : pairs) { uint32_t watchEvent = pair->second; if (!CheckIncludeEvent(event->mask, watchEvent)) { @@ -425,7 +427,7 @@ void FileWatcher::RemoveWatcherWdFileNameMap(const int &wd) } } //todo add end -void WatcherCallbackContext::Add(std::shared_ptr &arg, WatcherCallback callback) +void WatcherCallbackContext::Add(shared_ptr &arg, WatcherCallback callback) { lock_guard lock(contextMutex_); pair, WatcherCallback> callbackVal = make_pair(arg, callback); diff --git a/interfaces/kits/js/src/mod_fs/class_watcher/watcher_entity.h b/interfaces/kits/js/src/mod_fs/class_watcher/watcher_entity.h index deb127cde..07623ed0f 100644 --- a/interfaces/kits/js/src/mod_fs/class_watcher/watcher_entity.h +++ b/interfaces/kits/js/src/mod_fs/class_watcher/watcher_entity.h @@ -35,15 +35,14 @@ struct WatcherInfoArg { uint32_t events = 0; int wd = -1; napi_env env = nullptr; - // LibN::NRef nRef; - LibN::NVal jsCallbackVal; - // explicit WatcherInfoArg(LibN::NVal jsVal) : nRef(jsVal) {} - // ~WatcherInfoArg() = default; + LibN::NRef nRef; + explicit WatcherInfoArg(LibN::NVal jsVal) : nRef(jsVal) {} + ~WatcherInfoArg() = default; }; using WatcherCallbackMap = std::unordered_map, WatcherCallback>>; // using WatcherCallbackMapIter = std::unordered_map, WatcherCallback>>::iterator; -using JSWatcherCallbackMap = std::map>>; +using WatcherInfoList = std::unordered_map>>; class WatcherCallbackContext { public: WatcherCallbackContext() = default; @@ -70,7 +69,7 @@ public: bool StartNotify(std::shared_ptr &arg); bool StopNotify(const std::shared_ptr &arg); void GetNotifyEvent(std::shared_ptr &arg, WatcherCallback callback); - void AddJsCbList(const std::string & fileName, LibN::NVal jsCallbackVal, uint32_t events); + void AddWatcherInfoList(const std::string &fileName, const std::shared_ptr &arg); private: FileWatcher() = default; @@ -96,8 +95,8 @@ private: WatcherCallbackContext watcherCallbacks_; std::mutex stoppingMutex_; std::condition_variable stoppingLock_; - std::mutex jsCbsLock_; - JSWatcherCallbackMap jsWatcherCallbackMap_; + std::mutex watcherInfosLock_; + WatcherInfoList watcherInfoList_; std::map wdFileNameMap_; std::map fileNameEventMap_; std::mutex watcherWdFiledNameMutex_; diff --git a/interfaces/kits/js/src/mod_fs/properties/watcher.cpp b/interfaces/kits/js/src/mod_fs/properties/watcher.cpp index 83fa38ad6..5448bd054 100644 --- a/interfaces/kits/js/src/mod_fs/properties/watcher.cpp +++ b/interfaces/kits/js/src/mod_fs/properties/watcher.cpp @@ -88,17 +88,12 @@ HILOGE("CreateWatcher notifyFd_2: %{public}d", FileWatcher::GetInstance()->GetNo return nullptr; } - // watcherEntity->data_ = make_shared(NVal(env, funcArg[NARG_POS::THIRD])); - watcherEntity->data_ = make_shared(); - watcherEntity->data_->events = events; - watcherEntity->data_->env = env; - watcherEntity->data_->filename = string(filename.get()); - watcherEntity->data_->jsCallbackVal = NVal(env, funcArg[NARG_POS::THIRD]); - // watcherEntity->data_->fd = fd; - - // watcherEntity->watcherPtr_ = watcherPtr_; - - FileWatcher::GetInstance()->AddJsCbList(string(filename.get()), NVal(env, funcArg[NARG_POS::THIRD]), events); + auto infoArg = make_shared(NVal(env, funcArg[NARG_POS::THIRD])); + infoArg->events = events; + infoArg->env = env; + infoArg->filename = string(filename.get()); + watcherEntity->data_ = infoArg; + FileWatcher::GetInstance()->AddWatcherInfoList(string(filename.get()), infoArg); return objWatcher; } diff --git a/utils/filemgmt_libn/include/n_val.h b/utils/filemgmt_libn/include/n_val.h index 3ff6d32df..02e98b18e 100644 --- a/utils/filemgmt_libn/include/n_val.h +++ b/utils/filemgmt_libn/include/n_val.h @@ -32,20 +32,6 @@ public: NVal(napi_env nEnv, napi_value nVal); NVal(const NVal &) = default; NVal &operator=(const NVal &) = default; - bool operator==(const NVal &nVal) const - { - if (!*this) { - return false; - } - - if (nVal.env_ == nullptr) { - return false; - } - - bool res = false; - napi_strict_equals(env_, val_, nVal.val_, &res); - return res; - } virtual ~NVal() = default; /* NOTE! env_ and val_ is LIKELY to be null */ -- Gitee From 7b442a77e10d3db54dd2999311b205f5e878573f Mon Sep 17 00:00:00 2001 From: Cao Chuan Date: Thu, 8 Jun 2023 12:19:02 +0800 Subject: [PATCH 08/27] Change some func Signed-off-by: Cao Chuan --- .../mod_fs/class_watcher/watcher_entity.cpp | 128 ++++++++---------- .../src/mod_fs/class_watcher/watcher_entity.h | 4 +- 2 files changed, 60 insertions(+), 72 deletions(-) diff --git a/interfaces/kits/js/src/mod_fs/class_watcher/watcher_entity.cpp b/interfaces/kits/js/src/mod_fs/class_watcher/watcher_entity.cpp index 84e5612a4..d9718177b 100644 --- a/interfaces/kits/js/src/mod_fs/class_watcher/watcher_entity.cpp +++ b/interfaces/kits/js/src/mod_fs/class_watcher/watcher_entity.cpp @@ -23,21 +23,22 @@ #include "filemgmt_libhilog.h" #include "uv.h" -namespace { - constexpr int32_t STOPPING_WAIT_TIMEOUT_MS = 5000; - constexpr int64_t SELECT_TIME_OUT_US = 100000; - const vector EVENT_LIST = {IN_ACCESS, IN_MODIFY, IN_ATTRIB, IN_CLOSE_WRITE, - IN_CLOSE_NOWRITE, IN_CLOSE, IN_OPEN, IN_MOVED_FROM, IN_MOVED_TO, IN_MOVE, IN_CREATE, IN_DELETE, IN_DELETE_SELF, IN_MOVE_SELF}; -} // namespace namespace OHOS::FileManagement::ModuleFileIO { using namespace OHOS::FileManagement::LibN; using namespace std; +namespace { + constexpr int32_t STOPPING_WAIT_TIMEOUT_MS = 5000; + constexpr int64_t SELECT_TIME_OUT_US = 100000; + const vector EVENT_LIST = { IN_ACCESS, IN_MODIFY, IN_ATTRIB, IN_CLOSE_WRITE, IN_CLOSE_NOWRITE, + IN_CLOSE, IN_OPEN, IN_MOVED_FROM, IN_MOVED_TO, IN_MOVE, + IN_CREATE, IN_DELETE, IN_DELETE_SELF, IN_MOVE_SELF }; +} // namespace + shared_ptr FileWatcher::instance_ = nullptr; mutex FileWatcher::mutex_; - shared_ptr FileWatcher::GetInstance() { if (instance_ == nullptr) { @@ -64,28 +65,29 @@ bool FileWatcher::InitNotify() return true; } -vector GetEvents(uint32_t watchEvent) { - vector list; - for (auto event: EVENT_LIST) { +vector GetEvents(const uint32_t &watchEvent) +{ + vector eventList; + for (auto event : EVENT_LIST) { if (watchEvent & event) { - list.push_back(event); + eventList.push_back(event); } } - return list; + return eventList; } -vector FindNotWatchedEvent(const uint32_t &allEvent, const uint32_t &event) +vector FindUnwatchedEvent(const uint32_t &allEvent, const uint32_t &event) { - vector notWatchedEvents; + vector unWatchedEvents; vector allEvents = GetEvents(allEvent); vector watchEvents = GetEvents(event); for (auto event: watchEvents) { auto iter = find(allEvents.begin(), allEvents.end(), event); if (iter == allEvents.end()) { - notWatchedEvents.push_back(event); + unWatchedEvents.push_back(event); } } - return notWatchedEvents; + return unWatchedEvents; } bool FileWatcher::CheckEventWatched(const string &fileName, const uint32_t &event) @@ -96,11 +98,11 @@ bool FileWatcher::CheckEventWatched(const string &fileName, const uint32_t &even return false; } uint32_t allEvent = iter->second; - vector notWatchedEvents = FindNotWatchedEvent(allEvent, event); - if (notWatchedEvents.size() == 0) { + vector unWatchedEvents = FindUnwatchedEvent(allEvent, event); + if (unWatchedEvents.size() == 0) { return true; } - + return false; } @@ -132,14 +134,14 @@ bool FileWatcher::NotifyToWatchNewEvents(int &wd) return true; } string fileName = fileNameIter->second; - auto callbackIter = jsWatcherCallbackMap_.find(fileName); - if (callbackIter == jsWatcherCallbackMap_.end()) { + auto watcherInfosIter = watcherInfoList_.find(fileName); + if (watcherInfosIter == watcherInfoList_.end()) { return true; } - vector> callbacks = callbackIter->second; + auto args = watcherInfosIter->second; uint32_t events = 0; - for (auto callback: callbacks) { - events |= callback->second; + for (auto arg : args) { + events |= arg->events; } auto eventIter = fileNameEventMap_.find(fileName); if (eventIter == fileNameEventMap_.end()) { @@ -165,7 +167,7 @@ bool FileWatcher::StopNotify(const shared_ptr &arg) return false; } - RemoveJSWatcherCallback(arg->wd, arg->events, arg->jsCallbackVal); + RemoveJSWatcherCallback(arg); bool ret = NotifyToWatchNewEvents(arg->wd); if (!ret) { HILOGE("Failed to notify watch new event notifyFd_:%{public}d", notifyFd_); @@ -174,7 +176,7 @@ bool FileWatcher::StopNotify(const shared_ptr &arg) if (GetJSWatcherCallbackSize(arg->wd) == 0) { if (inotify_rm_watch(notifyFd_, arg->wd) == -1) { auto iter = wdFileNameMap_.find(arg->wd); - it (iter == wdFileNameMap_.end()) { + if (iter == wdFileNameMap_.end()) { return false; } string filename = iter->second; @@ -296,10 +298,10 @@ uint32_t FileWatcher::ParseEvent(const string &fileName, const uint32_t &watcher fileNameEventMap_[fileName] = event; return event; } else { - vector notWatchedEvents = FindNotWatchedEvent(iter->second, event); + vector notWatchedEvents = FindUnwatchedEvent(iter->second, event); if (notWatchedEvents.size() > 0) { for (auto notWatchedEvent: notWatchedEvents) { - event |= iter->notWatchedEvent; + event |= notWatchedEvent; } fileNameEventMap_[fileName] = event; return event; @@ -309,43 +311,26 @@ uint32_t FileWatcher::ParseEvent(const string &fileName, const uint32_t &watcher } } -void FileWatcher::AddJSWatcherCallbacks(const string & fileName, NVal jsCallbackVal, uint32_t events) +void FileWatcher::RemoveJSWatcherCallback(const shared_ptr &arg) { lock_guard lock(jsWatcherCallbackMutex_); - pair jsCallbackPair = make_pair(jsCallbackVal, events); - auto iter = jsWatcherCallbackMap_.find(fileName); - if (iter != jsWatcherCallbackMap_.end()) { - iter->second.push_back(jsCallbackPair); - } else { - vector> callbacks; - callbacks.push_back(jsCallbackPair); - jsWatcherCallbackMap_[fileName] = callbacks; - } -} - -bool FileWatcher::CheckSameJSCallback(const NVal &jsCallbackVal, const NVal &pairCallback) -{ - //todo 判断是否是同一个callback - return true; -} - -void FileWatcher::RemoveJSWatcherCallback(const int &wd, const uint32_t &watcherEvent, const NVal jsCallbackVal) -{ - lock_guard lock(jsWatcherCallbackMutex_); - auto fileNameIter = wdFileNameMap_.find(event->wd); + auto fileNameIter = wdFileNameMap_.find(arg->wd); if (fileNameIter == wdFileNameMap_.end()) { - return; + return; } string fileName = fileNameIter->second; - auto callbackIter = jsWatcherCallbackMap_.find(fileName); - if (callbackIter == jsWatcherCallbackMap_.end()) { + auto iter = watcherInfoList_.find(fileName); + if (iter == watcherInfoList_.end()) { return; } - auto callbackPairs = callbackIter->second; - for (auto callbackPair: callbackPairs) { - if (callbackPair->second == watcherEvent) { - if (CheckSameJSCallback(jsCallbackVal, callbackPair->first)) { - jsWatcherCallbackMap_.erase(callbackIter); + auto infoArgs = iter->second; + for (size_t i = 0; i < infoArgs.size(); i++) { + if (infoArgs[i]->events == arg->events) { + bool isSame = false; + napi_strict_equals(infoArgs[i]->env, infoArgs[i]->nRef.Deref(infoArgs[i]->env).val_, + arg->nRef.Deref(arg->env).val_, &isSame); + if (isSame) { + iter->second.erase(iter->second.begin() + i); } } } @@ -359,16 +344,16 @@ int32_t FileWatcher::GetJSWatcherCallbackSize(const int &wd) return 0; } string fileName = fileNameIter->second; - auto callbackIter = jsWatcherCallbackMap_.find(fileName); - if (callbackIter == jsWatcherCallbackMap_.end()) { + auto watcherInfosIter = watcherInfoList_.find(fileName); + if (watcherInfosIter == watcherInfoList_.end()) { return 0; } - return callbackIter->second.size(); + return watcherInfosIter->second.size(); } bool CheckIncludeEvent(const uint32_t &allEvent, const uint32_t &event) { - vector events = GetEvents(); + vector events = GetEvents(event); for (auto event : events) { if (allEvent & event) { return true; @@ -386,14 +371,14 @@ void FileWatcher::NotifyEvent(const struct inotify_event *event) } string fileName = fileNameIter->second; - auto callbackIter = jsWatcherCallbackMap_.find(fileName); - if (callbackIter == jsWatcherCallbackMap_.end()) { + auto watcherInfosIter = watcherInfoList_.find(fileName); + if (watcherInfosIter == watcherInfoList_.end()) { return; } - vector> pairs = callbackIter->second; - for (auto pair : pairs) { - uint32_t watchEvent = pair->second; + auto args = watcherInfosIter->second; + for (auto arg : args) { + uint32_t watchEvent = arg->events; if (!CheckIncludeEvent(event->mask, watchEvent)) { return; } @@ -402,6 +387,9 @@ void FileWatcher::NotifyEvent(const struct inotify_event *event) fileName.append(string(event->name)); } // todo callback + + // auto callback = iter->second.second; + // callback(arg->env, arg->nRef, fileName, event->mask, event->cookie); } } @@ -410,7 +398,7 @@ void FileWatcher::AddWatcherWdFileNameMap(const int &wd, const string &fileName) lock_guard lock(watcherWdFiledNameMutex_); auto it = wdFileNameMap_.find(wd); if (it == wdFileNameMap_.end()) { - wdFileNameMap_.insert(pair(wd, path)); + wdFileNameMap_.insert(pair(wd, fileName)); } } @@ -420,8 +408,8 @@ void FileWatcher::RemoveWatcherWdFileNameMap(const int &wd) auto pathIter = wdFileNameMap_.find(wd); if(pathIter != wdFileNameMap_.end()) { string fileName = pathIter->second; - auto callbackIter = jsWatcherCallbackMap_.find(fileName); - if (callbackIter == jsWatcherCallbackMap_.end()) { + auto watcherInfosIter = watcherInfoList_.find(fileName); + if (watcherInfosIter == watcherInfoList_.end()) { wdFileNameMap_.erase(pathIter); } } diff --git a/interfaces/kits/js/src/mod_fs/class_watcher/watcher_entity.h b/interfaces/kits/js/src/mod_fs/class_watcher/watcher_entity.h index 07623ed0f..004dec5c2 100644 --- a/interfaces/kits/js/src/mod_fs/class_watcher/watcher_entity.h +++ b/interfaces/kits/js/src/mod_fs/class_watcher/watcher_entity.h @@ -79,11 +79,11 @@ private: void AddWatcher(std::shared_ptr &arg, WatcherCallback callback); void AddWatcherWdFileNameMap(const int &wd, const std::string &fileName); void RemoveWatcherWdFileNameMap(const int &wd); - void RemoveJSWatcherCallback(const int &wd, const uint32_t &watcherEvent, const LibN::NVal jsCallbackVal); + void RemoveJSWatcherCallback(const std::shared_ptr &arg); int32_t GetJSWatcherCallbackSize(const int &wd); bool CheckEventWatched(const std::string &fileName, const uint32_t &event); uint32_t ParseEvent(const std::string &fileName, const uint32_t &watcherEvent); - void NotifyEvent(const int &wd, const uint32_t &event); + void NotifyEvent(const struct inotify_event *event); bool CheckSameJSCallback(const LibN::NVal &jsCallbackVal, const LibN::NVal &pairCallback); bool NotifyToWatchNewEvents(int &wd); bool AddWatchEvent(const std::string &fileName, const uint32_t &events, int &watchWd); -- Gitee From d6a2b473f2f25f2dac1d370442761be024faee07 Mon Sep 17 00:00:00 2001 From: Cao Chuan Date: Thu, 8 Jun 2023 18:04:44 +0800 Subject: [PATCH 09/27] modify lock Signed-off-by: Cao Chuan --- .../mod_fs/class_watcher/watcher_entity.cpp | 163 ++++-------------- .../src/mod_fs/class_watcher/watcher_entity.h | 50 ++---- .../kits/js/src/mod_fs/properties/watcher.cpp | 2 +- 3 files changed, 49 insertions(+), 166 deletions(-) diff --git a/interfaces/kits/js/src/mod_fs/class_watcher/watcher_entity.cpp b/interfaces/kits/js/src/mod_fs/class_watcher/watcher_entity.cpp index d9718177b..4f709a422 100644 --- a/interfaces/kits/js/src/mod_fs/class_watcher/watcher_entity.cpp +++ b/interfaces/kits/js/src/mod_fs/class_watcher/watcher_entity.cpp @@ -29,7 +29,6 @@ using namespace OHOS::FileManagement::LibN; using namespace std; namespace { - constexpr int32_t STOPPING_WAIT_TIMEOUT_MS = 5000; constexpr int64_t SELECT_TIME_OUT_US = 100000; const vector EVENT_LIST = { IN_ACCESS, IN_MODIFY, IN_ATTRIB, IN_CLOSE_WRITE, IN_CLOSE_NOWRITE, IN_CLOSE, IN_OPEN, IN_MOVED_FROM, IN_MOVED_TO, IN_MOVE, @@ -38,7 +37,7 @@ namespace { shared_ptr FileWatcher::instance_ = nullptr; mutex FileWatcher::mutex_; - +mutex FileWatcher::watchMutex_; shared_ptr FileWatcher::GetInstance() { if (instance_ == nullptr) { @@ -76,7 +75,7 @@ vector GetEvents(const uint32_t &watchEvent) return eventList; } -vector FindUnwatchedEvent(const uint32_t &allEvent, const uint32_t &event) +vector FindUnWatchedEvent(const uint32_t &allEvent, const uint32_t &event) { vector unWatchedEvents; vector allEvents = GetEvents(allEvent); @@ -92,13 +91,12 @@ vector FindUnwatchedEvent(const uint32_t &allEvent, const uint32_t &ev bool FileWatcher::CheckEventWatched(const string &fileName, const uint32_t &event) { - unique_lock lock(fileNameEventMutex_); auto iter = fileNameEventMap_.find(fileName); if (iter == fileNameEventMap_.end()) { return false; } uint32_t allEvent = iter->second; - vector unWatchedEvents = FindUnwatchedEvent(allEvent, event); + vector unWatchedEvents = FindUnWatchedEvent(allEvent, event); if (unWatchedEvents.size() == 0) { return true; } @@ -108,6 +106,7 @@ bool FileWatcher::CheckEventWatched(const string &fileName, const uint32_t &even bool FileWatcher::StartNotify(shared_ptr &arg) { + lock_guard lock(watchMutex_); if (notifyFd_ < 0) { HILOGE("Failed to start notify fail notifyFd_:%{public}d", notifyFd_); return false; @@ -126,16 +125,15 @@ bool FileWatcher::StartNotify(shared_ptr &arg) return true; } -bool FileWatcher::NotifyToWatchNewEvents(int &wd) +bool FileWatcher::NotifyToWatchNewEvents(const int &wd) { - unique_lock lock(watchNewEventMutex_); auto fileNameIter = wdFileNameMap_.find(wd); if (fileNameIter == wdFileNameMap_.end()) { return true; } string fileName = fileNameIter->second; - auto watcherInfosIter = watcherInfoList_.find(fileName); - if (watcherInfosIter == watcherInfoList_.end()) { + auto watcherInfosIter = watcherInfoMap_.find(fileName); + if (watcherInfosIter == watcherInfoMap_.end()) { return true; } auto args = watcherInfosIter->second; @@ -149,11 +147,15 @@ bool FileWatcher::NotifyToWatchNewEvents(int &wd) } fileNameEventMap_.erase(eventIter); uint32_t watchEvent = ParseEvent(fileName.c_str(), events); - wd = inotify_add_watch(notifyFd_, fileName.c_str(), watchEvent); - if (wd < 0) { - HILOGE("Failed to start notify1 fail errCode:%{public}d", errno); + int newWd = inotify_add_watch(notifyFd_, fileName.c_str(), watchEvent); + if (newWd < 0) { + HILOGE("Failed to start new notify fail errCode:%{public}d", errno); return false; } else { + if (newWd != wd) { + HILOGE("New notify wd is error"); + return false; + } AddWatcherWdFileNameMap(wd, fileName); return true; } @@ -161,19 +163,20 @@ bool FileWatcher::NotifyToWatchNewEvents(int &wd) bool FileWatcher::StopNotify(const shared_ptr &arg) { + lock_guard lock(watchMutex_); HILOGE("FileWatcher::StopNotify!"); if (notifyFd_ < 0) { HILOGE("Failed to stop notify fail notifyFd_:%{public}d", notifyFd_); return false; } - RemoveJSWatcherCallback(arg); + RemoveWatcherInfo(arg); bool ret = NotifyToWatchNewEvents(arg->wd); if (!ret) { HILOGE("Failed to notify watch new event notifyFd_:%{public}d", notifyFd_); return false; } - if (GetJSWatcherCallbackSize(arg->wd) == 0) { + if (GetWatcherInfoSize(arg->wd) == 0) { if (inotify_rm_watch(notifyFd_, arg->wd) == -1) { auto iter = wdFileNameMap_.find(arg->wd); if (iter == wdFileNameMap_.end()) { @@ -189,35 +192,11 @@ bool FileWatcher::StopNotify(const shared_ptr &arg) close(notifyFd_); notifyFd_ = -1; run_ = false; - if (!WaitForStop()) { - HILOGE("Wait for stop timeout!"); - } else { - HILOGE("Stopped!~!!"); - } return true; } return true; } -void FileWatcher::HandleEvent(const struct inotify_event *event) -{ - HILOGE("FileWatcher::HandleEvent!"); - auto iter = watcherCallbacks_.Get(event->wd); - if (watcherCallbacks_.IsEnd(iter)) { - return; - } - HILOGE("FileWatcher::HandleEvent find callback!"); - shared_ptr arg = iter->second.first; - string fileName = arg->filename; - if (event->len > 0) { - fileName.append(string("/")); - fileName.append(string(event->name)); - } - - auto callback = iter->second.second; - callback(arg->env, arg->nRef, fileName, event->mask, event->cookie); -} - void FileWatcher::GetNotifyEvent(shared_ptr &arg, WatcherCallback callback) { if (run_) { @@ -242,37 +221,20 @@ void FileWatcher::GetNotifyEvent(shared_ptr &arg, WatcherCallbac while (((len = read(notifyFd_, &buf, sizeof(buf))) < 0) && (errno == EINTR)) {}; while (index < len) { event = reinterpret_cast(buf + index); - HandleEvent(event); + NotifyEvent(event, callback); index += sizeof(struct inotify_event) + event->len; } } - if (!run_) { - NotifyStopped(); - } } HILOGE("Listener Thread has stopped!"); } -bool FileWatcher::WaitForStop() -{ - unique_lock lock(stoppingMutex_); - auto status = stoppingLock_.wait_for(lock, chrono::milliseconds(STOPPING_WAIT_TIMEOUT_MS)); - return status != cv_status::timeout; -} - -void FileWatcher::NotifyStopped() -{ - unique_lock lock(stoppingMutex_); - stoppingLock_.notify_one(); -} - -void FileWatcher::AddWatcherInfoList(const string &fileName, const shared_ptr &arg) +void FileWatcher::AddWatcherInfo(const string &fileName, const shared_ptr &arg) { - unique_lock lock(watcherInfosLock_); - WatcherInfoList::iterator it = watcherInfoList_.find(fileName); - if (it == watcherInfoList_.end()) { + WatcherInfoMap::iterator it = watcherInfoMap_.find(fileName); + if (it == watcherInfoMap_.end()) { vector> watcherInfoVec = { arg }; - watcherInfoList_[fileName] = watcherInfoVec; + watcherInfoMap_[fileName] = watcherInfoVec; return; } @@ -280,7 +242,7 @@ void FileWatcher::AddWatcherInfoList(const string &fileName, const shared_ptrenv, info->nRef.Deref(info->env).val_, arg->nRef.Deref(arg->env).val_, &isSame); -HILOGE("AddWatcherInfoList isSame: %{public}d", isSame); +HILOGE("AddWatcherInfo isSame: %{public}d", isSame); if (isSame && info->events == arg->events) { return; } @@ -288,17 +250,15 @@ HILOGE("AddWatcherInfoList isSame: %{public}d", isSame); it->second.push_back(arg); } -//todo add begin uint32_t FileWatcher::ParseEvent(const string &fileName, const uint32_t &watcherEvent) { - lock_guard lock(fileNameEventMutex_); uint32_t event = watcherEvent; auto iter = fileNameEventMap_.find(fileName); if (iter == fileNameEventMap_.end()) { fileNameEventMap_[fileName] = event; return event; } else { - vector notWatchedEvents = FindUnwatchedEvent(iter->second, event); + vector notWatchedEvents = FindUnWatchedEvent(iter->second, event); if (notWatchedEvents.size() > 0) { for (auto notWatchedEvent: notWatchedEvents) { event |= notWatchedEvent; @@ -311,16 +271,15 @@ uint32_t FileWatcher::ParseEvent(const string &fileName, const uint32_t &watcher } } -void FileWatcher::RemoveJSWatcherCallback(const shared_ptr &arg) +void FileWatcher::RemoveWatcherInfo(const shared_ptr &arg) { - lock_guard lock(jsWatcherCallbackMutex_); auto fileNameIter = wdFileNameMap_.find(arg->wd); if (fileNameIter == wdFileNameMap_.end()) { return; } string fileName = fileNameIter->second; - auto iter = watcherInfoList_.find(fileName); - if (iter == watcherInfoList_.end()) { + auto iter = watcherInfoMap_.find(fileName); + if (iter == watcherInfoMap_.end()) { return; } auto infoArgs = iter->second; @@ -336,16 +295,15 @@ void FileWatcher::RemoveJSWatcherCallback(const shared_ptr &arg) } } -int32_t FileWatcher::GetJSWatcherCallbackSize(const int &wd) +int32_t FileWatcher::GetWatcherInfoSize(const int &wd) { - lock_guard lock(jsWatcherCallbackMutex_); auto fileNameIter = wdFileNameMap_.find(wd); if (fileNameIter == wdFileNameMap_.end()) { return 0; } string fileName = fileNameIter->second; - auto watcherInfosIter = watcherInfoList_.find(fileName); - if (watcherInfosIter == watcherInfoList_.end()) { + auto watcherInfosIter = watcherInfoMap_.find(fileName); + if (watcherInfosIter == watcherInfoMap_.end()) { return 0; } return watcherInfosIter->second.size(); @@ -362,17 +320,16 @@ bool CheckIncludeEvent(const uint32_t &allEvent, const uint32_t &event) return false; } -void FileWatcher::NotifyEvent(const struct inotify_event *event) -{ - lock_guard lock(notifyMutex_); +void FileWatcher::NotifyEvent(const struct inotify_event *event, WatcherCallback callback) +{ //todo lock auto fileNameIter = wdFileNameMap_.find(event->wd); if (fileNameIter == wdFileNameMap_.end()) { return; } string fileName = fileNameIter->second; - auto watcherInfosIter = watcherInfoList_.find(fileName); - if (watcherInfosIter == watcherInfoList_.end()) { + auto watcherInfosIter = watcherInfoMap_.find(fileName); + if (watcherInfosIter == watcherInfoMap_.end()) { return; } @@ -385,17 +342,13 @@ void FileWatcher::NotifyEvent(const struct inotify_event *event) if (event->len > 0) { fileName.append(string("/")); fileName.append(string(event->name)); - } - // todo callback - - // auto callback = iter->second.second; - // callback(arg->env, arg->nRef, fileName, event->mask, event->cookie); + } + callback(arg->env, arg->nRef, fileName, event->mask, event->cookie); } } void FileWatcher::AddWatcherWdFileNameMap(const int &wd, const string &fileName) { - lock_guard lock(watcherWdFiledNameMutex_); auto it = wdFileNameMap_.find(wd); if (it == wdFileNameMap_.end()) { wdFileNameMap_.insert(pair(wd, fileName)); @@ -404,53 +357,13 @@ void FileWatcher::AddWatcherWdFileNameMap(const int &wd, const string &fileName) void FileWatcher::RemoveWatcherWdFileNameMap(const int &wd) { - lock_guard lock(watcherWdFiledNameMutex_); auto pathIter = wdFileNameMap_.find(wd); if(pathIter != wdFileNameMap_.end()) { string fileName = pathIter->second; - auto watcherInfosIter = watcherInfoList_.find(fileName); - if (watcherInfosIter == watcherInfoList_.end()) { + auto watcherInfosIter = watcherInfoMap_.find(fileName); + if (watcherInfosIter == watcherInfoMap_.end()) { wdFileNameMap_.erase(pathIter); } } } -//todo add end -void WatcherCallbackContext::Add(shared_ptr &arg, WatcherCallback callback) -{ - lock_guard lock(contextMutex_); - pair, WatcherCallback> callbackVal = make_pair(arg, callback); - map_[arg->wd] = callbackVal; -} - -WatcherCallbackMap::iterator WatcherCallbackContext::Get(const int &fd) -{ - lock_guard lock(contextMutex_); - return UnSafeGet(fd); -} -bool WatcherCallbackContext::IsEnd(WatcherCallbackMap::iterator &iter) -{ - return iter == map_.end(); -} -void WatcherCallbackContext::Remove(int &fd) -{ - lock_guard lock(contextMutex_); - auto iter = UnSafeGet(fd); - if (IsEnd(iter)) { - return true; - } - map_.erase(iter); -} -size_t WatcherCallbackContext::Size() -{ - lock_guard lock(contextMutex_); - return map_.size(); -} -WatcherCallbackMap::iterator WatcherCallbackContext::UnSafeGet(const int &fd) -{ - if (map_.size() == 0) { - return map_.end(); - } - return map_.find(fd); -} - } // namespace OHOS::FileManagement::ModuleFileIO diff --git a/interfaces/kits/js/src/mod_fs/class_watcher/watcher_entity.h b/interfaces/kits/js/src/mod_fs/class_watcher/watcher_entity.h index 004dec5c2..a371949e0 100644 --- a/interfaces/kits/js/src/mod_fs/class_watcher/watcher_entity.h +++ b/interfaces/kits/js/src/mod_fs/class_watcher/watcher_entity.h @@ -40,25 +40,8 @@ struct WatcherInfoArg { ~WatcherInfoArg() = default; }; -using WatcherCallbackMap = std::unordered_map, WatcherCallback>>; -// using WatcherCallbackMapIter = std::unordered_map, WatcherCallback>>::iterator; -using WatcherInfoList = std::unordered_map>>; -class WatcherCallbackContext { -public: - WatcherCallbackContext() = default; - ~WatcherCallbackContext() { - map_.clear(); - } - void Add(std::shared_ptr &arg, WatcherCallback callback); - WatcherCallbackMap::iterator Get(const int &fd); - bool IsEnd(WatcherCallbackMap::iterator &iter); - void Remove(int &fd); - size_t Size(); -private: - WatcherCallbackMap::iterator UnSafeGet(const int &fd); - std::mutex contextMutex_; - WatcherCallbackMap map_; -}; +using WatcherInfoMap = std::unordered_map>>; + class FileWatcher { public: virtual ~FileWatcher() = default; @@ -69,41 +52,28 @@ public: bool StartNotify(std::shared_ptr &arg); bool StopNotify(const std::shared_ptr &arg); void GetNotifyEvent(std::shared_ptr &arg, WatcherCallback callback); - void AddWatcherInfoList(const std::string &fileName, const std::shared_ptr &arg); + void AddWatcherInfo(const std::string &fileName, const std::shared_ptr &arg); private: FileWatcher() = default; - void HandleEvent(const struct inotify_event *event); - bool WaitForStop(); - void NotifyStopped(); - void AddWatcher(std::shared_ptr &arg, WatcherCallback callback); void AddWatcherWdFileNameMap(const int &wd, const std::string &fileName); void RemoveWatcherWdFileNameMap(const int &wd); - void RemoveJSWatcherCallback(const std::shared_ptr &arg); - int32_t GetJSWatcherCallbackSize(const int &wd); + void RemoveWatcherInfo(const std::shared_ptr &arg); + int32_t GetWatcherInfoSize(const int &wd); bool CheckEventWatched(const std::string &fileName, const uint32_t &event); uint32_t ParseEvent(const std::string &fileName, const uint32_t &watcherEvent); - void NotifyEvent(const struct inotify_event *event); - bool CheckSameJSCallback(const LibN::NVal &jsCallbackVal, const LibN::NVal &pairCallback); - bool NotifyToWatchNewEvents(int &wd); - bool AddWatchEvent(const std::string &fileName, const uint32_t &events, int &watchWd); + void NotifyEvent(const struct inotify_event *event, WatcherCallback callback); + bool NotifyToWatchNewEvents(const int &wd); + private: static std::mutex mutex_; + static std::mutex watchMutex_; static std::shared_ptr instance_; bool run_ = false; int32_t notifyFd_ = -1; - WatcherCallbackContext watcherCallbacks_; - std::mutex stoppingMutex_; - std::condition_variable stoppingLock_; - std::mutex watcherInfosLock_; - WatcherInfoList watcherInfoList_; + WatcherInfoMap watcherInfoMap_; std::map wdFileNameMap_; std::map fileNameEventMap_; - std::mutex watcherWdFiledNameMutex_; - std::mutex jsWatcherCallbackMutex_; - std::mutex fileNameEventMutex_; - std::mutex notifyMutex_; - std::mutex watchNewEventMutex_; }; struct WatcherEntity { diff --git a/interfaces/kits/js/src/mod_fs/properties/watcher.cpp b/interfaces/kits/js/src/mod_fs/properties/watcher.cpp index 5448bd054..f66fb3dc3 100644 --- a/interfaces/kits/js/src/mod_fs/properties/watcher.cpp +++ b/interfaces/kits/js/src/mod_fs/properties/watcher.cpp @@ -93,7 +93,7 @@ HILOGE("CreateWatcher notifyFd_2: %{public}d", FileWatcher::GetInstance()->GetNo infoArg->env = env; infoArg->filename = string(filename.get()); watcherEntity->data_ = infoArg; - FileWatcher::GetInstance()->AddWatcherInfoList(string(filename.get()), infoArg); + FileWatcher::GetInstance()->AddWatcherInfo(string(filename.get()), infoArg); return objWatcher; } -- Gitee From 5d6faf7f8e1841057298e6e54357cbb0742e0250 Mon Sep 17 00:00:00 2001 From: Cao Chuan Date: Fri, 9 Jun 2023 16:00:18 +0800 Subject: [PATCH 10/27] modify stop notify Signed-off-by: Cao Chuan --- .../mod_fs/class_watcher/watcher_entity.cpp | 164 ++++++++++++++---- .../src/mod_fs/class_watcher/watcher_entity.h | 8 +- 2 files changed, 134 insertions(+), 38 deletions(-) diff --git a/interfaces/kits/js/src/mod_fs/class_watcher/watcher_entity.cpp b/interfaces/kits/js/src/mod_fs/class_watcher/watcher_entity.cpp index 4f709a422..d8e70e064 100644 --- a/interfaces/kits/js/src/mod_fs/class_watcher/watcher_entity.cpp +++ b/interfaces/kits/js/src/mod_fs/class_watcher/watcher_entity.cpp @@ -75,14 +75,16 @@ vector GetEvents(const uint32_t &watchEvent) return eventList; } -vector FindUnWatchedEvent(const uint32_t &allEvent, const uint32_t &event) +vector FindUnWatchedEvent(const vector &allEvents, const uint32_t &event) { vector unWatchedEvents; - vector allEvents = GetEvents(allEvent); vector watchEvents = GetEvents(event); + HILOGE("FindUnWatchedEvent 2 watchEvents:%{public}d", watchEvents.size()); for (auto event: watchEvents) { + HILOGE("FindUnWatchedEvent 3 event:%{public}x", event); auto iter = find(allEvents.begin(), allEvents.end(), event); if (iter == allEvents.end()) { + HILOGE("FindUnWatchedEvent 4 event:%{public}x", event); unWatchedEvents.push_back(event); } } @@ -95,8 +97,8 @@ bool FileWatcher::CheckEventWatched(const string &fileName, const uint32_t &even if (iter == fileNameEventMap_.end()) { return false; } - uint32_t allEvent = iter->second; - vector unWatchedEvents = FindUnWatchedEvent(allEvent, event); + vector allEvents = iter->second; + vector unWatchedEvents = FindUnWatchedEvent(allEvents, event); if (unWatchedEvents.size() == 0) { return true; } @@ -114,8 +116,13 @@ bool FileWatcher::StartNotify(shared_ptr &arg) if (CheckEventWatched(arg->filename, arg->events)) { return true; } - uint32_t watchEvent = ParseEvent(arg->filename.c_str(), arg->events); + vector watchEvents = ParseEvent(arg->filename.c_str(), arg->events); + uint32_t watchEvent = 0; + for (auto event: watchEvents) { + watchEvent |= event; + } int wd = inotify_add_watch(notifyFd_, arg->filename.c_str(), watchEvent); + HILOGE("StartNotify fileName:%{public}s, wd:%{public}d", arg->filename.c_str(), wd); if (wd < 0) { HILOGE("Failed to start notify1 fail errCode:%{public}d", errno); return false; @@ -125,38 +132,89 @@ bool FileWatcher::StartNotify(shared_ptr &arg) return true; } -bool FileWatcher::NotifyToWatchNewEvents(const int &wd) +bool FileWatcher::FindWatcherInfo(const std::string &fileName, const uint32_t &event) { - auto fileNameIter = wdFileNameMap_.find(wd); - if (fileNameIter == wdFileNameMap_.end()) { - return true; + auto iter = watcherInfoMap_.find(fileName); + if (iter == watcherInfoMap_.end()) { + return false; } - string fileName = fileNameIter->second; - auto watcherInfosIter = watcherInfoMap_.find(fileName); + vector> args = iter->second; + for (auto arg : args) { + if (arg->events == event) { + return true; + } + } + return false; +} + +void FileWatcher::RemoveEventFromMap(const shared_ptr &arg) +{ + HILOGE("RemoveEventFromMap fileName:%{public}s", arg->filename.c_str()); + auto watcherInfosIter = watcherInfoMap_.find(arg->filename); if (watcherInfosIter == watcherInfoMap_.end()) { - return true; + return; } auto args = watcherInfosIter->second; - uint32_t events = 0; + vector watchedEvent; for (auto arg : args) { - events |= arg->events; + uint32_t event = arg->events; + vector events = GetEvents(event); + watchedEvent.insert(watchedEvent.end(), events.begin(), events.end()); + } + sort(watchedEvent.begin(), watchedEvent.end()); + auto iter = unique(watchedEvent.begin(), watchedEvent.end()); + watchedEvent.erase(iter, watchedEvent.end()); + + uint32_t removeEvent = arg->events; + vector removeEvents = GetEvents(removeEvent); + for (auto toRemoveEvent : removeEvents) { + auto watchedIter = find(watchedEvent.begin(), watchedEvent.end(), toRemoveEvent); + if (watchedIter != watchedEvent.end()) { + continue; + } + auto fileIter = fileNameEventMap_.find(arg->filename); + if (fileIter == fileNameEventMap_.end()) { + continue; + } + vector watchEvents = fileIter->second; + auto eventIter = find(watchEvents.begin(), watchEvents.end(), toRemoveEvent); + if (eventIter == watchEvents.end()) { + continue; + } + HILOGE("RemoveEventFromMap fileName:%{public}s remove:event%{public}x", arg->filename.c_str(), toRemoveEvent); + watchEvents.erase(eventIter); + } + HILOGE("RemoveEventFromMap fileName:%{public}s end", arg->filename.c_str()); +} + +bool FileWatcher::NotifyToWatchNewEvents(const shared_ptr &arg) +{ + if (FindWatcherInfo(arg->filename, arg->events)) { + return true; } - auto eventIter = fileNameEventMap_.find(fileName); + RemoveEventFromMap(arg); + auto eventIter = fileNameEventMap_.find(arg->filename); if (eventIter == fileNameEventMap_.end()) { return true; } - fileNameEventMap_.erase(eventIter); - uint32_t watchEvent = ParseEvent(fileName.c_str(), events); - int newWd = inotify_add_watch(notifyFd_, fileName.c_str(), watchEvent); + vector watchEvents = eventIter->second; + uint32_t watchEvent = 0; + for (auto event : watchEvents) { + watchEvent |= event; + } + int newWd = inotify_add_watch(notifyFd_, arg->filename.c_str(), watchEvent); + + HILOGE("NotifyNewEvents fd:%{public}d, wd:%{public}d, fileName:%{public}s, watchEvent:%{public}x,newWd:%{public}d", + notifyFd_, arg->wd, arg->filename.c_str(), watchEvent, newWd); if (newWd < 0) { HILOGE("Failed to start new notify fail errCode:%{public}d", errno); return false; } else { - if (newWd != wd) { + if (newWd != arg->wd) { HILOGE("New notify wd is error"); return false; } - AddWatcherWdFileNameMap(wd, fileName); + AddWatcherWdFileNameMap(newWd, arg->filename); return true; } } @@ -171,13 +229,16 @@ bool FileWatcher::StopNotify(const shared_ptr &arg) } RemoveWatcherInfo(arg); - bool ret = NotifyToWatchNewEvents(arg->wd); + bool ret = NotifyToWatchNewEvents(arg); if (!ret) { HILOGE("Failed to notify watch new event notifyFd_:%{public}d", notifyFd_); return false; } if (GetWatcherInfoSize(arg->wd) == 0) { + HILOGE("StopNotify 1"); if (inotify_rm_watch(notifyFd_, arg->wd) == -1) { + HILOGE("StopNotify 2"); + RemoveWatcherWdFileNameMap(arg->wd); auto iter = wdFileNameMap_.find(arg->wd); if (iter == wdFileNameMap_.end()) { return false; @@ -188,10 +249,15 @@ bool FileWatcher::StopNotify(const shared_ptr &arg) return false; } } - - close(notifyFd_); - notifyFd_ = -1; - run_ = false; + HILOGE("StopNotify 3"); + RemoveWatcherWdFileNameMap(arg->wd); + if (watcherInfoMap_.size() == 0) { + HILOGE("StopNotify 4"); + close(notifyFd_); + notifyFd_ = -1; + run_ = false; + } + HILOGE("StopNotify 4"); return true; } return true; @@ -250,22 +316,31 @@ HILOGE("AddWatcherInfo isSame: %{public}d", isSame); it->second.push_back(arg); } -uint32_t FileWatcher::ParseEvent(const string &fileName, const uint32_t &watcherEvent) +vector FileWatcher::ParseEvent(const string &fileName, const uint32_t &watcherEvent) { - uint32_t event = watcherEvent; + HILOGE("ParseEvent begin fileName:%{public}s, watcherEvent:%{public}x", fileName.c_str(), watcherEvent); auto iter = fileNameEventMap_.find(fileName); if (iter == fileNameEventMap_.end()) { - fileNameEventMap_[fileName] = event; - return event; + HILOGE("ParseEvent 1 fileName:%{public}s, watcherEvent:%{public}x", fileName.c_str(), watcherEvent); + vector events = GetEvents(watcherEvent); + fileNameEventMap_[fileName] = events; + return events; } else { - vector notWatchedEvents = FindUnWatchedEvent(iter->second, event); + vector notWatchedEvents = FindUnWatchedEvent(iter->second, watcherEvent); if (notWatchedEvents.size() > 0) { - for (auto notWatchedEvent: notWatchedEvents) { - event |= notWatchedEvent; - } - fileNameEventMap_[fileName] = event; - return event; + HILOGE("ParseEvent 2 fileName:%{public}s, watcherEvent:%{public}x, notWatchedEvents.size:%{public}d", + fileName.c_str(), watcherEvent, notWatchedEvents.size()); + vector newEvents; + newEvents.insert(newEvents.end(), iter->second.begin(), iter->second.end()); + newEvents.insert(newEvents.end(), notWatchedEvents.begin(), notWatchedEvents.end()); + sort(newEvents.begin(), newEvents.end()); + auto newEventIter = unique(newEvents.begin(), newEvents.end()); + newEvents.erase(newEventIter, newEvents.end()); + fileNameEventMap_[fileName] = newEvents; + return newEvents; } else { + HILOGE("ParseEvent 4 fileName:%{public}s, watcherEvent:%{public}x, event:%{public}d", + fileName.c_str(), watcherEvent, iter->second.size()); return iter->second; } } @@ -273,13 +348,17 @@ uint32_t FileWatcher::ParseEvent(const string &fileName, const uint32_t &watcher void FileWatcher::RemoveWatcherInfo(const shared_ptr &arg) { + HILOGE("RemoveWatcherInfo filename:%{public}s, wd:%{public}d", arg->filename.c_str(), arg->wd); auto fileNameIter = wdFileNameMap_.find(arg->wd); if (fileNameIter == wdFileNameMap_.end()) { + HILOGE("RemoveWatcherInfo 1 filename:%{public}s, wd:%{public}d", arg->filename.c_str(), arg->wd); return; } string fileName = fileNameIter->second; + HILOGE("RemoveWatcherInfo 2 filename:%{public}s, wd:%{public}d", arg->filename.c_str(), arg->wd); auto iter = watcherInfoMap_.find(fileName); if (iter == watcherInfoMap_.end()) { + HILOGE("RemoveWatcherInfo 3 filename:%{public}s, wd:%{public}d", arg->filename.c_str(), arg->wd); return; } auto infoArgs = iter->second; @@ -289,23 +368,31 @@ void FileWatcher::RemoveWatcherInfo(const shared_ptr &arg) napi_strict_equals(infoArgs[i]->env, infoArgs[i]->nRef.Deref(infoArgs[i]->env).val_, arg->nRef.Deref(arg->env).val_, &isSame); if (isSame) { + HILOGE("RemoveWatcherInfo 4 filename:%{public}s, wd:%{public}d", arg->filename.c_str(), arg->wd); iter->second.erase(iter->second.begin() + i); } } } + if (iter->second.size() == 0) { + watcherInfoMap_.erase(iter); + } } int32_t FileWatcher::GetWatcherInfoSize(const int &wd) { + HILOGE("GetWatcherInfoSize 1"); auto fileNameIter = wdFileNameMap_.find(wd); if (fileNameIter == wdFileNameMap_.end()) { + HILOGE("GetWatcherInfoSize 2"); return 0; } string fileName = fileNameIter->second; auto watcherInfosIter = watcherInfoMap_.find(fileName); if (watcherInfosIter == watcherInfoMap_.end()) { + HILOGE("GetWatcherInfoSize 3"); return 0; } + HILOGE("GetWatcherInfoSize 4 size:%{public}d", watcherInfosIter->second.size()); return watcherInfosIter->second.size(); } @@ -349,20 +436,27 @@ void FileWatcher::NotifyEvent(const struct inotify_event *event, WatcherCallback void FileWatcher::AddWatcherWdFileNameMap(const int &wd, const string &fileName) { + HILOGE("AddWatcherWdFileNameMap fileName:%{public}s, wd:%{public}d", fileName.c_str(), wd); auto it = wdFileNameMap_.find(wd); if (it == wdFileNameMap_.end()) { + HILOGE("AddWatcherWdFileNameMap fileName:%{public}s, wd:%{public}d insert", fileName.c_str(), wd); wdFileNameMap_.insert(pair(wd, fileName)); } } void FileWatcher::RemoveWatcherWdFileNameMap(const int &wd) { + HILOGE("RemoveWatcherWdFileNameMap wd:%{public}d", wd); auto pathIter = wdFileNameMap_.find(wd); if(pathIter != wdFileNameMap_.end()) { string fileName = pathIter->second; + HILOGE("RemoveWatcherWdFileNameMap wd:%{public}d, fileName:%{public}s", wd, fileName.c_str()); auto watcherInfosIter = watcherInfoMap_.find(fileName); if (watcherInfosIter == watcherInfoMap_.end()) { + HILOGE("RemoveWatcherWdFileNameMap 1 wd:%{public}d, fileName:%{public}s", wd, fileName.c_str()); wdFileNameMap_.erase(pathIter); + } else { + HILOGE("RemoveWatcherWdFileNameMap 2 wd:%{public}d, fileName:%{public}s", wd, fileName.c_str()); } } } diff --git a/interfaces/kits/js/src/mod_fs/class_watcher/watcher_entity.h b/interfaces/kits/js/src/mod_fs/class_watcher/watcher_entity.h index a371949e0..9c71ed515 100644 --- a/interfaces/kits/js/src/mod_fs/class_watcher/watcher_entity.h +++ b/interfaces/kits/js/src/mod_fs/class_watcher/watcher_entity.h @@ -61,9 +61,11 @@ private: void RemoveWatcherInfo(const std::shared_ptr &arg); int32_t GetWatcherInfoSize(const int &wd); bool CheckEventWatched(const std::string &fileName, const uint32_t &event); - uint32_t ParseEvent(const std::string &fileName, const uint32_t &watcherEvent); + std::vector ParseEvent(const std::string &fileName, const uint32_t &watcherEvent); void NotifyEvent(const struct inotify_event *event, WatcherCallback callback); - bool NotifyToWatchNewEvents(const int &wd); + bool NotifyToWatchNewEvents(const std::shared_ptr &arg); + bool FindWatcherInfo(const std::string &fileName, const uint32_t &event); + void RemoveEventFromMap(const std::shared_ptr &arg); private: static std::mutex mutex_; @@ -73,7 +75,7 @@ private: int32_t notifyFd_ = -1; WatcherInfoMap watcherInfoMap_; std::map wdFileNameMap_; - std::map fileNameEventMap_; + std::map> fileNameEventMap_; }; struct WatcherEntity { -- Gitee From a806a47996994a9197494d94227abafaa2731ba4 Mon Sep 17 00:00:00 2001 From: Cao Chuan Date: Fri, 9 Jun 2023 18:35:22 +0800 Subject: [PATCH 11/27] modify stop notify Signed-off-by: Cao Chuan --- .../mod_fs/class_watcher/watcher_entity.cpp | 69 ++++++++++++++++--- .../src/mod_fs/class_watcher/watcher_entity.h | 1 + 2 files changed, 59 insertions(+), 11 deletions(-) diff --git a/interfaces/kits/js/src/mod_fs/class_watcher/watcher_entity.cpp b/interfaces/kits/js/src/mod_fs/class_watcher/watcher_entity.cpp index d8e70e064..d344b59d3 100644 --- a/interfaces/kits/js/src/mod_fs/class_watcher/watcher_entity.cpp +++ b/interfaces/kits/js/src/mod_fs/class_watcher/watcher_entity.cpp @@ -152,8 +152,10 @@ void FileWatcher::RemoveEventFromMap(const shared_ptr &arg) HILOGE("RemoveEventFromMap fileName:%{public}s", arg->filename.c_str()); auto watcherInfosIter = watcherInfoMap_.find(arg->filename); if (watcherInfosIter == watcherInfoMap_.end()) { + HILOGE("RemoveEventFromMap 1 fileName:%{public}s", arg->filename.c_str()); return; } + HILOGE("RemoveEventFromMap 2 fileName:%{public}s", arg->filename.c_str()); auto args = watcherInfosIter->second; vector watchedEvent; for (auto arg : args) { @@ -161,28 +163,55 @@ void FileWatcher::RemoveEventFromMap(const shared_ptr &arg) vector events = GetEvents(event); watchedEvent.insert(watchedEvent.end(), events.begin(), events.end()); } + HILOGE("RemoveEventFromMap 3 fileName:%{public}s, watchedEvent.size:%{public}d", arg->filename.c_str(), + watchedEvent.size()); sort(watchedEvent.begin(), watchedEvent.end()); + HILOGE("RemoveEventFromMap 4 fileName:%{public}s, watchedEvent.size:%{public}d", arg->filename.c_str(), + watchedEvent.size()); auto iter = unique(watchedEvent.begin(), watchedEvent.end()); + HILOGE("RemoveEventFromMap 5 fileName:%{public}s, watchedEvent.size:%{public}d", arg->filename.c_str(), + watchedEvent.size()); watchedEvent.erase(iter, watchedEvent.end()); - + HILOGE("RemoveEventFromMap 6 fileName:%{public}s, watchedEvent.size:%{public}d", arg->filename.c_str(), + watchedEvent.size()); + map>::iterator fileIter; uint32_t removeEvent = arg->events; vector removeEvents = GetEvents(removeEvent); + HILOGE("RemoveEventFromMap 7 fileName:%{public}s, removeEvents.size:%{public}d", arg->filename.c_str(), + removeEvents.size()); for (auto toRemoveEvent : removeEvents) { + HILOGE("RemoveEventFromMap 8 fileName:%{public}s, removeEvents.size:%{public}d, toRemoveEvent:%{public}x", + arg->filename.c_str(), removeEvents.size(), toRemoveEvent); auto watchedIter = find(watchedEvent.begin(), watchedEvent.end(), toRemoveEvent); if (watchedIter != watchedEvent.end()) { + HILOGE("RemoveEventFromMap 9 fileName:%{public}s, removeEvents.size:%{public}d, toRemoveEvent:%{public}x", + arg->filename.c_str(), removeEvents.size(), toRemoveEvent); continue; } - auto fileIter = fileNameEventMap_.find(arg->filename); + fileIter = fileNameEventMap_.find(arg->filename); + HILOGE("RemoveEventFromMap 10 fileName:%{public}s, removeEvents.size:%{public}d, toRemoveEvent:%{public}x", + arg->filename.c_str(), removeEvents.size(), toRemoveEvent); if (fileIter == fileNameEventMap_.end()) { + HILOGE("RemoveEventFromMap 11 fileName:%{public}s, removeEvents.size:%{public}d, toRemoveEvent:%{public}x", + arg->filename.c_str(), removeEvents.size(), toRemoveEvent); continue; } - vector watchEvents = fileIter->second; - auto eventIter = find(watchEvents.begin(), watchEvents.end(), toRemoveEvent); - if (eventIter == watchEvents.end()) { + HILOGE("RemoveEventFromMap 12 fileName:%{public}s, removeEvents.size:%{public}d, toRemoveEvent:%{public}x", + arg->filename.c_str(), removeEvents.size(), toRemoveEvent); + auto eventIter = find(fileIter->second.begin(), fileIter->second.end(), toRemoveEvent); + HILOGE("RemoveEventFromMap 13 fileName:%{public}s, removeEvents.size:%{public}d, toRemoveEvent:%{public}x", + arg->filename.c_str(), removeEvents.size(), toRemoveEvent); + if (eventIter == fileIter->second.end()) { + HILOGE("RemoveEventFromMap 14 fileName:%{public}s, removeEvents.size:%{public}d, toRemoveEvent:%{public}x", + arg->filename.c_str(), removeEvents.size(), toRemoveEvent); continue; } HILOGE("RemoveEventFromMap fileName:%{public}s remove:event%{public}x", arg->filename.c_str(), toRemoveEvent); - watchEvents.erase(eventIter); + fileIter->second.erase(eventIter); + } + + if (fileIter->second.size() == 0) { + fileNameEventMap_.erase(fileIter); } HILOGE("RemoveEventFromMap fileName:%{public}s end", arg->filename.c_str()); } @@ -219,6 +248,15 @@ bool FileWatcher::NotifyToWatchNewEvents(const shared_ptr &arg) } } +bool FileWatcher::FindWatcherByFileName(const shared_ptr &arg) +{ + auto iter = watcherInfoMap_.find(arg->filename); + if (iter == watcherInfoMap_.end()) { + return false; + } + return true; +} + bool FileWatcher::StopNotify(const shared_ptr &arg) { lock_guard lock(watchMutex_); @@ -227,12 +265,21 @@ bool FileWatcher::StopNotify(const shared_ptr &arg) HILOGE("Failed to stop notify fail notifyFd_:%{public}d", notifyFd_); return false; } - RemoveWatcherInfo(arg); - bool ret = NotifyToWatchNewEvents(arg); - if (!ret) { - HILOGE("Failed to notify watch new event notifyFd_:%{public}d", notifyFd_); - return false; + if (FindWatcherByFileName(arg)) { + HILOGE("FindWatcherByFileName filename:%{public}s", arg->filename.c_str()); + bool ret = NotifyToWatchNewEvents(arg); + if (!ret) { + HILOGE("Failed to notify watch new event notifyFd_:%{public}d", notifyFd_); + return false; + } + } else { + HILOGE("FindWatcherByFileName 2 filename:%{public}s", arg->filename.c_str()); + auto iter = fileNameEventMap_.find(arg->filename); + if (iter != fileNameEventMap_.end()) { + HILOGE("FindWatcherByFileName 3 filename:%{public}s", arg->filename.c_str()); + fileNameEventMap_.erase(iter); + } } if (GetWatcherInfoSize(arg->wd) == 0) { HILOGE("StopNotify 1"); diff --git a/interfaces/kits/js/src/mod_fs/class_watcher/watcher_entity.h b/interfaces/kits/js/src/mod_fs/class_watcher/watcher_entity.h index 9c71ed515..13b03e81c 100644 --- a/interfaces/kits/js/src/mod_fs/class_watcher/watcher_entity.h +++ b/interfaces/kits/js/src/mod_fs/class_watcher/watcher_entity.h @@ -65,6 +65,7 @@ private: void NotifyEvent(const struct inotify_event *event, WatcherCallback callback); bool NotifyToWatchNewEvents(const std::shared_ptr &arg); bool FindWatcherInfo(const std::string &fileName, const uint32_t &event); + bool FindWatcherByFileName(const std::shared_ptr &arg); void RemoveEventFromMap(const std::shared_ptr &arg); private: -- Gitee From 93861d818f8013a27e13490a8ce556026f459416 Mon Sep 17 00:00:00 2001 From: Cao Chuan Date: Sat, 10 Jun 2023 10:51:19 +0800 Subject: [PATCH 12/27] Add set and get wd func with watcher Signed-off-by: Cao Chuan --- .../mod_fs/class_watcher/watcher_entity.cpp | 126 +++++++++++------- .../src/mod_fs/class_watcher/watcher_entity.h | 4 +- .../class_watcher/watcher_n_exporter.cpp | 2 +- .../kits/js/src/mod_fs/properties/watcher.cpp | 2 +- 4 files changed, 86 insertions(+), 48 deletions(-) diff --git a/interfaces/kits/js/src/mod_fs/class_watcher/watcher_entity.cpp b/interfaces/kits/js/src/mod_fs/class_watcher/watcher_entity.cpp index d344b59d3..ac4cb6478 100644 --- a/interfaces/kits/js/src/mod_fs/class_watcher/watcher_entity.cpp +++ b/interfaces/kits/js/src/mod_fs/class_watcher/watcher_entity.cpp @@ -106,6 +106,23 @@ bool FileWatcher::CheckEventWatched(const string &fileName, const uint32_t &even return false; } +void FileWatcher::SetWdToWatcherInfo(const uint32_t &wd, const string &fileName) +{ + auto iter = watcherInfoMap_.find(fileName); + if (iter == watcherInfoMap_.end()) { + HILOGE("Failed to set wd to filename :%{public}s", fileName.c_str()); + return; + } + + if (iter->second.size() == 0) { + HILOGE("Failed to set wd as there is no event "); + return; + } + for (auto &arg : iter->second) { + arg->wd = wd; + } +} + bool FileWatcher::StartNotify(shared_ptr &arg) { lock_guard lock(watchMutex_); @@ -113,22 +130,22 @@ bool FileWatcher::StartNotify(shared_ptr &arg) HILOGE("Failed to start notify fail notifyFd_:%{public}d", notifyFd_); return false; } - if (CheckEventWatched(arg->filename, arg->events)) { + if (CheckEventWatched(arg->fileName, arg->events)) { return true; } - vector watchEvents = ParseEvent(arg->filename.c_str(), arg->events); + vector watchEvents = ParseEvent(arg->fileName.c_str(), arg->events); uint32_t watchEvent = 0; for (auto event: watchEvents) { watchEvent |= event; } - int wd = inotify_add_watch(notifyFd_, arg->filename.c_str(), watchEvent); - HILOGE("StartNotify fileName:%{public}s, wd:%{public}d", arg->filename.c_str(), wd); + int wd = inotify_add_watch(notifyFd_, arg->fileName.c_str(), watchEvent); + HILOGE("StartNotify fileName:%{public}s, wd:%{public}d", arg->fileName.c_str(), wd); if (wd < 0) { HILOGE("Failed to start notify1 fail errCode:%{public}d", errno); return false; } - arg->wd = wd; - AddWatcherWdFileNameMap(wd, arg->filename); + SetWdToWatcherInfo(wd, arg->fileName); + AddWatcherWdFileNameMap(wd, arg->fileName); return true; } @@ -149,13 +166,13 @@ bool FileWatcher::FindWatcherInfo(const std::string &fileName, const uint32_t &e void FileWatcher::RemoveEventFromMap(const shared_ptr &arg) { - HILOGE("RemoveEventFromMap fileName:%{public}s", arg->filename.c_str()); - auto watcherInfosIter = watcherInfoMap_.find(arg->filename); + HILOGE("RemoveEventFromMap fileName:%{public}s", arg->fileName.c_str()); + auto watcherInfosIter = watcherInfoMap_.find(arg->fileName); if (watcherInfosIter == watcherInfoMap_.end()) { - HILOGE("RemoveEventFromMap 1 fileName:%{public}s", arg->filename.c_str()); + HILOGE("RemoveEventFromMap 1 fileName:%{public}s", arg->fileName.c_str()); return; } - HILOGE("RemoveEventFromMap 2 fileName:%{public}s", arg->filename.c_str()); + HILOGE("RemoveEventFromMap 2 fileName:%{public}s", arg->fileName.c_str()); auto args = watcherInfosIter->second; vector watchedEvent; for (auto arg : args) { @@ -163,66 +180,66 @@ void FileWatcher::RemoveEventFromMap(const shared_ptr &arg) vector events = GetEvents(event); watchedEvent.insert(watchedEvent.end(), events.begin(), events.end()); } - HILOGE("RemoveEventFromMap 3 fileName:%{public}s, watchedEvent.size:%{public}d", arg->filename.c_str(), + HILOGE("RemoveEventFromMap 3 fileName:%{public}s, watchedEvent.size:%{public}d", arg->fileName.c_str(), watchedEvent.size()); sort(watchedEvent.begin(), watchedEvent.end()); - HILOGE("RemoveEventFromMap 4 fileName:%{public}s, watchedEvent.size:%{public}d", arg->filename.c_str(), + HILOGE("RemoveEventFromMap 4 fileName:%{public}s, watchedEvent.size:%{public}d", arg->fileName.c_str(), watchedEvent.size()); auto iter = unique(watchedEvent.begin(), watchedEvent.end()); - HILOGE("RemoveEventFromMap 5 fileName:%{public}s, watchedEvent.size:%{public}d", arg->filename.c_str(), + HILOGE("RemoveEventFromMap 5 fileName:%{public}s, watchedEvent.size:%{public}d", arg->fileName.c_str(), watchedEvent.size()); watchedEvent.erase(iter, watchedEvent.end()); - HILOGE("RemoveEventFromMap 6 fileName:%{public}s, watchedEvent.size:%{public}d", arg->filename.c_str(), + HILOGE("RemoveEventFromMap 6 fileName:%{public}s, watchedEvent.size:%{public}d", arg->fileName.c_str(), watchedEvent.size()); map>::iterator fileIter; uint32_t removeEvent = arg->events; vector removeEvents = GetEvents(removeEvent); - HILOGE("RemoveEventFromMap 7 fileName:%{public}s, removeEvents.size:%{public}d", arg->filename.c_str(), + HILOGE("RemoveEventFromMap 7 fileName:%{public}s, removeEvents.size:%{public}d", arg->fileName.c_str(), removeEvents.size()); for (auto toRemoveEvent : removeEvents) { HILOGE("RemoveEventFromMap 8 fileName:%{public}s, removeEvents.size:%{public}d, toRemoveEvent:%{public}x", - arg->filename.c_str(), removeEvents.size(), toRemoveEvent); + arg->fileName.c_str(), removeEvents.size(), toRemoveEvent); auto watchedIter = find(watchedEvent.begin(), watchedEvent.end(), toRemoveEvent); if (watchedIter != watchedEvent.end()) { HILOGE("RemoveEventFromMap 9 fileName:%{public}s, removeEvents.size:%{public}d, toRemoveEvent:%{public}x", - arg->filename.c_str(), removeEvents.size(), toRemoveEvent); + arg->fileName.c_str(), removeEvents.size(), toRemoveEvent); continue; } - fileIter = fileNameEventMap_.find(arg->filename); + fileIter = fileNameEventMap_.find(arg->fileName); HILOGE("RemoveEventFromMap 10 fileName:%{public}s, removeEvents.size:%{public}d, toRemoveEvent:%{public}x", - arg->filename.c_str(), removeEvents.size(), toRemoveEvent); + arg->fileName.c_str(), removeEvents.size(), toRemoveEvent); if (fileIter == fileNameEventMap_.end()) { HILOGE("RemoveEventFromMap 11 fileName:%{public}s, removeEvents.size:%{public}d, toRemoveEvent:%{public}x", - arg->filename.c_str(), removeEvents.size(), toRemoveEvent); + arg->fileName.c_str(), removeEvents.size(), toRemoveEvent); continue; } HILOGE("RemoveEventFromMap 12 fileName:%{public}s, removeEvents.size:%{public}d, toRemoveEvent:%{public}x", - arg->filename.c_str(), removeEvents.size(), toRemoveEvent); + arg->fileName.c_str(), removeEvents.size(), toRemoveEvent); auto eventIter = find(fileIter->second.begin(), fileIter->second.end(), toRemoveEvent); HILOGE("RemoveEventFromMap 13 fileName:%{public}s, removeEvents.size:%{public}d, toRemoveEvent:%{public}x", - arg->filename.c_str(), removeEvents.size(), toRemoveEvent); + arg->fileName.c_str(), removeEvents.size(), toRemoveEvent); if (eventIter == fileIter->second.end()) { HILOGE("RemoveEventFromMap 14 fileName:%{public}s, removeEvents.size:%{public}d, toRemoveEvent:%{public}x", - arg->filename.c_str(), removeEvents.size(), toRemoveEvent); + arg->fileName.c_str(), removeEvents.size(), toRemoveEvent); continue; } - HILOGE("RemoveEventFromMap fileName:%{public}s remove:event%{public}x", arg->filename.c_str(), toRemoveEvent); + HILOGE("RemoveEventFromMap fileName:%{public}s remove:event%{public}x", arg->fileName.c_str(), toRemoveEvent); fileIter->second.erase(eventIter); } if (fileIter->second.size() == 0) { fileNameEventMap_.erase(fileIter); } - HILOGE("RemoveEventFromMap fileName:%{public}s end", arg->filename.c_str()); + HILOGE("RemoveEventFromMap fileName:%{public}s end", arg->fileName.c_str()); } bool FileWatcher::NotifyToWatchNewEvents(const shared_ptr &arg) { - if (FindWatcherInfo(arg->filename, arg->events)) { + if (FindWatcherInfo(arg->fileName, arg->events)) { return true; } RemoveEventFromMap(arg); - auto eventIter = fileNameEventMap_.find(arg->filename); + auto eventIter = fileNameEventMap_.find(arg->fileName); if (eventIter == fileNameEventMap_.end()) { return true; } @@ -231,10 +248,10 @@ bool FileWatcher::NotifyToWatchNewEvents(const shared_ptr &arg) for (auto event : watchEvents) { watchEvent |= event; } - int newWd = inotify_add_watch(notifyFd_, arg->filename.c_str(), watchEvent); + int newWd = inotify_add_watch(notifyFd_, arg->fileName.c_str(), watchEvent); HILOGE("NotifyNewEvents fd:%{public}d, wd:%{public}d, fileName:%{public}s, watchEvent:%{public}x,newWd:%{public}d", - notifyFd_, arg->wd, arg->filename.c_str(), watchEvent, newWd); + notifyFd_, arg->wd, arg->fileName.c_str(), watchEvent, newWd); if (newWd < 0) { HILOGE("Failed to start new notify fail errCode:%{public}d", errno); return false; @@ -243,20 +260,37 @@ bool FileWatcher::NotifyToWatchNewEvents(const shared_ptr &arg) HILOGE("New notify wd is error"); return false; } - AddWatcherWdFileNameMap(newWd, arg->filename); + SetWdToWatcherInfo(newWd, arg->fileName); + AddWatcherWdFileNameMap(newWd, arg->fileName); return true; } } bool FileWatcher::FindWatcherByFileName(const shared_ptr &arg) { - auto iter = watcherInfoMap_.find(arg->filename); + auto iter = watcherInfoMap_.find(arg->fileName); if (iter == watcherInfoMap_.end()) { return false; } return true; } +int32_t FileWatcher::GetWdFromWatcherInfoMap(const string &fileName) +{ + auto iter = watcherInfoMap_.find(fileName); + if (iter == watcherInfoMap_.end()) { + HILOGE("Failed to get wd of filename :%{public}s", fileName.c_str()); + return -1; + } + if (iter->second.size() == 0) { + HILOGE("Failed to get wd as there is no event "); + return; + } + for (auto &arg : iter->second) { + return arg->wd; + } +} + bool FileWatcher::StopNotify(const shared_ptr &arg) { lock_guard lock(watchMutex_); @@ -265,28 +299,30 @@ bool FileWatcher::StopNotify(const shared_ptr &arg) HILOGE("Failed to stop notify fail notifyFd_:%{public}d", notifyFd_); return false; } + int32_t wd = GetWdFromWatcherInfoMap(arg->fileName); + HILOGE("StopNotify wd :%{public}d", wd); RemoveWatcherInfo(arg); if (FindWatcherByFileName(arg)) { - HILOGE("FindWatcherByFileName filename:%{public}s", arg->filename.c_str()); + HILOGE("FindWatcherByFileName filename:%{public}s", arg->fileName.c_str()); bool ret = NotifyToWatchNewEvents(arg); if (!ret) { HILOGE("Failed to notify watch new event notifyFd_:%{public}d", notifyFd_); return false; } } else { - HILOGE("FindWatcherByFileName 2 filename:%{public}s", arg->filename.c_str()); - auto iter = fileNameEventMap_.find(arg->filename); + HILOGE("FindWatcherByFileName 2 filename:%{public}s", arg->fileName.c_str()); + auto iter = fileNameEventMap_.find(arg->fileName); if (iter != fileNameEventMap_.end()) { - HILOGE("FindWatcherByFileName 3 filename:%{public}s", arg->filename.c_str()); + HILOGE("FindWatcherByFileName 3 filename:%{public}s", arg->fileName.c_str()); fileNameEventMap_.erase(iter); } } - if (GetWatcherInfoSize(arg->wd) == 0) { + if (GetWatcherInfoSize(wd) == 0) { HILOGE("StopNotify 1"); - if (inotify_rm_watch(notifyFd_, arg->wd) == -1) { + if (inotify_rm_watch(notifyFd_, wd) == -1) { HILOGE("StopNotify 2"); - RemoveWatcherWdFileNameMap(arg->wd); - auto iter = wdFileNameMap_.find(arg->wd); + RemoveWatcherWdFileNameMap(wd); + auto iter = wdFileNameMap_.find(wd); if (iter == wdFileNameMap_.end()) { return false; } @@ -297,7 +333,7 @@ bool FileWatcher::StopNotify(const shared_ptr &arg) } } HILOGE("StopNotify 3"); - RemoveWatcherWdFileNameMap(arg->wd); + RemoveWatcherWdFileNameMap(wd); if (watcherInfoMap_.size() == 0) { HILOGE("StopNotify 4"); close(notifyFd_); @@ -395,17 +431,17 @@ vector FileWatcher::ParseEvent(const string &fileName, const uint32_t void FileWatcher::RemoveWatcherInfo(const shared_ptr &arg) { - HILOGE("RemoveWatcherInfo filename:%{public}s, wd:%{public}d", arg->filename.c_str(), arg->wd); + HILOGE("RemoveWatcherInfo filename:%{public}s, wd:%{public}d", arg->fileName.c_str(), arg->wd); auto fileNameIter = wdFileNameMap_.find(arg->wd); if (fileNameIter == wdFileNameMap_.end()) { - HILOGE("RemoveWatcherInfo 1 filename:%{public}s, wd:%{public}d", arg->filename.c_str(), arg->wd); + HILOGE("RemoveWatcherInfo 1 filename:%{public}s, wd:%{public}d", arg->fileName.c_str(), arg->wd); return; } string fileName = fileNameIter->second; - HILOGE("RemoveWatcherInfo 2 filename:%{public}s, wd:%{public}d", arg->filename.c_str(), arg->wd); + HILOGE("RemoveWatcherInfo 2 filename:%{public}s, wd:%{public}d", arg->fileName.c_str(), arg->wd); auto iter = watcherInfoMap_.find(fileName); if (iter == watcherInfoMap_.end()) { - HILOGE("RemoveWatcherInfo 3 filename:%{public}s, wd:%{public}d", arg->filename.c_str(), arg->wd); + HILOGE("RemoveWatcherInfo 3 filename:%{public}s, wd:%{public}d", arg->fileName.c_str(), arg->wd); return; } auto infoArgs = iter->second; @@ -415,7 +451,7 @@ void FileWatcher::RemoveWatcherInfo(const shared_ptr &arg) napi_strict_equals(infoArgs[i]->env, infoArgs[i]->nRef.Deref(infoArgs[i]->env).val_, arg->nRef.Deref(arg->env).val_, &isSame); if (isSame) { - HILOGE("RemoveWatcherInfo 4 filename:%{public}s, wd:%{public}d", arg->filename.c_str(), arg->wd); + HILOGE("RemoveWatcherInfo 4 filename:%{public}s, wd:%{public}d", arg->fileName.c_str(), arg->wd); iter->second.erase(iter->second.begin() + i); } } diff --git a/interfaces/kits/js/src/mod_fs/class_watcher/watcher_entity.h b/interfaces/kits/js/src/mod_fs/class_watcher/watcher_entity.h index 13b03e81c..f799624ad 100644 --- a/interfaces/kits/js/src/mod_fs/class_watcher/watcher_entity.h +++ b/interfaces/kits/js/src/mod_fs/class_watcher/watcher_entity.h @@ -31,7 +31,7 @@ using WatcherCallback = void (*)(napi_env env, const uint32_t &cookie); constexpr int BUF_SIZE = 1024; struct WatcherInfoArg { - std::string filename = ""; + std::string fileName = ""; uint32_t events = 0; int wd = -1; napi_env env = nullptr; @@ -67,6 +67,8 @@ private: bool FindWatcherInfo(const std::string &fileName, const uint32_t &event); bool FindWatcherByFileName(const std::shared_ptr &arg); void RemoveEventFromMap(const std::shared_ptr &arg); + void SetWdToWatcherInfo(const uint32_t &wd, const std::string &fileName); + int32_t GetWdFromWatcherInfoMap(const std::string &fileName); private: static std::mutex mutex_; diff --git a/interfaces/kits/js/src/mod_fs/class_watcher/watcher_n_exporter.cpp b/interfaces/kits/js/src/mod_fs/class_watcher/watcher_n_exporter.cpp index 9a87ccbef..bf70a9f0c 100644 --- a/interfaces/kits/js/src/mod_fs/class_watcher/watcher_n_exporter.cpp +++ b/interfaces/kits/js/src/mod_fs/class_watcher/watcher_n_exporter.cpp @@ -92,7 +92,7 @@ HILOGE("WatcherNExporter::Start notifyFd_: %{public}d", FileWatcher::GetInstance NError(errno).ThrowErr(env); return nullptr; } -HILOGE("WatcherNExporter::Start filename: %{public}s", watchEntity->data_->filename.c_str()); +HILOGE("WatcherNExporter::Start filename: %{public}s", watchEntity->data_->fileName.c_str()); auto cbExec = [watchEntity]() -> NError { HILOGE("WatcherNExporter::Start GetNotifyEvent wd: %{public}d", watchEntity->data_->wd); diff --git a/interfaces/kits/js/src/mod_fs/properties/watcher.cpp b/interfaces/kits/js/src/mod_fs/properties/watcher.cpp index f66fb3dc3..941dc52f0 100644 --- a/interfaces/kits/js/src/mod_fs/properties/watcher.cpp +++ b/interfaces/kits/js/src/mod_fs/properties/watcher.cpp @@ -91,7 +91,7 @@ HILOGE("CreateWatcher notifyFd_2: %{public}d", FileWatcher::GetInstance()->GetNo auto infoArg = make_shared(NVal(env, funcArg[NARG_POS::THIRD])); infoArg->events = events; infoArg->env = env; - infoArg->filename = string(filename.get()); + infoArg->fileName = string(filename.get()); watcherEntity->data_ = infoArg; FileWatcher::GetInstance()->AddWatcherInfo(string(filename.get()), infoArg); -- Gitee From 4e8fb8883b9e48e578275ef46eabe3a3c167143c Mon Sep 17 00:00:00 2001 From: Cao Chuan Date: Mon, 12 Jun 2023 09:29:19 +0800 Subject: [PATCH 13/27] modify build error Signed-off-by: Cao Chuan --- .../mod_fs/class_watcher/watcher_entity.cpp | 22 ++++++++++--------- .../class_watcher/watcher_n_exporter.cpp | 3 ++- 2 files changed, 14 insertions(+), 11 deletions(-) diff --git a/interfaces/kits/js/src/mod_fs/class_watcher/watcher_entity.cpp b/interfaces/kits/js/src/mod_fs/class_watcher/watcher_entity.cpp index ac4cb6478..4dd91c251 100644 --- a/interfaces/kits/js/src/mod_fs/class_watcher/watcher_entity.cpp +++ b/interfaces/kits/js/src/mod_fs/class_watcher/watcher_entity.cpp @@ -79,12 +79,12 @@ vector FindUnWatchedEvent(const vector &allEvents, const uin { vector unWatchedEvents; vector watchEvents = GetEvents(event); - HILOGE("FindUnWatchedEvent 2 watchEvents:%{public}d", watchEvents.size()); + HILOGE("FindUnWatchedEvent 2 watchEvents:%{public}d", watchEvents.size()); for (auto event: watchEvents) { - HILOGE("FindUnWatchedEvent 3 event:%{public}x", event); + HILOGE("FindUnWatchedEvent 3 event:%{public}x", event); auto iter = find(allEvents.begin(), allEvents.end(), event); if (iter == allEvents.end()) { - HILOGE("FindUnWatchedEvent 4 event:%{public}x", event); + HILOGE("FindUnWatchedEvent 4 event:%{public}x", event); unWatchedEvents.push_back(event); } } @@ -159,7 +159,7 @@ bool FileWatcher::FindWatcherInfo(const std::string &fileName, const uint32_t &e for (auto arg : args) { if (arg->events == event) { return true; - } + } } return false; } @@ -226,7 +226,7 @@ void FileWatcher::RemoveEventFromMap(const shared_ptr &arg) HILOGE("RemoveEventFromMap fileName:%{public}s remove:event%{public}x", arg->fileName.c_str(), toRemoveEvent); fileIter->second.erase(eventIter); } - + if (fileIter->second.size() == 0) { fileNameEventMap_.erase(fileIter); } @@ -234,7 +234,7 @@ void FileWatcher::RemoveEventFromMap(const shared_ptr &arg) } bool FileWatcher::NotifyToWatchNewEvents(const shared_ptr &arg) -{ +{ if (FindWatcherInfo(arg->fileName, arg->events)) { return true; } @@ -249,7 +249,7 @@ bool FileWatcher::NotifyToWatchNewEvents(const shared_ptr &arg) watchEvent |= event; } int newWd = inotify_add_watch(notifyFd_, arg->fileName.c_str(), watchEvent); - + HILOGE("NotifyNewEvents fd:%{public}d, wd:%{public}d, fileName:%{public}s, watchEvent:%{public}x,newWd:%{public}d", notifyFd_, arg->wd, arg->fileName.c_str(), watchEvent, newWd); if (newWd < 0) { @@ -284,11 +284,12 @@ int32_t FileWatcher::GetWdFromWatcherInfoMap(const string &fileName) } if (iter->second.size() == 0) { HILOGE("Failed to get wd as there is no event "); - return; + return -1; } for (auto &arg : iter->second) { return arg->wd; } + return -1; } bool FileWatcher::StopNotify(const shared_ptr &arg) @@ -324,6 +325,7 @@ bool FileWatcher::StopNotify(const shared_ptr &arg) RemoveWatcherWdFileNameMap(wd); auto iter = wdFileNameMap_.find(wd); if (iter == wdFileNameMap_.end()) { + HILOGE("Failed to stop notify, not find wd:%{public}d", wd); return false; } string filename = iter->second; @@ -473,7 +475,7 @@ int32_t FileWatcher::GetWatcherInfoSize(const int &wd) auto watcherInfosIter = watcherInfoMap_.find(fileName); if (watcherInfosIter == watcherInfoMap_.end()) { HILOGE("GetWatcherInfoSize 3"); - return 0; + return 0; } HILOGE("GetWatcherInfoSize 4 size:%{public}d", watcherInfosIter->second.size()); return watcherInfosIter->second.size(); @@ -512,7 +514,7 @@ void FileWatcher::NotifyEvent(const struct inotify_event *event, WatcherCallback if (event->len > 0) { fileName.append(string("/")); fileName.append(string(event->name)); - } + } callback(arg->env, arg->nRef, fileName, event->mask, event->cookie); } } diff --git a/interfaces/kits/js/src/mod_fs/class_watcher/watcher_n_exporter.cpp b/interfaces/kits/js/src/mod_fs/class_watcher/watcher_n_exporter.cpp index bf70a9f0c..6d752a8a8 100644 --- a/interfaces/kits/js/src/mod_fs/class_watcher/watcher_n_exporter.cpp +++ b/interfaces/kits/js/src/mod_fs/class_watcher/watcher_n_exporter.cpp @@ -70,7 +70,8 @@ HILOGE("WatcherNExporter::Stop wd: %{public}d", watchEntity->data_->wd); NError(errno).ThrowErr(env); return nullptr; } - + + HILOGE("WatcherNExporter::Stop wd: %{public}d success", watchEntity->data_->wd); return NVal::CreateUndefined(env).val_; } -- Gitee From 556e73458bb8ebd803da0b0de7d519f6fabe2d9c Mon Sep 17 00:00:00 2001 From: Cao Chuan Date: Mon, 12 Jun 2023 16:36:12 +0800 Subject: [PATCH 14/27] Remove set and get wd with watcher Signed-off-by: Cao Chuan --- .../mod_fs/class_watcher/watcher_entity.cpp | 50 +++---------------- .../src/mod_fs/class_watcher/watcher_entity.h | 2 - 2 files changed, 7 insertions(+), 45 deletions(-) diff --git a/interfaces/kits/js/src/mod_fs/class_watcher/watcher_entity.cpp b/interfaces/kits/js/src/mod_fs/class_watcher/watcher_entity.cpp index 4dd91c251..1370d205e 100644 --- a/interfaces/kits/js/src/mod_fs/class_watcher/watcher_entity.cpp +++ b/interfaces/kits/js/src/mod_fs/class_watcher/watcher_entity.cpp @@ -106,23 +106,6 @@ bool FileWatcher::CheckEventWatched(const string &fileName, const uint32_t &even return false; } -void FileWatcher::SetWdToWatcherInfo(const uint32_t &wd, const string &fileName) -{ - auto iter = watcherInfoMap_.find(fileName); - if (iter == watcherInfoMap_.end()) { - HILOGE("Failed to set wd to filename :%{public}s", fileName.c_str()); - return; - } - - if (iter->second.size() == 0) { - HILOGE("Failed to set wd as there is no event "); - return; - } - for (auto &arg : iter->second) { - arg->wd = wd; - } -} - bool FileWatcher::StartNotify(shared_ptr &arg) { lock_guard lock(watchMutex_); @@ -144,7 +127,7 @@ bool FileWatcher::StartNotify(shared_ptr &arg) HILOGE("Failed to start notify1 fail errCode:%{public}d", errno); return false; } - SetWdToWatcherInfo(wd, arg->fileName); + arg->wd = wd; AddWatcherWdFileNameMap(wd, arg->fileName); return true; } @@ -260,7 +243,6 @@ bool FileWatcher::NotifyToWatchNewEvents(const shared_ptr &arg) HILOGE("New notify wd is error"); return false; } - SetWdToWatcherInfo(newWd, arg->fileName); AddWatcherWdFileNameMap(newWd, arg->fileName); return true; } @@ -275,23 +257,6 @@ bool FileWatcher::FindWatcherByFileName(const shared_ptr &arg) return true; } -int32_t FileWatcher::GetWdFromWatcherInfoMap(const string &fileName) -{ - auto iter = watcherInfoMap_.find(fileName); - if (iter == watcherInfoMap_.end()) { - HILOGE("Failed to get wd of filename :%{public}s", fileName.c_str()); - return -1; - } - if (iter->second.size() == 0) { - HILOGE("Failed to get wd as there is no event "); - return -1; - } - for (auto &arg : iter->second) { - return arg->wd; - } - return -1; -} - bool FileWatcher::StopNotify(const shared_ptr &arg) { lock_guard lock(watchMutex_); @@ -300,8 +265,7 @@ bool FileWatcher::StopNotify(const shared_ptr &arg) HILOGE("Failed to stop notify fail notifyFd_:%{public}d", notifyFd_); return false; } - int32_t wd = GetWdFromWatcherInfoMap(arg->fileName); - HILOGE("StopNotify wd :%{public}d", wd); + HILOGE("StopNotify wd :%{public}d", arg->wd); RemoveWatcherInfo(arg); if (FindWatcherByFileName(arg)) { HILOGE("FindWatcherByFileName filename:%{public}s", arg->fileName.c_str()); @@ -318,12 +282,12 @@ bool FileWatcher::StopNotify(const shared_ptr &arg) fileNameEventMap_.erase(iter); } } - if (GetWatcherInfoSize(wd) == 0) { + if (GetWatcherInfoSize(arg->wd) == 0) { HILOGE("StopNotify 1"); - if (inotify_rm_watch(notifyFd_, wd) == -1) { + if (inotify_rm_watch(notifyFd_, arg->wd) == -1) { HILOGE("StopNotify 2"); - RemoveWatcherWdFileNameMap(wd); - auto iter = wdFileNameMap_.find(wd); + RemoveWatcherWdFileNameMap(arg->wd); + auto iter = wdFileNameMap_.find(arg->wd); if (iter == wdFileNameMap_.end()) { HILOGE("Failed to stop notify, not find wd:%{public}d", wd); return false; @@ -335,7 +299,7 @@ bool FileWatcher::StopNotify(const shared_ptr &arg) } } HILOGE("StopNotify 3"); - RemoveWatcherWdFileNameMap(wd); + RemoveWatcherWdFileNameMap(arg->wd); if (watcherInfoMap_.size() == 0) { HILOGE("StopNotify 4"); close(notifyFd_); diff --git a/interfaces/kits/js/src/mod_fs/class_watcher/watcher_entity.h b/interfaces/kits/js/src/mod_fs/class_watcher/watcher_entity.h index f799624ad..504489605 100644 --- a/interfaces/kits/js/src/mod_fs/class_watcher/watcher_entity.h +++ b/interfaces/kits/js/src/mod_fs/class_watcher/watcher_entity.h @@ -67,8 +67,6 @@ private: bool FindWatcherInfo(const std::string &fileName, const uint32_t &event); bool FindWatcherByFileName(const std::shared_ptr &arg); void RemoveEventFromMap(const std::shared_ptr &arg); - void SetWdToWatcherInfo(const uint32_t &wd, const std::string &fileName); - int32_t GetWdFromWatcherInfoMap(const std::string &fileName); private: static std::mutex mutex_; -- Gitee From cbd90736e7825ac2627124a1ff2e13d896c6d9e2 Mon Sep 17 00:00:00 2001 From: Cao Chuan Date: Tue, 13 Jun 2023 09:29:52 +0800 Subject: [PATCH 15/27] modify build error Signed-off-by: Cao Chuan --- interfaces/kits/js/src/mod_fs/class_watcher/watcher_entity.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interfaces/kits/js/src/mod_fs/class_watcher/watcher_entity.cpp b/interfaces/kits/js/src/mod_fs/class_watcher/watcher_entity.cpp index 1370d205e..05049461a 100644 --- a/interfaces/kits/js/src/mod_fs/class_watcher/watcher_entity.cpp +++ b/interfaces/kits/js/src/mod_fs/class_watcher/watcher_entity.cpp @@ -289,7 +289,7 @@ bool FileWatcher::StopNotify(const shared_ptr &arg) RemoveWatcherWdFileNameMap(arg->wd); auto iter = wdFileNameMap_.find(arg->wd); if (iter == wdFileNameMap_.end()) { - HILOGE("Failed to stop notify, not find wd:%{public}d", wd); + HILOGE("Failed to stop notify, not find wd:%{public}d", arg->wd); return false; } string filename = iter->second; -- Gitee From 38eddcba6d7443dbf4cf6e5b87d8e935e13273e3 Mon Sep 17 00:00:00 2001 From: Cao Chuan Date: Tue, 13 Jun 2023 11:04:48 +0800 Subject: [PATCH 16/27] add log Signed-off-by: Cao Chuan --- .../mod_fs/class_watcher/watcher_entity.cpp | 23 +++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/interfaces/kits/js/src/mod_fs/class_watcher/watcher_entity.cpp b/interfaces/kits/js/src/mod_fs/class_watcher/watcher_entity.cpp index 05049461a..82e36d6a7 100644 --- a/interfaces/kits/js/src/mod_fs/class_watcher/watcher_entity.cpp +++ b/interfaces/kits/js/src/mod_fs/class_watcher/watcher_entity.cpp @@ -306,7 +306,7 @@ bool FileWatcher::StopNotify(const shared_ptr &arg) notifyFd_ = -1; run_ = false; } - HILOGE("StopNotify 4"); + HILOGE("StopNotify 5"); return true; } return true; @@ -447,38 +447,53 @@ int32_t FileWatcher::GetWatcherInfoSize(const int &wd) bool CheckIncludeEvent(const uint32_t &allEvent, const uint32_t &event) { + HILOGE("CheckIncludeEvent 1 allEvent:%{public}x, event:%{public}x", allEvent, event); vector events = GetEvents(event); + HILOGE("CheckIncludeEvent 2 events.size:%{public}d", events.size()); for (auto event : events) { + HILOGE("CheckIncludeEvent 3 event:%{public}x", event); if (allEvent & event) { + HILOGE("CheckIncludeEvent 4 allEvent:%{public}x, event:%{public}x", allEvent, event); return true; } } + HILOGE("CheckIncludeEvent 5 allEvent:%{public}x, event:%{public}x", allEvent, event); return false; } void FileWatcher::NotifyEvent(const struct inotify_event *event, WatcherCallback callback) -{ //todo lock +{ + HILOGE("NotifyEvent 1 wd:%{public}d", event->wd); auto fileNameIter = wdFileNameMap_.find(event->wd); if (fileNameIter == wdFileNameMap_.end()) { return; } - + HILOGE("NotifyEvent 2 wd:%{public}d", event->wd); string fileName = fileNameIter->second; + HILOGE("NotifyEvent 3 wd:%{public}d, fileName:%{public}s", event->wd, fileName.c_str()); auto watcherInfosIter = watcherInfoMap_.find(fileName); if (watcherInfosIter == watcherInfoMap_.end()) { return; } - + HILOGE("NotifyEvent 4 wd:%{public}d, fileName:%{public}s", event->wd, fileName.c_str()); auto args = watcherInfosIter->second; for (auto arg : args) { uint32_t watchEvent = arg->events; + HILOGE("NotifyEvent 5 wd:%{public}d, fileName:%{public}s, watchEvent:%{public}x", event->wd, fileName.c_str(), + arg->events); if (!CheckIncludeEvent(event->mask, watchEvent)) { + HILOGE("NotifyEvent 6 wd:%{public}d, fileName:%{public}s, watchEvent:%{public}x, mask:%{public}x", + event->wd, fileName.c_str(), arg->events, event->mask); return; } if (event->len > 0) { + HILOGE("NotifyEvent 7 wd:%{public}d, fileName:%{public}s, watchEvent:%{public}x, mask:%{public}x", + event->wd, fileName.c_str(), arg->events, event->mask); fileName.append(string("/")); fileName.append(string(event->name)); } + HILOGE("NotifyEvent 8 wd:%{public}d, fileName:%{public}s, watchEvent:%{public}x, mask:%{public}x", + event->wd, fileName.c_str(), arg->events, event->mask); callback(arg->env, arg->nRef, fileName, event->mask, event->cookie); } } -- Gitee From 797481b41b7a2e5d2c522c3178be83d1753ccf91 Mon Sep 17 00:00:00 2001 From: Cao Chuan Date: Tue, 13 Jun 2023 11:11:14 +0800 Subject: [PATCH 17/27] add log Signed-off-by: Cao Chuan --- interfaces/kits/js/src/mod_fs/class_watcher/watcher_entity.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interfaces/kits/js/src/mod_fs/class_watcher/watcher_entity.cpp b/interfaces/kits/js/src/mod_fs/class_watcher/watcher_entity.cpp index 82e36d6a7..8c77b6235 100644 --- a/interfaces/kits/js/src/mod_fs/class_watcher/watcher_entity.cpp +++ b/interfaces/kits/js/src/mod_fs/class_watcher/watcher_entity.cpp @@ -463,7 +463,7 @@ bool CheckIncludeEvent(const uint32_t &allEvent, const uint32_t &event) void FileWatcher::NotifyEvent(const struct inotify_event *event, WatcherCallback callback) { - HILOGE("NotifyEvent 1 wd:%{public}d", event->wd); + HILOGE("NotifyEvent 1 wd:%{public}d, mask:%{public}x", event->wd, event->mask); auto fileNameIter = wdFileNameMap_.find(event->wd); if (fileNameIter == wdFileNameMap_.end()) { return; -- Gitee From 88e5bae225749d5d2107d6b589fd1c1d1556ae5a Mon Sep 17 00:00:00 2001 From: Cao Chuan Date: Tue, 13 Jun 2023 13:37:42 +0800 Subject: [PATCH 18/27] modify log Signed-off-by: Cao Chuan --- interfaces/kits/js/src/mod_fs/class_watcher/watcher_entity.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interfaces/kits/js/src/mod_fs/class_watcher/watcher_entity.cpp b/interfaces/kits/js/src/mod_fs/class_watcher/watcher_entity.cpp index 8c77b6235..20a46b4f5 100644 --- a/interfaces/kits/js/src/mod_fs/class_watcher/watcher_entity.cpp +++ b/interfaces/kits/js/src/mod_fs/class_watcher/watcher_entity.cpp @@ -470,7 +470,7 @@ void FileWatcher::NotifyEvent(const struct inotify_event *event, WatcherCallback } HILOGE("NotifyEvent 2 wd:%{public}d", event->wd); string fileName = fileNameIter->second; - HILOGE("NotifyEvent 3 wd:%{public}d, fileName:%{public}s", event->wd, fileName.c_str()); + HILOGE("NotifyEvent 3 wd:%{public}d, fileName:%{public}s", event->wd, fileName.c_str()); auto watcherInfosIter = watcherInfoMap_.find(fileName); if (watcherInfosIter == watcherInfoMap_.end()) { return; -- Gitee From 5bb61cc9b751a866a577639a6fc0a1a6d149874a Mon Sep 17 00:00:00 2001 From: Cao Chuan Date: Tue, 13 Jun 2023 15:56:24 +0800 Subject: [PATCH 19/27] add lock Signed-off-by: Cao Chuan --- .../kits/js/src/mod_fs/class_watcher/watcher_entity.cpp | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/interfaces/kits/js/src/mod_fs/class_watcher/watcher_entity.cpp b/interfaces/kits/js/src/mod_fs/class_watcher/watcher_entity.cpp index 20a46b4f5..e768e3df6 100644 --- a/interfaces/kits/js/src/mod_fs/class_watcher/watcher_entity.cpp +++ b/interfaces/kits/js/src/mod_fs/class_watcher/watcher_entity.cpp @@ -29,7 +29,6 @@ using namespace OHOS::FileManagement::LibN; using namespace std; namespace { - constexpr int64_t SELECT_TIME_OUT_US = 100000; const vector EVENT_LIST = { IN_ACCESS, IN_MODIFY, IN_ATTRIB, IN_CLOSE_WRITE, IN_CLOSE_NOWRITE, IN_CLOSE, IN_OPEN, IN_MOVED_FROM, IN_MOVED_TO, IN_MOVE, IN_CREATE, IN_DELETE, IN_DELETE_SELF, IN_MOVE_SELF }; @@ -286,7 +285,6 @@ bool FileWatcher::StopNotify(const shared_ptr &arg) HILOGE("StopNotify 1"); if (inotify_rm_watch(notifyFd_, arg->wd) == -1) { HILOGE("StopNotify 2"); - RemoveWatcherWdFileNameMap(arg->wd); auto iter = wdFileNameMap_.find(arg->wd); if (iter == wdFileNameMap_.end()) { HILOGE("Failed to stop notify, not find wd:%{public}d", arg->wd); @@ -294,6 +292,7 @@ bool FileWatcher::StopNotify(const shared_ptr &arg) } string filename = iter->second; if (access(filename.c_str(), F_OK) == 0) { + RemoveWatcherWdFileNameMap(arg->wd); HILOGE("Failed to stop notify fail errCode:%{public}d", errno); return false; } @@ -330,8 +329,7 @@ void FileWatcher::GetNotifyEvent(shared_ptr &arg, WatcherCallbac fd_set fds; FD_ZERO(&fds); FD_SET(notifyFd_, &fds); - timeval timeout{.tv_sec = 0, .tv_usec = SELECT_TIME_OUT_US}; - if (select(notifyFd_ + 1, &fds, nullptr, nullptr, &timeout) > 0) { + if (select(notifyFd_ + 1, &fds, nullptr, nullptr, nullptr) > 0) { int len, index = 0; while (((len = read(notifyFd_, &buf, sizeof(buf))) < 0) && (errno == EINTR)) {}; while (index < len) { @@ -463,6 +461,7 @@ bool CheckIncludeEvent(const uint32_t &allEvent, const uint32_t &event) void FileWatcher::NotifyEvent(const struct inotify_event *event, WatcherCallback callback) { + lock_guard lock(watchMutex_); HILOGE("NotifyEvent 1 wd:%{public}d, mask:%{public}x", event->wd, event->mask); auto fileNameIter = wdFileNameMap_.find(event->wd); if (fileNameIter == wdFileNameMap_.end()) { -- Gitee From 70fc9ca52fa40823c25415a5362a83a06a4ecdf0 Mon Sep 17 00:00:00 2001 From: Cao Chuan Date: Tue, 13 Jun 2023 21:50:27 +0800 Subject: [PATCH 20/27] modify error event Signed-off-by: Cao Chuan --- .../mod_fs/class_watcher/watcher_entity.cpp | 170 +++++++++++------- .../src/mod_fs/class_watcher/watcher_entity.h | 2 +- .../kits/js/src/mod_fs/properties/watcher.cpp | 7 +- 3 files changed, 108 insertions(+), 71 deletions(-) diff --git a/interfaces/kits/js/src/mod_fs/class_watcher/watcher_entity.cpp b/interfaces/kits/js/src/mod_fs/class_watcher/watcher_entity.cpp index e768e3df6..d78889181 100644 --- a/interfaces/kits/js/src/mod_fs/class_watcher/watcher_entity.cpp +++ b/interfaces/kits/js/src/mod_fs/class_watcher/watcher_entity.cpp @@ -78,12 +78,12 @@ vector FindUnWatchedEvent(const vector &allEvents, const uin { vector unWatchedEvents; vector watchEvents = GetEvents(event); - HILOGE("FindUnWatchedEvent 2 watchEvents:%{public}d", watchEvents.size()); + HILOGI("FindUnWatchedEvent 2 watchEvents:%{public}d", watchEvents.size()); for (auto event: watchEvents) { - HILOGE("FindUnWatchedEvent 3 event:%{public}x", event); + HILOGI("FindUnWatchedEvent 3 event:%{public}x", event); auto iter = find(allEvents.begin(), allEvents.end(), event); if (iter == allEvents.end()) { - HILOGE("FindUnWatchedEvent 4 event:%{public}x", event); + HILOGI("FindUnWatchedEvent 4 event:%{public}x", event); unWatchedEvents.push_back(event); } } @@ -105,6 +105,19 @@ bool FileWatcher::CheckEventWatched(const string &fileName, const uint32_t &even return false; } +bool FileWatcher::CheckEventValid(const uint32_t &event) +{ + HILOGI("CheckEventValid begin:event:%{public}x", event); + vector events = GetEvents(event); + HILOGI("CheckEventValid 1:event:%{public}x, events.size:%{public}d", event, events.size()); + if (events.size() > 0) { + HILOGI("CheckEventValid 2:event:%{public}x, events.size:%{public}d", event, events.size()); + return true; + } + HILOGI("CheckEventValid 3:event:%{public}x, events.size:%{public}d", event, events.size()); + return false; +} + bool FileWatcher::StartNotify(shared_ptr &arg) { lock_guard lock(watchMutex_); @@ -112,18 +125,37 @@ bool FileWatcher::StartNotify(shared_ptr &arg) HILOGE("Failed to start notify fail notifyFd_:%{public}d", notifyFd_); return false; } + + HILOGI("StartNotify event:%{public}x", arg->events); + if (!CheckEventValid(arg->events)) { + HILOGE("Failed to start notify, the watch event:%{public}x is wrong", arg->events); + errno = E_INVAL; + return false; + } + if (CheckEventWatched(arg->fileName, arg->events)) { - return true; + for (auto iter = wdFileNameMap_.begin(); iter != wdFileNameMap_.end(); iter++) { + HILOGI("StartNotify 1 fileName:%{public}s", arg->fileName.c_str()); + if (iter->second.compare(arg->fileName) == 0) { + HILOGI("StartNotify 2 fileName:%{public}s, wd:%{public}d", arg->fileName.c_str(), iter->first); + arg->wd = iter->first; + return true; + } + } + HILOGI("StartNotify 3 fileName:%{public}s", arg->fileName.c_str()); + HILOGE("Failed to start notify, not find:%{public}s data" , arg->fileName.c_str()); + return false; } + vector watchEvents = ParseEvent(arg->fileName.c_str(), arg->events); uint32_t watchEvent = 0; for (auto event: watchEvents) { watchEvent |= event; } int wd = inotify_add_watch(notifyFd_, arg->fileName.c_str(), watchEvent); - HILOGE("StartNotify fileName:%{public}s, wd:%{public}d", arg->fileName.c_str(), wd); + HILOGI("StartNotify fileName:%{public}s, wd:%{public}d", arg->fileName.c_str(), wd); if (wd < 0) { - HILOGE("Failed to start notify1 fail errCode:%{public}d", errno); + HILOGE("Failed to start notify fail errCode:%{public}d", errno); return false; } arg->wd = wd; @@ -148,13 +180,13 @@ bool FileWatcher::FindWatcherInfo(const std::string &fileName, const uint32_t &e void FileWatcher::RemoveEventFromMap(const shared_ptr &arg) { - HILOGE("RemoveEventFromMap fileName:%{public}s", arg->fileName.c_str()); + HILOGI("RemoveEventFromMap fileName:%{public}s", arg->fileName.c_str()); auto watcherInfosIter = watcherInfoMap_.find(arg->fileName); if (watcherInfosIter == watcherInfoMap_.end()) { - HILOGE("RemoveEventFromMap 1 fileName:%{public}s", arg->fileName.c_str()); + HILOGI("RemoveEventFromMap 1 fileName:%{public}s", arg->fileName.c_str()); return; } - HILOGE("RemoveEventFromMap 2 fileName:%{public}s", arg->fileName.c_str()); + HILOGI("RemoveEventFromMap 2 fileName:%{public}s", arg->fileName.c_str()); auto args = watcherInfosIter->second; vector watchedEvent; for (auto arg : args) { @@ -162,57 +194,57 @@ void FileWatcher::RemoveEventFromMap(const shared_ptr &arg) vector events = GetEvents(event); watchedEvent.insert(watchedEvent.end(), events.begin(), events.end()); } - HILOGE("RemoveEventFromMap 3 fileName:%{public}s, watchedEvent.size:%{public}d", arg->fileName.c_str(), + HILOGI("RemoveEventFromMap 3 fileName:%{public}s, watchedEvent.size:%{public}d", arg->fileName.c_str(), watchedEvent.size()); sort(watchedEvent.begin(), watchedEvent.end()); - HILOGE("RemoveEventFromMap 4 fileName:%{public}s, watchedEvent.size:%{public}d", arg->fileName.c_str(), + HILOGI("RemoveEventFromMap 4 fileName:%{public}s, watchedEvent.size:%{public}d", arg->fileName.c_str(), watchedEvent.size()); auto iter = unique(watchedEvent.begin(), watchedEvent.end()); - HILOGE("RemoveEventFromMap 5 fileName:%{public}s, watchedEvent.size:%{public}d", arg->fileName.c_str(), + HILOGI("RemoveEventFromMap 5 fileName:%{public}s, watchedEvent.size:%{public}d", arg->fileName.c_str(), watchedEvent.size()); watchedEvent.erase(iter, watchedEvent.end()); - HILOGE("RemoveEventFromMap 6 fileName:%{public}s, watchedEvent.size:%{public}d", arg->fileName.c_str(), + HILOGI("RemoveEventFromMap 6 fileName:%{public}s, watchedEvent.size:%{public}d", arg->fileName.c_str(), watchedEvent.size()); map>::iterator fileIter; uint32_t removeEvent = arg->events; vector removeEvents = GetEvents(removeEvent); - HILOGE("RemoveEventFromMap 7 fileName:%{public}s, removeEvents.size:%{public}d", arg->fileName.c_str(), + HILOGI("RemoveEventFromMap 7 fileName:%{public}s, removeEvents.size:%{public}d", arg->fileName.c_str(), removeEvents.size()); for (auto toRemoveEvent : removeEvents) { - HILOGE("RemoveEventFromMap 8 fileName:%{public}s, removeEvents.size:%{public}d, toRemoveEvent:%{public}x", + HILOGI("RemoveEventFromMap 8 fileName:%{public}s, removeEvents.size:%{public}d, toRemoveEvent:%{public}x", arg->fileName.c_str(), removeEvents.size(), toRemoveEvent); auto watchedIter = find(watchedEvent.begin(), watchedEvent.end(), toRemoveEvent); if (watchedIter != watchedEvent.end()) { - HILOGE("RemoveEventFromMap 9 fileName:%{public}s, removeEvents.size:%{public}d, toRemoveEvent:%{public}x", + HILOGI("RemoveEventFromMap 9 fileName:%{public}s, removeEvents.size:%{public}d, toRemoveEvent:%{public}x", arg->fileName.c_str(), removeEvents.size(), toRemoveEvent); continue; } fileIter = fileNameEventMap_.find(arg->fileName); - HILOGE("RemoveEventFromMap 10 fileName:%{public}s, removeEvents.size:%{public}d, toRemoveEvent:%{public}x", + HILOGI("RemoveEventFromMap 10 fileName:%{public}s, removeEvents.size:%{public}d, toRemoveEvent:%{public}x", arg->fileName.c_str(), removeEvents.size(), toRemoveEvent); if (fileIter == fileNameEventMap_.end()) { - HILOGE("RemoveEventFromMap 11 fileName:%{public}s, removeEvents.size:%{public}d, toRemoveEvent:%{public}x", + HILOGI("RemoveEventFromMap 11 fileName:%{public}s, removeEvents.size:%{public}d, toRemoveEvent:%{public}x", arg->fileName.c_str(), removeEvents.size(), toRemoveEvent); continue; } - HILOGE("RemoveEventFromMap 12 fileName:%{public}s, removeEvents.size:%{public}d, toRemoveEvent:%{public}x", + HILOGI("RemoveEventFromMap 12 fileName:%{public}s, removeEvents.size:%{public}d, toRemoveEvent:%{public}x", arg->fileName.c_str(), removeEvents.size(), toRemoveEvent); auto eventIter = find(fileIter->second.begin(), fileIter->second.end(), toRemoveEvent); - HILOGE("RemoveEventFromMap 13 fileName:%{public}s, removeEvents.size:%{public}d, toRemoveEvent:%{public}x", + HILOGI("RemoveEventFromMap 13 fileName:%{public}s, removeEvents.size:%{public}d, toRemoveEvent:%{public}x", arg->fileName.c_str(), removeEvents.size(), toRemoveEvent); if (eventIter == fileIter->second.end()) { - HILOGE("RemoveEventFromMap 14 fileName:%{public}s, removeEvents.size:%{public}d, toRemoveEvent:%{public}x", + HILOGI("RemoveEventFromMap 14 fileName:%{public}s, removeEvents.size:%{public}d, toRemoveEvent:%{public}x", arg->fileName.c_str(), removeEvents.size(), toRemoveEvent); continue; } - HILOGE("RemoveEventFromMap fileName:%{public}s remove:event%{public}x", arg->fileName.c_str(), toRemoveEvent); + HILOGI("RemoveEventFromMap fileName:%{public}s remove:event%{public}x", arg->fileName.c_str(), toRemoveEvent); fileIter->second.erase(eventIter); } if (fileIter->second.size() == 0) { fileNameEventMap_.erase(fileIter); } - HILOGE("RemoveEventFromMap fileName:%{public}s end", arg->fileName.c_str()); + HILOGI("RemoveEventFromMap fileName:%{public}s end", arg->fileName.c_str()); } bool FileWatcher::NotifyToWatchNewEvents(const shared_ptr &arg) @@ -232,7 +264,7 @@ bool FileWatcher::NotifyToWatchNewEvents(const shared_ptr &arg) } int newWd = inotify_add_watch(notifyFd_, arg->fileName.c_str(), watchEvent); - HILOGE("NotifyNewEvents fd:%{public}d, wd:%{public}d, fileName:%{public}s, watchEvent:%{public}x,newWd:%{public}d", + HILOGI("NotifyNewEvents fd:%{public}d, wd:%{public}d, fileName:%{public}s, watchEvent:%{public}x,newWd:%{public}d", notifyFd_, arg->wd, arg->fileName.c_str(), watchEvent, newWd); if (newWd < 0) { HILOGE("Failed to start new notify fail errCode:%{public}d", errno); @@ -259,32 +291,32 @@ bool FileWatcher::FindWatcherByFileName(const shared_ptr &arg) bool FileWatcher::StopNotify(const shared_ptr &arg) { lock_guard lock(watchMutex_); - HILOGE("FileWatcher::StopNotify!"); + HILOGI("FileWatcher::StopNotify!"); if (notifyFd_ < 0) { HILOGE("Failed to stop notify fail notifyFd_:%{public}d", notifyFd_); return false; } - HILOGE("StopNotify wd :%{public}d", arg->wd); + HILOGI("StopNotify wd :%{public}d", arg->wd); RemoveWatcherInfo(arg); if (FindWatcherByFileName(arg)) { - HILOGE("FindWatcherByFileName filename:%{public}s", arg->fileName.c_str()); + HILOGI("FindWatcherByFileName filename:%{public}s", arg->fileName.c_str()); bool ret = NotifyToWatchNewEvents(arg); if (!ret) { HILOGE("Failed to notify watch new event notifyFd_:%{public}d", notifyFd_); return false; } } else { - HILOGE("FindWatcherByFileName 2 filename:%{public}s", arg->fileName.c_str()); + HILOGI("FindWatcherByFileName 2 filename:%{public}s", arg->fileName.c_str()); auto iter = fileNameEventMap_.find(arg->fileName); if (iter != fileNameEventMap_.end()) { - HILOGE("FindWatcherByFileName 3 filename:%{public}s", arg->fileName.c_str()); + HILOGI("FindWatcherByFileName 3 filename:%{public}s", arg->fileName.c_str()); fileNameEventMap_.erase(iter); } } if (GetWatcherInfoSize(arg->wd) == 0) { - HILOGE("StopNotify 1"); + HILOGI("StopNotify 1"); if (inotify_rm_watch(notifyFd_, arg->wd) == -1) { - HILOGE("StopNotify 2"); + HILOGI("StopNotify 2"); auto iter = wdFileNameMap_.find(arg->wd); if (iter == wdFileNameMap_.end()) { HILOGE("Failed to stop notify, not find wd:%{public}d", arg->wd); @@ -297,15 +329,15 @@ bool FileWatcher::StopNotify(const shared_ptr &arg) return false; } } - HILOGE("StopNotify 3"); + HILOGI("StopNotify 3"); RemoveWatcherWdFileNameMap(arg->wd); if (watcherInfoMap_.size() == 0) { - HILOGE("StopNotify 4"); + HILOGI("StopNotify 4"); close(notifyFd_); notifyFd_ = -1; run_ = false; } - HILOGE("StopNotify 5"); + HILOGI("StopNotify 5"); return true; } return true; @@ -314,7 +346,7 @@ bool FileWatcher::StopNotify(const shared_ptr &arg) void FileWatcher::GetNotifyEvent(shared_ptr &arg, WatcherCallback callback) { if (run_) { - HILOGE("Listener Thread has started and do nothing!"); + HILOGI("Listener Thread has started and do nothing!"); return; } @@ -339,7 +371,7 @@ void FileWatcher::GetNotifyEvent(shared_ptr &arg, WatcherCallbac } } } - HILOGE("Listener Thread has stopped!"); + HILOGI("Listener Thread has stopped!"); } void FileWatcher::AddWatcherInfo(const string &fileName, const shared_ptr &arg) @@ -355,7 +387,7 @@ void FileWatcher::AddWatcherInfo(const string &fileName, const shared_ptrenv, info->nRef.Deref(info->env).val_, arg->nRef.Deref(arg->env).val_, &isSame); -HILOGE("AddWatcherInfo isSame: %{public}d", isSame); +HILOGI("AddWatcherInfo isSame: %{public}d", isSame); if (isSame && info->events == arg->events) { return; } @@ -365,17 +397,17 @@ HILOGE("AddWatcherInfo isSame: %{public}d", isSame); vector FileWatcher::ParseEvent(const string &fileName, const uint32_t &watcherEvent) { - HILOGE("ParseEvent begin fileName:%{public}s, watcherEvent:%{public}x", fileName.c_str(), watcherEvent); + HILOGI("ParseEvent begin fileName:%{public}s, watcherEvent:%{public}x", fileName.c_str(), watcherEvent); auto iter = fileNameEventMap_.find(fileName); if (iter == fileNameEventMap_.end()) { - HILOGE("ParseEvent 1 fileName:%{public}s, watcherEvent:%{public}x", fileName.c_str(), watcherEvent); + HILOGI("ParseEvent 1 fileName:%{public}s, watcherEvent:%{public}x", fileName.c_str(), watcherEvent); vector events = GetEvents(watcherEvent); fileNameEventMap_[fileName] = events; return events; } else { vector notWatchedEvents = FindUnWatchedEvent(iter->second, watcherEvent); if (notWatchedEvents.size() > 0) { - HILOGE("ParseEvent 2 fileName:%{public}s, watcherEvent:%{public}x, notWatchedEvents.size:%{public}d", + HILOGI("ParseEvent 2 fileName:%{public}s, watcherEvent:%{public}x, notWatchedEvents.size:%{public}d", fileName.c_str(), watcherEvent, notWatchedEvents.size()); vector newEvents; newEvents.insert(newEvents.end(), iter->second.begin(), iter->second.end()); @@ -386,7 +418,7 @@ vector FileWatcher::ParseEvent(const string &fileName, const uint32_t fileNameEventMap_[fileName] = newEvents; return newEvents; } else { - HILOGE("ParseEvent 4 fileName:%{public}s, watcherEvent:%{public}x, event:%{public}d", + HILOGI("ParseEvent 4 fileName:%{public}s, watcherEvent:%{public}x, event:%{public}d", fileName.c_str(), watcherEvent, iter->second.size()); return iter->second; } @@ -395,17 +427,17 @@ vector FileWatcher::ParseEvent(const string &fileName, const uint32_t void FileWatcher::RemoveWatcherInfo(const shared_ptr &arg) { - HILOGE("RemoveWatcherInfo filename:%{public}s, wd:%{public}d", arg->fileName.c_str(), arg->wd); + HILOGI("RemoveWatcherInfo filename:%{public}s, wd:%{public}d", arg->fileName.c_str(), arg->wd); auto fileNameIter = wdFileNameMap_.find(arg->wd); if (fileNameIter == wdFileNameMap_.end()) { - HILOGE("RemoveWatcherInfo 1 filename:%{public}s, wd:%{public}d", arg->fileName.c_str(), arg->wd); + HILOGI("RemoveWatcherInfo 1 filename:%{public}s, wd:%{public}d", arg->fileName.c_str(), arg->wd); return; } string fileName = fileNameIter->second; - HILOGE("RemoveWatcherInfo 2 filename:%{public}s, wd:%{public}d", arg->fileName.c_str(), arg->wd); + HILOGI("RemoveWatcherInfo 2 filename:%{public}s, wd:%{public}d", arg->fileName.c_str(), arg->wd); auto iter = watcherInfoMap_.find(fileName); if (iter == watcherInfoMap_.end()) { - HILOGE("RemoveWatcherInfo 3 filename:%{public}s, wd:%{public}d", arg->fileName.c_str(), arg->wd); + HILOGI("RemoveWatcherInfo 3 filename:%{public}s, wd:%{public}d", arg->fileName.c_str(), arg->wd); return; } auto infoArgs = iter->second; @@ -415,7 +447,7 @@ void FileWatcher::RemoveWatcherInfo(const shared_ptr &arg) napi_strict_equals(infoArgs[i]->env, infoArgs[i]->nRef.Deref(infoArgs[i]->env).val_, arg->nRef.Deref(arg->env).val_, &isSame); if (isSame) { - HILOGE("RemoveWatcherInfo 4 filename:%{public}s, wd:%{public}d", arg->fileName.c_str(), arg->wd); + HILOGI("RemoveWatcherInfo 4 filename:%{public}s, wd:%{public}d", arg->fileName.c_str(), arg->wd); iter->second.erase(iter->second.begin() + i); } } @@ -427,71 +459,71 @@ void FileWatcher::RemoveWatcherInfo(const shared_ptr &arg) int32_t FileWatcher::GetWatcherInfoSize(const int &wd) { - HILOGE("GetWatcherInfoSize 1"); + HILOGI("GetWatcherInfoSize 1"); auto fileNameIter = wdFileNameMap_.find(wd); if (fileNameIter == wdFileNameMap_.end()) { - HILOGE("GetWatcherInfoSize 2"); + HILOGI("GetWatcherInfoSize 2"); return 0; } string fileName = fileNameIter->second; auto watcherInfosIter = watcherInfoMap_.find(fileName); if (watcherInfosIter == watcherInfoMap_.end()) { - HILOGE("GetWatcherInfoSize 3"); + HILOGI("GetWatcherInfoSize 3"); return 0; } - HILOGE("GetWatcherInfoSize 4 size:%{public}d", watcherInfosIter->second.size()); + HILOGI("GetWatcherInfoSize 4 size:%{public}d", watcherInfosIter->second.size()); return watcherInfosIter->second.size(); } bool CheckIncludeEvent(const uint32_t &allEvent, const uint32_t &event) { - HILOGE("CheckIncludeEvent 1 allEvent:%{public}x, event:%{public}x", allEvent, event); + HILOGI("CheckIncludeEvent 1 allEvent:%{public}x, event:%{public}x", allEvent, event); vector events = GetEvents(event); - HILOGE("CheckIncludeEvent 2 events.size:%{public}d", events.size()); + HILOGI("CheckIncludeEvent 2 events.size:%{public}d", events.size()); for (auto event : events) { - HILOGE("CheckIncludeEvent 3 event:%{public}x", event); + HILOGI("CheckIncludeEvent 3 event:%{public}x", event); if (allEvent & event) { - HILOGE("CheckIncludeEvent 4 allEvent:%{public}x, event:%{public}x", allEvent, event); + HILOGI("CheckIncludeEvent 4 allEvent:%{public}x, event:%{public}x", allEvent, event); return true; } } - HILOGE("CheckIncludeEvent 5 allEvent:%{public}x, event:%{public}x", allEvent, event); + HILOGI("CheckIncludeEvent 5 allEvent:%{public}x, event:%{public}x", allEvent, event); return false; } void FileWatcher::NotifyEvent(const struct inotify_event *event, WatcherCallback callback) { lock_guard lock(watchMutex_); - HILOGE("NotifyEvent 1 wd:%{public}d, mask:%{public}x", event->wd, event->mask); + HILOGI("NotifyEvent 1 wd:%{public}d, mask:%{public}x", event->wd, event->mask); auto fileNameIter = wdFileNameMap_.find(event->wd); if (fileNameIter == wdFileNameMap_.end()) { return; } - HILOGE("NotifyEvent 2 wd:%{public}d", event->wd); + HILOGI("NotifyEvent 2 wd:%{public}d", event->wd); string fileName = fileNameIter->second; - HILOGE("NotifyEvent 3 wd:%{public}d, fileName:%{public}s", event->wd, fileName.c_str()); + HILOGI("NotifyEvent 3 wd:%{public}d, fileName:%{public}s", event->wd, fileName.c_str()); auto watcherInfosIter = watcherInfoMap_.find(fileName); if (watcherInfosIter == watcherInfoMap_.end()) { return; } - HILOGE("NotifyEvent 4 wd:%{public}d, fileName:%{public}s", event->wd, fileName.c_str()); + HILOGI("NotifyEvent 4 wd:%{public}d, fileName:%{public}s", event->wd, fileName.c_str()); auto args = watcherInfosIter->second; for (auto arg : args) { uint32_t watchEvent = arg->events; - HILOGE("NotifyEvent 5 wd:%{public}d, fileName:%{public}s, watchEvent:%{public}x", event->wd, fileName.c_str(), + HILOGI("NotifyEvent 5 wd:%{public}d, fileName:%{public}s, watchEvent:%{public}x", event->wd, fileName.c_str(), arg->events); if (!CheckIncludeEvent(event->mask, watchEvent)) { - HILOGE("NotifyEvent 6 wd:%{public}d, fileName:%{public}s, watchEvent:%{public}x, mask:%{public}x", + HILOGI("NotifyEvent 6 wd:%{public}d, fileName:%{public}s, watchEvent:%{public}x, mask:%{public}x", event->wd, fileName.c_str(), arg->events, event->mask); return; } if (event->len > 0) { - HILOGE("NotifyEvent 7 wd:%{public}d, fileName:%{public}s, watchEvent:%{public}x, mask:%{public}x", + HILOGI("NotifyEvent 7 wd:%{public}d, fileName:%{public}s, watchEvent:%{public}x, mask:%{public}x", event->wd, fileName.c_str(), arg->events, event->mask); fileName.append(string("/")); fileName.append(string(event->name)); } - HILOGE("NotifyEvent 8 wd:%{public}d, fileName:%{public}s, watchEvent:%{public}x, mask:%{public}x", + HILOGI("NotifyEvent 8 wd:%{public}d, fileName:%{public}s, watchEvent:%{public}x, mask:%{public}x", event->wd, fileName.c_str(), arg->events, event->mask); callback(arg->env, arg->nRef, fileName, event->mask, event->cookie); } @@ -499,27 +531,27 @@ void FileWatcher::NotifyEvent(const struct inotify_event *event, WatcherCallback void FileWatcher::AddWatcherWdFileNameMap(const int &wd, const string &fileName) { - HILOGE("AddWatcherWdFileNameMap fileName:%{public}s, wd:%{public}d", fileName.c_str(), wd); + HILOGI("AddWatcherWdFileNameMap fileName:%{public}s, wd:%{public}d", fileName.c_str(), wd); auto it = wdFileNameMap_.find(wd); if (it == wdFileNameMap_.end()) { - HILOGE("AddWatcherWdFileNameMap fileName:%{public}s, wd:%{public}d insert", fileName.c_str(), wd); + HILOGI("AddWatcherWdFileNameMap fileName:%{public}s, wd:%{public}d insert", fileName.c_str(), wd); wdFileNameMap_.insert(pair(wd, fileName)); } } void FileWatcher::RemoveWatcherWdFileNameMap(const int &wd) { - HILOGE("RemoveWatcherWdFileNameMap wd:%{public}d", wd); + HILOGI("RemoveWatcherWdFileNameMap wd:%{public}d", wd); auto pathIter = wdFileNameMap_.find(wd); if(pathIter != wdFileNameMap_.end()) { string fileName = pathIter->second; - HILOGE("RemoveWatcherWdFileNameMap wd:%{public}d, fileName:%{public}s", wd, fileName.c_str()); + HILOGI("RemoveWatcherWdFileNameMap wd:%{public}d, fileName:%{public}s", wd, fileName.c_str()); auto watcherInfosIter = watcherInfoMap_.find(fileName); if (watcherInfosIter == watcherInfoMap_.end()) { - HILOGE("RemoveWatcherWdFileNameMap 1 wd:%{public}d, fileName:%{public}s", wd, fileName.c_str()); + HILOGI("RemoveWatcherWdFileNameMap 1 wd:%{public}d, fileName:%{public}s", wd, fileName.c_str()); wdFileNameMap_.erase(pathIter); } else { - HILOGE("RemoveWatcherWdFileNameMap 2 wd:%{public}d, fileName:%{public}s", wd, fileName.c_str()); + HILOGI("RemoveWatcherWdFileNameMap 2 wd:%{public}d, fileName:%{public}s", wd, fileName.c_str()); } } } diff --git a/interfaces/kits/js/src/mod_fs/class_watcher/watcher_entity.h b/interfaces/kits/js/src/mod_fs/class_watcher/watcher_entity.h index 504489605..a7283df3f 100644 --- a/interfaces/kits/js/src/mod_fs/class_watcher/watcher_entity.h +++ b/interfaces/kits/js/src/mod_fs/class_watcher/watcher_entity.h @@ -67,7 +67,7 @@ private: bool FindWatcherInfo(const std::string &fileName, const uint32_t &event); bool FindWatcherByFileName(const std::shared_ptr &arg); void RemoveEventFromMap(const std::shared_ptr &arg); - + bool CheckEventValid(const uint32_t &event); private: static std::mutex mutex_; static std::mutex watchMutex_; diff --git a/interfaces/kits/js/src/mod_fs/properties/watcher.cpp b/interfaces/kits/js/src/mod_fs/properties/watcher.cpp index 941dc52f0..c9d55b458 100644 --- a/interfaces/kits/js/src/mod_fs/properties/watcher.cpp +++ b/interfaces/kits/js/src/mod_fs/properties/watcher.cpp @@ -58,12 +58,17 @@ napi_value Watcher::CreateWatcher(napi_env env, napi_callback_info info) return nullptr; } - auto [succGetEvent, events] = NVal(env, funcArg[NARG_POS::SECOND]).ToUint32(); + auto [succGetEvent, events] = NVal(env, funcArg[NARG_POS::SECOND]).ToInt32(); if (!succGetEvent) { NError(EINVAL).ThrowErr(env); return nullptr; } + HILOGE("CreateWatcher events: %{public}d", events); + if (events <= 0) { + NError(EINVAL).ThrowErr(env); + return nullptr; + } HILOGE("CreateWatcher notifyFd_1: %{public}d", FileWatcher::GetInstance()->GetNotifyId()); if (FileWatcher::GetInstance()->GetNotifyId() < 0 && !FileWatcher::GetInstance()->InitNotify()) { NError(errno).ThrowErr(env); -- Gitee From b31c4f3c8011a49c24c7e58fc483faca3732a6f9 Mon Sep 17 00:00:00 2001 From: Cao Chuan Date: Wed, 14 Jun 2023 15:55:12 +0800 Subject: [PATCH 21/27] Fix can not finish thread issue Signed-off-by: Cao Chuan --- .../js/src/mod_fs/class_watcher/watcher_entity.cpp | 10 +++++++++- .../kits/js/src/mod_fs/class_watcher/watcher_entity.h | 3 +++ 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/interfaces/kits/js/src/mod_fs/class_watcher/watcher_entity.cpp b/interfaces/kits/js/src/mod_fs/class_watcher/watcher_entity.cpp index d78889181..bfe21ab49 100644 --- a/interfaces/kits/js/src/mod_fs/class_watcher/watcher_entity.cpp +++ b/interfaces/kits/js/src/mod_fs/class_watcher/watcher_entity.cpp @@ -29,6 +29,8 @@ using namespace OHOS::FileManagement::LibN; using namespace std; namespace { + constexpr int64_t SELECT_TIME_OUT_US = 100000; + constexpr int64_t STOP_WATCHER_TIME_OUT_US = 120000; const vector EVENT_LIST = { IN_ACCESS, IN_MODIFY, IN_ATTRIB, IN_CLOSE_WRITE, IN_CLOSE_NOWRITE, IN_CLOSE, IN_OPEN, IN_MOVED_FROM, IN_MOVED_TO, IN_MOVE, IN_CREATE, IN_DELETE, IN_DELETE_SELF, IN_MOVE_SELF }; @@ -336,6 +338,7 @@ bool FileWatcher::StopNotify(const shared_ptr &arg) close(notifyFd_); notifyFd_ = -1; run_ = false; + stopWatcherCv_.wait_for(lock, chrono::milliseconds(STOP_WATCHER_TIME_OUT_US)); } HILOGI("StopNotify 5"); return true; @@ -361,7 +364,8 @@ void FileWatcher::GetNotifyEvent(shared_ptr &arg, WatcherCallbac fd_set fds; FD_ZERO(&fds); FD_SET(notifyFd_, &fds); - if (select(notifyFd_ + 1, &fds, nullptr, nullptr, nullptr) > 0) { + timeval timeout{.tv_sec = 0, .tv_usec = SELECT_TIME_OUT_US}; + if (select(notifyFd_ + 1, &fds, nullptr, nullptr, &timeout) > 0) { int len, index = 0; while (((len = read(notifyFd_, &buf, sizeof(buf))) < 0) && (errno == EINTR)) {}; while (index < len) { @@ -371,6 +375,10 @@ void FileWatcher::GetNotifyEvent(shared_ptr &arg, WatcherCallbac } } } + + if (!run_) { + stopWatcherCv_.notify_one(); + } HILOGI("Listener Thread has stopped!"); } diff --git a/interfaces/kits/js/src/mod_fs/class_watcher/watcher_entity.h b/interfaces/kits/js/src/mod_fs/class_watcher/watcher_entity.h index a7283df3f..272d589c3 100644 --- a/interfaces/kits/js/src/mod_fs/class_watcher/watcher_entity.h +++ b/interfaces/kits/js/src/mod_fs/class_watcher/watcher_entity.h @@ -14,6 +14,8 @@ */ #ifndef INTERFACES_KITS_JS_SRC_MOD_FILEIO_CLASS_WATCHER_WATCHER_ENTITY_H #define INTERFACES_KITS_JS_SRC_MOD_FILEIO_CLASS_WATCHER_WATCHER_ENTITY_H + +#include #include #include #include @@ -77,6 +79,7 @@ private: WatcherInfoMap watcherInfoMap_; std::map wdFileNameMap_; std::map> fileNameEventMap_; + std::condition_variable stopWatcherCv_; }; struct WatcherEntity { -- Gitee From 08a5cc1fe764d2d5a0eee0f99ffb1a1bf4473b44 Mon Sep 17 00:00:00 2001 From: Cao Chuan Date: Wed, 14 Jun 2023 16:44:51 +0800 Subject: [PATCH 22/27] Fix compile issue for can not finish thread issue Signed-off-by: Cao Chuan --- interfaces/kits/js/src/mod_fs/class_watcher/watcher_entity.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interfaces/kits/js/src/mod_fs/class_watcher/watcher_entity.cpp b/interfaces/kits/js/src/mod_fs/class_watcher/watcher_entity.cpp index bfe21ab49..96aa324ff 100644 --- a/interfaces/kits/js/src/mod_fs/class_watcher/watcher_entity.cpp +++ b/interfaces/kits/js/src/mod_fs/class_watcher/watcher_entity.cpp @@ -292,7 +292,7 @@ bool FileWatcher::FindWatcherByFileName(const shared_ptr &arg) bool FileWatcher::StopNotify(const shared_ptr &arg) { - lock_guard lock(watchMutex_); + unique_lock lock(watchMutex_); HILOGI("FileWatcher::StopNotify!"); if (notifyFd_ < 0) { HILOGE("Failed to stop notify fail notifyFd_:%{public}d", notifyFd_); -- Gitee From 6a7a16b7d6af0959b9f929cd7f11be996dfc391e Mon Sep 17 00:00:00 2001 From: Cao Chuan Date: Thu, 15 Jun 2023 14:36:10 +0800 Subject: [PATCH 23/27] Synchronize branch commit Signed-off-by: Cao Chuan --- .../mod_fs/class_watcher/watcher_entity.cpp | 15 +++------ .../src/mod_fs/class_watcher/watcher_entity.h | 6 +++- .../kits/js/src/mod_fs/properties/watcher.cpp | 31 +++++++++++++------ 3 files changed, 31 insertions(+), 21 deletions(-) diff --git a/interfaces/kits/js/src/mod_fs/class_watcher/watcher_entity.cpp b/interfaces/kits/js/src/mod_fs/class_watcher/watcher_entity.cpp index 96aa324ff..54acb2450 100644 --- a/interfaces/kits/js/src/mod_fs/class_watcher/watcher_entity.cpp +++ b/interfaces/kits/js/src/mod_fs/class_watcher/watcher_entity.cpp @@ -34,11 +34,12 @@ namespace { const vector EVENT_LIST = { IN_ACCESS, IN_MODIFY, IN_ATTRIB, IN_CLOSE_WRITE, IN_CLOSE_NOWRITE, IN_CLOSE, IN_OPEN, IN_MOVED_FROM, IN_MOVED_TO, IN_MOVE, IN_CREATE, IN_DELETE, IN_DELETE_SELF, IN_MOVE_SELF }; -} // namespace +} shared_ptr FileWatcher::instance_ = nullptr; mutex FileWatcher::mutex_; mutex FileWatcher::watchMutex_; + shared_ptr FileWatcher::GetInstance() { if (instance_ == nullptr) { @@ -111,13 +112,7 @@ bool FileWatcher::CheckEventValid(const uint32_t &event) { HILOGI("CheckEventValid begin:event:%{public}x", event); vector events = GetEvents(event); - HILOGI("CheckEventValid 1:event:%{public}x, events.size:%{public}d", event, events.size()); - if (events.size() > 0) { - HILOGI("CheckEventValid 2:event:%{public}x, events.size:%{public}d", event, events.size()); - return true; - } - HILOGI("CheckEventValid 3:event:%{public}x, events.size:%{public}d", event, events.size()); - return false; + return events.size() > 0 ? true : false; } bool FileWatcher::StartNotify(shared_ptr &arg) @@ -138,7 +133,7 @@ bool FileWatcher::StartNotify(shared_ptr &arg) if (CheckEventWatched(arg->fileName, arg->events)) { for (auto iter = wdFileNameMap_.begin(); iter != wdFileNameMap_.end(); iter++) { HILOGI("StartNotify 1 fileName:%{public}s", arg->fileName.c_str()); - if (iter->second.compare(arg->fileName) == 0) { + if (iter->second == arg->fileName) { HILOGI("StartNotify 2 fileName:%{public}s, wd:%{public}d", arg->fileName.c_str(), iter->first); arg->wd = iter->first; return true; @@ -326,8 +321,8 @@ bool FileWatcher::StopNotify(const shared_ptr &arg) } string filename = iter->second; if (access(filename.c_str(), F_OK) == 0) { - RemoveWatcherWdFileNameMap(arg->wd); HILOGE("Failed to stop notify fail errCode:%{public}d", errno); + RemoveWatcherWdFileNameMap(arg->wd); return false; } } diff --git a/interfaces/kits/js/src/mod_fs/class_watcher/watcher_entity.h b/interfaces/kits/js/src/mod_fs/class_watcher/watcher_entity.h index 272d589c3..e7d6dab56 100644 --- a/interfaces/kits/js/src/mod_fs/class_watcher/watcher_entity.h +++ b/interfaces/kits/js/src/mod_fs/class_watcher/watcher_entity.h @@ -18,19 +18,22 @@ #include #include #include +#include #include #include #include #include #include -#include + #include "filemgmt_libn.h" + namespace OHOS::FileManagement::ModuleFileIO { using WatcherCallback = void (*)(napi_env env, LibN::NRef &callback, const std::string &filename, const uint32_t &event, const uint32_t &cookie); + constexpr int BUF_SIZE = 1024; struct WatcherInfoArg { std::string fileName = ""; @@ -70,6 +73,7 @@ private: bool FindWatcherByFileName(const std::shared_ptr &arg); void RemoveEventFromMap(const std::shared_ptr &arg); bool CheckEventValid(const uint32_t &event); + private: static std::mutex mutex_; static std::mutex watchMutex_; diff --git a/interfaces/kits/js/src/mod_fs/properties/watcher.cpp b/interfaces/kits/js/src/mod_fs/properties/watcher.cpp index c9d55b458..fd955f99c 100644 --- a/interfaces/kits/js/src/mod_fs/properties/watcher.cpp +++ b/interfaces/kits/js/src/mod_fs/properties/watcher.cpp @@ -39,6 +39,18 @@ namespace { } } +static tuple CreateAndCheckForWatcherEntity(napi_env env, int& fd) +{ + if (FileWatcher::GetInstance()->GetNotifyId() < 0 && !FileWatcher::GetInstance()->InitNotify()) { + return {nullptr, NError(errno)}; + } + napi_value objWatcher = NClass::InstantiateClass(env, WatcherNExporter::className_, {}); + if (!objWatcher) { + return {nullptr, NError(EINVAL)}; + } + return {objWatcher, NError(ERRNO_NOERR)}; +} + napi_value Watcher::CreateWatcher(napi_env env, napi_callback_info info) { if (!IsSystemApp()) { @@ -69,16 +81,11 @@ napi_value Watcher::CreateWatcher(napi_env env, napi_callback_info info) NError(EINVAL).ThrowErr(env); return nullptr; } -HILOGE("CreateWatcher notifyFd_1: %{public}d", FileWatcher::GetInstance()->GetNotifyId()); - if (FileWatcher::GetInstance()->GetNotifyId() < 0 && !FileWatcher::GetInstance()->InitNotify()) { - NError(errno).ThrowErr(env); - return nullptr; - } -HILOGE("CreateWatcher notifyFd_2: %{public}d", FileWatcher::GetInstance()->GetNotifyId()); - napi_value objWatcher = NClass::InstantiateClass(env, WatcherNExporter::className_, {}); + int fd = -1; + auto [objWatcher, err] = CreateAndCheckForWatcherEntity(env, fd); if (!objWatcher) { - NError(EINVAL).ThrowErr(env); + err.ThrowErr(env); return nullptr; } @@ -92,8 +99,12 @@ HILOGE("CreateWatcher notifyFd_2: %{public}d", FileWatcher::GetInstance()->GetNo NError(EINVAL).ThrowErr(env); return nullptr; } - - auto infoArg = make_shared(NVal(env, funcArg[NARG_POS::THIRD])); + auto infoArg = CreateSharedPtr(NVal(env, funcArg[NARG_POS::THIRD])); + if (infoArg == nullptr) { + HILOGE("Failed to request heap memory."); + NError(ENOMEM).ThrowErr(env); + return nullptr; + } infoArg->events = events; infoArg->env = env; infoArg->fileName = string(filename.get()); -- Gitee From db86ba178a793b1134535cf8a1bd309584975dd5 Mon Sep 17 00:00:00 2001 From: Cao Chuan Date: Fri, 16 Jun 2023 17:13:15 +0800 Subject: [PATCH 24/27] add log Signed-off-by: Cao Chuan --- .../mod_fs/class_watcher/watcher_n_exporter.cpp | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/interfaces/kits/js/src/mod_fs/class_watcher/watcher_n_exporter.cpp b/interfaces/kits/js/src/mod_fs/class_watcher/watcher_n_exporter.cpp index 6d752a8a8..aa86abf87 100644 --- a/interfaces/kits/js/src/mod_fs/class_watcher/watcher_n_exporter.cpp +++ b/interfaces/kits/js/src/mod_fs/class_watcher/watcher_n_exporter.cpp @@ -160,34 +160,45 @@ static void WatcherCallbackComplete(uv_work_t *work, int stat) void WatcherNExporter::WatcherCallback(napi_env env, NRef &callback, const std::string &fileName, const uint32_t &event, const uint32_t &cookie) { + HILOGI("WatcherCallback 1 fileName:%{public}s, event:%{public}x, cookie:%{public}d", + fileName.c_str(), event, cookie); uv_loop_s *loop = nullptr; + HILOGI("WatcherCallback 2"); napi_get_uv_event_loop(env, &loop); + HILOGI("WatcherCallback 3"); if (loop == nullptr) { + HILOGI("WatcherCallback 4"); HILOGE("Failed to get uv event loop"); return; } - + HILOGI("WatcherCallback 5"); uv_work_t *work = new (std::nothrow) uv_work_t; + HILOGI("WatcherCallback 6"); if (work == nullptr) { + HILOGI("WatcherCallback 7"); HILOGE("Failed to create uv_work_t pointer"); return; } - + HILOGI("WatcherCallback 8"); if (!callback) { + HILOGI("WatcherCallback 9"); HILOGE("Failed to pass watcher callback"); return; } + HILOGI("WatcherCallback 10"); JSCallbackContext *callbackContext = new (std::nothrow) JSCallbackContext(callback); callbackContext->env_ = env; callbackContext->fileName_ = fileName; callbackContext->event_ = event; callbackContext->cookie_ = cookie; work->data = reinterpret_cast(callbackContext); - + HILOGI("WatcherCallback 11"); int ret = uv_queue_work( loop, work, [](uv_work_t *work) {}, reinterpret_cast(WatcherCallbackComplete)); + HILOGI("WatcherCallback 12"); if (ret != 0) { + HILOGI("WatcherCallback 13"); HILOGE("Failed to execute libuv work queue, ret: %{public}d", ret); delete callbackContext; delete work; -- Gitee From ac8500e3499786c658c6c61e59082af0b4cd1e2b Mon Sep 17 00:00:00 2001 From: Cao Chuan Date: Tue, 20 Jun 2023 10:42:10 +0800 Subject: [PATCH 25/27] add lock Signed-off-by: Cao Chuan --- .../mod_fs/class_watcher/watcher_entity.cpp | 23 ++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/interfaces/kits/js/src/mod_fs/class_watcher/watcher_entity.cpp b/interfaces/kits/js/src/mod_fs/class_watcher/watcher_entity.cpp index 54acb2450..8e64cb00e 100644 --- a/interfaces/kits/js/src/mod_fs/class_watcher/watcher_entity.cpp +++ b/interfaces/kits/js/src/mod_fs/class_watcher/watcher_entity.cpp @@ -31,9 +31,9 @@ using namespace std; namespace { constexpr int64_t SELECT_TIME_OUT_US = 100000; constexpr int64_t STOP_WATCHER_TIME_OUT_US = 120000; - const vector EVENT_LIST = { IN_ACCESS, IN_MODIFY, IN_ATTRIB, IN_CLOSE_WRITE, IN_CLOSE_NOWRITE, - IN_CLOSE, IN_OPEN, IN_MOVED_FROM, IN_MOVED_TO, IN_MOVE, - IN_CREATE, IN_DELETE, IN_DELETE_SELF, IN_MOVE_SELF }; + const vector EVENT_LIST = { IN_ACCESS, IN_MODIFY, IN_ATTRIB, IN_CLOSE_WRITE, IN_CLOSE_NOWRITE, + IN_OPEN, IN_MOVED_FROM, IN_MOVED_TO, IN_CREATE, IN_DELETE, + IN_DELETE_SELF, IN_MOVE_SELF }; } shared_ptr FileWatcher::instance_ = nullptr; @@ -70,7 +70,9 @@ vector GetEvents(const uint32_t &watchEvent) { vector eventList; for (auto event : EVENT_LIST) { + HILOGI("GetEvents 1 watchEvent:%{public}x, event:%{public}x", watchEvent, event); if (watchEvent & event) { + HILOGI("GetEvents 2 watchEvent:%{public}x, event:%{public}x", watchEvent, event); eventList.push_back(event); } } @@ -79,6 +81,11 @@ vector GetEvents(const uint32_t &watchEvent) vector FindUnWatchedEvent(const vector &allEvents, const uint32_t &event) { + HILOGI("FindUnWatchedEvent allEvents.size:%{public}d, event:%{public}x", allEvents.size(), event); + for(auto allevent: allEvents) { + HILOGI("FindUnWatchedEvent 1 allEvents.size:%{public}d, allevent:%{public}x", allEvents.size(), allevent); + } + vector unWatchedEvents; vector watchEvents = GetEvents(event); HILOGI("FindUnWatchedEvent 2 watchEvents:%{public}d", watchEvents.size()); @@ -95,6 +102,7 @@ vector FindUnWatchedEvent(const vector &allEvents, const uin bool FileWatcher::CheckEventWatched(const string &fileName, const uint32_t &event) { + HILOGI("CheckEventWatched fileName:%{public}s, event:%{public}x", fileName.c_str(), event); auto iter = fileNameEventMap_.find(fileName); if (iter == fileNameEventMap_.end()) { return false; @@ -148,7 +156,9 @@ bool FileWatcher::StartNotify(shared_ptr &arg) uint32_t watchEvent = 0; for (auto event: watchEvents) { watchEvent |= event; + HILOGI("StartNotify 4 fileName:%{public}s, event:%{public}x, watchEvent:%{public}x", arg->fileName.c_str(), event, watchEvent); } + HILOGI("StartNotify 5 fileName:%{public}s, watchEvent:%{public}x", arg->fileName.c_str(), watchEvent); int wd = inotify_add_watch(notifyFd_, arg->fileName.c_str(), watchEvent); HILOGI("StartNotify fileName:%{public}s, wd:%{public}d", arg->fileName.c_str(), wd); if (wd < 0) { @@ -379,6 +389,7 @@ void FileWatcher::GetNotifyEvent(shared_ptr &arg, WatcherCallbac void FileWatcher::AddWatcherInfo(const string &fileName, const shared_ptr &arg) { + unique_lock lock(watchMutex_); WatcherInfoMap::iterator it = watcherInfoMap_.find(fileName); if (it == watcherInfoMap_.end()) { vector> watcherInfoVec = { arg }; @@ -408,6 +419,8 @@ vector FileWatcher::ParseEvent(const string &fileName, const uint32_t fileNameEventMap_[fileName] = events; return events; } else { + HILOGI("ParseEvent 01 fileName:%{public}s, iter->second.size:%{public}d", fileName.c_str(), + iter->second.size()); vector notWatchedEvents = FindUnWatchedEvent(iter->second, watcherEvent); if (notWatchedEvents.size() > 0) { HILOGI("ParseEvent 2 fileName:%{public}s, watcherEvent:%{public}x, notWatchedEvents.size:%{public}d", @@ -419,6 +432,8 @@ vector FileWatcher::ParseEvent(const string &fileName, const uint32_t auto newEventIter = unique(newEvents.begin(), newEvents.end()); newEvents.erase(newEventIter, newEvents.end()); fileNameEventMap_[fileName] = newEvents; + HILOGI("ParseEvent 3 fileName:%{public}s, watcherEvent:%{public}x, newEvents.size:%{public}d", + fileName.c_str(), watcherEvent, newEvents.size()); return newEvents; } else { HILOGI("ParseEvent 4 fileName:%{public}s, watcherEvent:%{public}x, event:%{public}d", @@ -511,6 +526,8 @@ void FileWatcher::NotifyEvent(const struct inotify_event *event, WatcherCallback } HILOGI("NotifyEvent 4 wd:%{public}d, fileName:%{public}s", event->wd, fileName.c_str()); auto args = watcherInfosIter->second; + HILOGI("NotifyEvent 04 wd:%{public}d, fileName:%{public}s, args.size:%{public}d", + event->wd, fileName.c_str(), args.size()); for (auto arg : args) { uint32_t watchEvent = arg->events; HILOGI("NotifyEvent 5 wd:%{public}d, fileName:%{public}s, watchEvent:%{public}x", event->wd, fileName.c_str(), -- Gitee From 6441815ba8c62a97eb5e98c458828952a9b00ef5 Mon Sep 17 00:00:00 2001 From: Cao Chuan Date: Tue, 20 Jun 2023 14:53:29 +0800 Subject: [PATCH 26/27] modify notify Signed-off-by: Cao Chuan --- .../js/src/mod_fs/class_watcher/watcher_entity.cpp | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/interfaces/kits/js/src/mod_fs/class_watcher/watcher_entity.cpp b/interfaces/kits/js/src/mod_fs/class_watcher/watcher_entity.cpp index 8e64cb00e..6875062db 100644 --- a/interfaces/kits/js/src/mod_fs/class_watcher/watcher_entity.cpp +++ b/interfaces/kits/js/src/mod_fs/class_watcher/watcher_entity.cpp @@ -72,7 +72,7 @@ vector GetEvents(const uint32_t &watchEvent) for (auto event : EVENT_LIST) { HILOGI("GetEvents 1 watchEvent:%{public}x, event:%{public}x", watchEvent, event); if (watchEvent & event) { - HILOGI("GetEvents 2 watchEvent:%{public}x, event:%{public}x", watchEvent, event); + HILOGI("GetEvents 2 found watchEvent:%{public}x", watchEvent); eventList.push_back(event); } } @@ -389,7 +389,6 @@ void FileWatcher::GetNotifyEvent(shared_ptr &arg, WatcherCallbac void FileWatcher::AddWatcherInfo(const string &fileName, const shared_ptr &arg) { - unique_lock lock(watchMutex_); WatcherInfoMap::iterator it = watcherInfoMap_.find(fileName); if (it == watcherInfoMap_.end()) { vector> watcherInfoVec = { arg }; @@ -501,7 +500,7 @@ bool CheckIncludeEvent(const uint32_t &allEvent, const uint32_t &event) for (auto event : events) { HILOGI("CheckIncludeEvent 3 event:%{public}x", event); if (allEvent & event) { - HILOGI("CheckIncludeEvent 4 allEvent:%{public}x, event:%{public}x", allEvent, event); + HILOGI("CheckIncludeEvent 4 found event:%{public}x", event); return true; } } @@ -528,6 +527,10 @@ void FileWatcher::NotifyEvent(const struct inotify_event *event, WatcherCallback auto args = watcherInfosIter->second; HILOGI("NotifyEvent 04 wd:%{public}d, fileName:%{public}s, args.size:%{public}d", event->wd, fileName.c_str(), args.size()); + for (int i = 0; i < args.size(); i++) { + HILOGI("NotifyEvent 05 i:%{public}d, wd:%{public}d, fileName:%{public}s, watchEvent:%{public}x", + i, event->wd, fileName.c_str(), args[i]->events); + } for (auto arg : args) { uint32_t watchEvent = arg->events; HILOGI("NotifyEvent 5 wd:%{public}d, fileName:%{public}s, watchEvent:%{public}x", event->wd, fileName.c_str(), @@ -535,7 +538,7 @@ void FileWatcher::NotifyEvent(const struct inotify_event *event, WatcherCallback if (!CheckIncludeEvent(event->mask, watchEvent)) { HILOGI("NotifyEvent 6 wd:%{public}d, fileName:%{public}s, watchEvent:%{public}x, mask:%{public}x", event->wd, fileName.c_str(), arg->events, event->mask); - return; + continue; } if (event->len > 0) { HILOGI("NotifyEvent 7 wd:%{public}d, fileName:%{public}s, watchEvent:%{public}x, mask:%{public}x", -- Gitee From d8d7d962f7c7d7232092a8a1cc8e1ee32cf57b5c Mon Sep 17 00:00:00 2001 From: Cao Chuan Date: Tue, 20 Jun 2023 16:29:33 +0800 Subject: [PATCH 27/27] code review Signed-off-by: Cao Chuan --- .../kits/js/src/mod_fs/class_watcher/watcher_entity.cpp | 6 +++--- .../kits/js/src/mod_fs/class_watcher/watcher_entity.h | 2 +- .../kits/js/src/mod_fs/class_watcher/watcher_n_exporter.cpp | 2 +- interfaces/kits/js/src/mod_fs/properties/watcher.cpp | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/interfaces/kits/js/src/mod_fs/class_watcher/watcher_entity.cpp b/interfaces/kits/js/src/mod_fs/class_watcher/watcher_entity.cpp index 6875062db..f3adc6961 100644 --- a/interfaces/kits/js/src/mod_fs/class_watcher/watcher_entity.cpp +++ b/interfaces/kits/js/src/mod_fs/class_watcher/watcher_entity.cpp @@ -32,7 +32,7 @@ namespace { constexpr int64_t SELECT_TIME_OUT_US = 100000; constexpr int64_t STOP_WATCHER_TIME_OUT_US = 120000; const vector EVENT_LIST = { IN_ACCESS, IN_MODIFY, IN_ATTRIB, IN_CLOSE_WRITE, IN_CLOSE_NOWRITE, - IN_OPEN, IN_MOVED_FROM, IN_MOVED_TO, IN_CREATE, IN_DELETE, + IN_OPEN, IN_MOVED_FROM, IN_MOVED_TO, IN_CREATE, IN_DELETE, IN_DELETE_SELF, IN_MOVE_SELF }; } @@ -172,7 +172,7 @@ bool FileWatcher::StartNotify(shared_ptr &arg) bool FileWatcher::FindWatcherInfo(const std::string &fileName, const uint32_t &event) { - auto iter = watcherInfoMap_.find(fileName); + auto iter = watcherInfoMap_.find(fileName); if (iter == watcherInfoMap_.end()) { return false; } @@ -351,7 +351,7 @@ bool FileWatcher::StopNotify(const shared_ptr &arg) return true; } -void FileWatcher::GetNotifyEvent(shared_ptr &arg, WatcherCallback callback) +void FileWatcher::GetNotifyEvent(WatcherCallback callback) { if (run_) { HILOGI("Listener Thread has started and do nothing!"); diff --git a/interfaces/kits/js/src/mod_fs/class_watcher/watcher_entity.h b/interfaces/kits/js/src/mod_fs/class_watcher/watcher_entity.h index e7d6dab56..36fb462cd 100644 --- a/interfaces/kits/js/src/mod_fs/class_watcher/watcher_entity.h +++ b/interfaces/kits/js/src/mod_fs/class_watcher/watcher_entity.h @@ -56,7 +56,7 @@ public: bool InitNotify(); bool StartNotify(std::shared_ptr &arg); bool StopNotify(const std::shared_ptr &arg); - void GetNotifyEvent(std::shared_ptr &arg, WatcherCallback callback); + void GetNotifyEvent(WatcherCallback callback); void AddWatcherInfo(const std::string &fileName, const std::shared_ptr &arg); private: diff --git a/interfaces/kits/js/src/mod_fs/class_watcher/watcher_n_exporter.cpp b/interfaces/kits/js/src/mod_fs/class_watcher/watcher_n_exporter.cpp index aa86abf87..10c4bb06e 100644 --- a/interfaces/kits/js/src/mod_fs/class_watcher/watcher_n_exporter.cpp +++ b/interfaces/kits/js/src/mod_fs/class_watcher/watcher_n_exporter.cpp @@ -97,7 +97,7 @@ HILOGE("WatcherNExporter::Start filename: %{public}s", watchEntity->data_->fileN auto cbExec = [watchEntity]() -> NError { HILOGE("WatcherNExporter::Start GetNotifyEvent wd: %{public}d", watchEntity->data_->wd); - FileWatcher::GetInstance()->GetNotifyEvent(watchEntity->data_, WatcherCallback); + FileWatcher::GetInstance()->GetNotifyEvent(WatcherCallback); return NError(ERRNO_NOERR); }; diff --git a/interfaces/kits/js/src/mod_fs/properties/watcher.cpp b/interfaces/kits/js/src/mod_fs/properties/watcher.cpp index fd955f99c..d18da71d6 100644 --- a/interfaces/kits/js/src/mod_fs/properties/watcher.cpp +++ b/interfaces/kits/js/src/mod_fs/properties/watcher.cpp @@ -39,7 +39,7 @@ namespace { } } -static tuple CreateAndCheckForWatcherEntity(napi_env env, int& fd) +static tuple CreateAndCheckForWatcherEntity(napi_env env, int &fd) { if (FileWatcher::GetInstance()->GetNotifyId() < 0 && !FileWatcher::GetInstance()->InitNotify()) { return {nullptr, NError(errno)}; -- Gitee