• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2025 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  * http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 #include "watcher_data_cache.h"
16 
17 #include "filemgmt_libhilog.h"
18 
19 namespace OHOS::FileManagement::ModuleFileIO {
20 
AddWatcherInfo(std::shared_ptr<WatcherInfo> info)21 bool WatcherDataCache::AddWatcherInfo(std::shared_ptr<WatcherInfo> info)
22 {
23     std::lock_guard<std::mutex> lock(cacheMutex_);
24     for (auto &iter : watcherInfoCache_) {
25         if (iter->fileName == info->fileName && iter->events == info->events) {
26             bool isSame = iter->callback->IsStrictEquals(info->callback);
27             if (isSame) {
28                 HILOGE("Failed to add watcher, fileName:%{private}s the callback is same", info->fileName.c_str());
29                 return false;
30             }
31         }
32     }
33     watcherInfoCache_.push_back(info);
34     wdFileNameCache_[info->fileName] = std::make_pair(info->wd, info->events);
35     return true;
36 }
37 
RemoveWatcherInfo(std::shared_ptr<WatcherInfo> info)38 uint32_t WatcherDataCache::RemoveWatcherInfo(std::shared_ptr<WatcherInfo> info)
39 {
40     std::lock_guard<std::mutex> lock(cacheMutex_);
41     auto it = std::find(watcherInfoCache_.begin(), watcherInfoCache_.end(), info);
42     if (it != watcherInfoCache_.end()) {
43         watcherInfoCache_.erase(it);
44     }
45 
46     uint32_t remainingEvents = 0;
47     for (const auto &iter : watcherInfoCache_) {
48         if (iter->fileName == info->fileName && iter->wd > 0) {
49             remainingEvents |= iter->events;
50         }
51     }
52 
53     return remainingEvents;
54 }
55 
RemoveFileWatcher(const std::string & fileName)56 bool WatcherDataCache::RemoveFileWatcher(const std::string &fileName)
57 {
58     std::lock_guard<std::mutex> lock(cacheMutex_);
59 
60     auto iter = wdFileNameCache_.find(fileName);
61     if (iter == wdFileNameCache_.end()) {
62         HILOGE("Failed to find fileName");
63         return false;
64     }
65     wdFileNameCache_.erase(iter);
66 
67     watcherInfoCache_.erase(std::remove_if(watcherInfoCache_.begin(), watcherInfoCache_.end(),
68         [&fileName](const std::shared_ptr<WatcherInfo> &info) {
69             return info->fileName == fileName;
70         }), watcherInfoCache_.end());
71 
72     return true;
73 }
74 
FindWatchedWd(const std::string & fileName,uint32_t event)75 std::tuple<bool, int32_t> WatcherDataCache::FindWatchedWd(const std::string &fileName, uint32_t event)
76 {
77     std::lock_guard<std::mutex> lock(cacheMutex_);
78 
79     int32_t wd = -1;
80     auto iter = wdFileNameCache_.find(fileName);
81     if (iter == wdFileNameCache_.end()) {
82         return { false, wd };
83     }
84 
85     wd = iter->second.first;
86     if ((iter->second.second & event) == event) {
87         return { true, wd };
88     }
89 
90     return { false, wd };
91 }
92 
UpdateWatchedEvents(const std::string & fileName,int32_t wd,uint32_t events)93 bool WatcherDataCache::UpdateWatchedEvents(const std::string &fileName, int32_t wd, uint32_t events)
94 {
95     std::lock_guard<std::mutex> lock(cacheMutex_);
96     auto iter = wdFileNameCache_.find(fileName);
97     if (iter == wdFileNameCache_.end()) {
98         return false;
99     }
100 
101     iter->second = std::make_pair(wd, events);
102     return true;
103 }
104 
CheckIncludeEvent(uint32_t mask,uint32_t event)105 static bool CheckIncludeEvent(uint32_t mask, uint32_t event)
106 {
107     return (mask & event) > 0;
108 }
109 
FindWatcherInfos(int32_t wd,uint32_t eventMask)110 std::tuple<bool, std::string, std::vector<std::shared_ptr<WatcherInfo>>> WatcherDataCache::FindWatcherInfos(
111     int32_t wd, uint32_t eventMask)
112 {
113     std::lock_guard<std::mutex> lock(cacheMutex_);
114     std::string fileName;
115     bool found = false;
116     for (const auto &[key, val] : wdFileNameCache_) {
117         if (val.first == wd) {
118             fileName = key;
119             found = true;
120             break;
121         }
122     }
123 
124     if (!found) {
125         return { false, "", {} };
126     }
127 
128     std::vector<std::shared_ptr<WatcherInfo>> matchedInfos;
129     for (const auto &info : watcherInfoCache_) {
130         uint32_t watchEvent = 0;
131         if ((info->fileName == fileName) && (info->wd > 0)) {
132             watchEvent = info->events;
133         }
134         if (CheckIncludeEvent(eventMask, watchEvent)) {
135             matchedInfos.push_back(info);
136         }
137     }
138     return { !matchedInfos.empty(), fileName, matchedInfos };
139 }
140 
GetFileEvents(const std::string & fileName)141 uint32_t WatcherDataCache::GetFileEvents(const std::string &fileName)
142 {
143     std::lock_guard<std::mutex> lock(cacheMutex_);
144     auto iter = wdFileNameCache_.find(fileName);
145     if (iter == wdFileNameCache_.end()) {
146         return 0;
147     }
148     return iter->second.second;
149 }
150 
HasWatcherInfo() const151 bool WatcherDataCache::HasWatcherInfo() const
152 {
153     std::lock_guard<std::mutex> lock(cacheMutex_);
154     return !watcherInfoCache_.empty();
155 }
156 
ClearCache()157 void WatcherDataCache::ClearCache()
158 {
159     std::lock_guard<std::mutex> lock(cacheMutex_);
160     watcherInfoCache_.clear();
161     wdFileNameCache_.clear();
162 }
163 
164 } // namespace OHOS::FileManagement::ModuleFileIO