1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
13 | |
14 | |
15 | |
16 | |
17 | |
18 | |
19 | |
20 | |
21 | |
22 | |
23 | |
24 | |
25 | |
26 | |
27 | |
28 | |
29 | |
30 | |
31 | |
32 | |
33 | |
34 | |
35 | |
36 | |
37 | |
38 | |
39 | #include <Debug.h> |
40 | #include <Directory.h> |
41 | #include <Entry.h> |
42 | #include <FindDirectory.h> |
43 | #include <Node.h> |
44 | #include <NodeMonitor.h> |
45 | #include <Path.h> |
46 | |
47 | #include "AutoLock.h" |
48 | #include "IconCache.h" |
49 | #include "NodePreloader.h" |
50 | #include "Thread.h" |
51 | #include "Tracker.h" |
52 | |
53 | |
54 | NodePreloader* |
55 | NodePreloader::InstallNodePreloader(const char* name, BLooper* host) |
56 | { |
57 | NodePreloader* result = new NodePreloader(name); |
| |
58 | { |
59 | AutoLock<BLooper> lock(host); |
60 | if (!lock) |
| |
61 | return NULL__null; |
| 3 | | Within the expansion of the macro 'NULL':
|
a | Potential leak of memory pointed to by 'result' |
|
62 | |
63 | host->AddHandler(result); |
64 | } |
65 | result->Run(); |
66 | |
67 | return result; |
68 | } |
69 | |
70 | |
71 | NodePreloader::NodePreloader(const char* name) |
72 | : |
73 | BHandler(name), |
74 | fModelList(20, true), |
75 | fQuitRequested(false) |
76 | { |
77 | } |
78 | |
79 | |
80 | NodePreloader::~NodePreloader() |
81 | { |
82 | |
83 | fQuitRequested = true; |
84 | fLock.Lock(); |
85 | } |
86 | |
87 | |
88 | void |
89 | NodePreloader::Run() |
90 | { |
91 | fLock.Lock(); |
92 | Thread::Launch(NewMemberFunctionObject(&NodePreloader::Preload, this)); |
93 | } |
94 | |
95 | |
96 | Model* |
97 | NodePreloader::FindModel(node_ref itemNode) const |
98 | { |
99 | for (int32 count = fModelList.CountItems() - 1; count >= 0; count--) { |
100 | Model* model = fModelList.ItemAt(count); |
101 | if (*model->NodeRef() == itemNode) |
102 | return model; |
103 | } |
104 | |
105 | return NULL__null; |
106 | } |
107 | |
108 | |
109 | void |
110 | NodePreloader::MessageReceived(BMessage* message) |
111 | { |
112 | |
113 | |
114 | node_ref itemNode; |
115 | switch (message->what) { |
116 | case B_NODE_MONITOR: |
117 | { |
118 | switch (message->FindInt32("opcode")) { |
119 | case B_ENTRY_REMOVED2: |
120 | { |
121 | AutoLock<Benaphore> locker(fLock); |
122 | message->FindInt32("device", &itemNode.device); |
123 | message->FindInt64("node", &itemNode.node); |
124 | Model* model = FindModel(itemNode); |
125 | if (model == NULL__null) |
126 | break; |
127 | |
128 | |
129 | IconCache::sIconCache->Removing(model); |
130 | fModelList.RemoveItem(model); |
131 | break; |
132 | } |
133 | |
134 | case B_ATTR_CHANGED5: |
135 | case B_STAT_CHANGED4: |
136 | { |
137 | AutoLock<Benaphore> locker(fLock); |
138 | message->FindInt32("device", &itemNode.device); |
139 | message->FindInt64("node", &itemNode.node); |
140 | |
141 | const char* attrName; |
142 | message->FindString("attr", &attrName); |
143 | Model* model = FindModel(itemNode); |
144 | if (model == NULL__null) |
145 | break; |
146 | |
147 | BModelOpener opener(model); |
148 | IconCache::sIconCache->IconChanged(model->ResolveIfLink()); |
149 | |
150 | break; |
151 | } |
152 | } |
153 | break; |
154 | } |
155 | |
156 | default: |
157 | _inherited::MessageReceived(message); |
158 | break; |
159 | } |
160 | } |
161 | |
162 | |
163 | void |
164 | NodePreloader::PreloadOne(const char* dirPath) |
165 | { |
166 | |
167 | BDirectory dir(dirPath); |
168 | if (dir.InitCheck() != B_OK((int)0)) |
169 | return; |
170 | |
171 | node_ref nodeRef; |
172 | dir.GetNodeRef(&nodeRef); |
173 | |
174 | |
175 | TTracker::WatchNode(&nodeRef, B_WATCH_DIRECTORY, this); |
176 | |
177 | dir.Rewind(); |
178 | for (;;) { |
179 | entry_ref ref; |
180 | if (dir.GetNextRef(&ref) != B_OK((int)0)) |
181 | break; |
182 | |
183 | BEntry entry(&ref); |
184 | if (!entry.IsFile()) |
185 | |
186 | continue; |
187 | |
188 | Model* model = new Model(&ref, true); |
189 | if (model->InitCheck() == B_OK((int)0) && model->IconFrom() == kUnknownSource) { |
190 | TTracker::WatchNode(model->NodeRef(), |
191 | B_WATCH_STAT | B_WATCH_ATTR, this); |
192 | IconCache::sIconCache->Preload(model, kNormalIcon, B_MINI_ICON, |
193 | true); |
194 | fModelList.AddItem(model); |
195 | model->CloseNode(); |
196 | } else |
197 | delete model; |
198 | } |
199 | } |
200 | |
201 | |
202 | void |
203 | NodePreloader::Preload() |
204 | { |
205 | for (int32 count = 100; count >= 0; count--) { |
206 | |
207 | |
208 | snooze(100000); |
209 | if (fQuitRequested) { |
210 | fLock.Unlock(); |
211 | return; |
212 | } |
213 | } |
214 | |
215 | BMessenger messenger(kTrackerSignature"application/x-vnd.Be-TRAK"); |
216 | if (!messenger.IsValid()) { |
217 | |
218 | return; |
219 | } |
220 | |
221 | ASSERT(fLock.IsLocked())(!(fLock.IsLocked()) ? _debuggerAssert("/home/haiku/haiku/haiku/src/kits/tracker/NodePreloader.cpp" ,221, "fLock.IsLocked()") : (int)0); |
222 | BPath path; |
223 | if (find_directory(B_BEOS_APPS_DIRECTORY, &path) == B_OK((int)0)) |
224 | PreloadOne(path.Path()); |
225 | |
226 | if (find_directory(B_BEOS_PREFERENCES_DIRECTORY, &path) == B_OK((int)0)) |
227 | PreloadOne(path.Path()); |
228 | |
229 | fLock.Unlock(); |
230 | } |