vfs: check userland buffers before reading them.
[haiku.git] / src / servers / index / CatchUpManager.cpp
blob80fb695dffef7edd423e2be7ecf2a141f2b53965
1 /*
2 * Copyright 2010, Haiku.
3 * Distributed under the terms of the MIT License.
5 * Authors:
6 * Clemens Zeidler <haiku@clemens-zeidler.de>
7 */
9 #include "CatchUpManager.h"
11 #include <vector>
13 #include <Debug.h>
14 #include <Query.h>
16 #include "IndexServer.h"
19 const uint32 kCatchUp = '&CaU';
20 const uint32 kCatchUpDone = '&CUD';
22 const bigtime_t kSecond = 1000000;
25 CatchUpAnalyser::CatchUpAnalyser(const BVolume& volume, time_t start,
26 time_t end, BHandler* manager)
28 AnalyserDispatcher("CatchUpAnalyser"),
29 fVolume(volume),
30 fStart(start),
31 fEnd(end),
32 fCatchUpManager(manager)
38 void
39 CatchUpAnalyser::MessageReceived(BMessage *message)
41 switch (message->what) {
42 case kCatchUp:
43 _CatchUp();
44 break;
46 default:
47 BLooper::MessageReceived(message);
52 void
53 CatchUpAnalyser::StartAnalysing()
55 PostMessage(kCatchUp);
56 Run();
60 void
61 CatchUpAnalyser::AnalyseEntry(const entry_ref& ref)
63 for (int i = 0; i < fFileAnalyserList.CountItems(); i++) {
64 FileAnalyser* analyser = fFileAnalyserList.ItemAt(i);
65 const analyser_settings& settings = analyser->CachedSettings();
66 if (settings.syncPosition / kSecond >= fStart
67 && settings.watchingStart / kSecond <= fEnd)
68 analyser->AnalyseEntry(ref);
73 void
74 CatchUpAnalyser::_CatchUp()
76 STRACE("_CatchUp start %i, end %i\n", (int)fStart, (int)fEnd);
77 for (int i = 0; i < fFileAnalyserList.CountItems(); i++)
78 STRACE("- Analyser %s\n", fFileAnalyserList.ItemAt(i)->Name().String());
80 BQuery query;
81 query.SetVolume(&fVolume);
82 query.PushAttr("last_modified");
83 query.PushInt32(fStart);
84 query.PushOp(B_GE);
85 query.PushAttr("last_modified");
86 query.PushInt32(fEnd);
87 query.PushOp(B_LE);
88 query.PushOp(B_AND);
90 query.Fetch();
92 std::vector<entry_ref> entryList;
93 entry_ref ref;
94 while (query.GetNextRef(&ref) == B_OK)
95 entryList.push_back(ref);
97 printf("CatchUpAnalyser:: entryList.size() %i\n", (int)entryList.size());
99 if (entryList.size() == 0)
100 return;
102 for (uint32 i = 0; i < entryList.size(); i++) {
103 if (Stopped())
104 return;
105 if (i % 100 == 0)
106 printf("Catch up: %i/%i\n", (int)i,(int)entryList.size());
107 AnalyseEntry(entryList[i]);
109 LastEntry();
111 _WriteSyncSatus(fEnd * kSecond);
112 printf("Catched up.\n");
114 BMessenger managerMessenger(fCatchUpManager);
115 BMessage msg(kCatchUpDone);
116 msg.AddPointer("Analyser", this);
117 managerMessenger.SendMessage(&msg);
121 void
122 CatchUpAnalyser::_WriteSyncSatus(bigtime_t syncTime)
124 for (int i = 0; i < fFileAnalyserList.CountItems(); i++) {
125 AnalyserSettings* settings = fFileAnalyserList.ItemAt(i)->Settings();
126 ASSERT(settings);
127 settings->SetSyncPosition(syncTime);
128 settings->WriteSettings();
134 CatchUpManager::CatchUpManager(const BVolume& volume)
136 fVolume(volume)
142 CatchUpManager::~CatchUpManager()
144 Stop();
146 for (int i = 0; i < fFileAnalyserQueue.CountItems(); i++)
147 delete fFileAnalyserQueue.ItemAt(i);
151 void
152 CatchUpManager::MessageReceived(BMessage *message)
154 CatchUpAnalyser* analyser;
155 switch (message->what) {
156 case kCatchUpDone:
157 message->AddPointer("Analyser", &analyser);
158 fCatchUpAnalyserList.RemoveItem(analyser);
159 analyser->PostMessage(B_QUIT_REQUESTED);
160 break;
162 default:
163 BHandler::MessageReceived(message);
168 bool
169 CatchUpManager::AddAnalyser(const FileAnalyser* analyserOrg)
171 IndexServer* server = (IndexServer*)be_app;
172 FileAnalyser* analyser = server->CreateFileAnalyser(analyserOrg->Name(),
173 fVolume);
174 if (!analyser)
175 return false;
176 ASSERT(analyserOrg->Settings());
177 analyser->SetSettings(analyserOrg->Settings());
179 bool status = fFileAnalyserQueue.AddItem(analyser);
180 if (!status)
181 delete analyser;
182 return status;
186 void
187 CatchUpManager::RemoveAnalyser(const BString& name)
189 for (int i = 0; i < fFileAnalyserQueue.CountItems(); i++) {
190 FileAnalyser* analyser = fFileAnalyserQueue.ItemAt(i);
191 if (analyser->Name() == name) {
192 fFileAnalyserQueue.RemoveItem(analyser);
193 delete analyser;
197 for (int i = 0; i < fCatchUpAnalyserList.CountItems(); i++)
198 fCatchUpAnalyserList.ItemAt(i)->RemoveAnalyser(name);
202 bool
203 CatchUpManager::CatchUp()
205 STRACE("CatchUpManager::CatchUp()\n");
206 bigtime_t startBig = real_time_clock_usecs();
207 bigtime_t endBig = 0;
208 for (int i = 0; i < fFileAnalyserQueue.CountItems(); i++) {
209 FileAnalyser* analyser = fFileAnalyserQueue.ItemAt(i);
210 analyser->UpdateSettingsCache();
211 const analyser_settings& settings = analyser->CachedSettings();
212 STRACE("%s, %i, %i\n", analyser->Name().String(),
213 (int)settings.syncPosition, (int)settings.watchingStart);
214 if (settings.syncPosition < startBig)
215 startBig = settings.syncPosition;
216 if (settings.watchingStart > endBig)
217 endBig = settings.watchingStart;
220 CatchUpAnalyser* catchUpAnalyser = new CatchUpAnalyser(fVolume,
221 startBig / kSecond, endBig / kSecond, this);
222 if (!catchUpAnalyser)
223 return false;
224 if (!fCatchUpAnalyserList.AddItem(catchUpAnalyser)) {
225 delete catchUpAnalyser;
226 return false;
229 for (int i = 0; i < fFileAnalyserQueue.CountItems(); i++) {
230 FileAnalyser* analyser = fFileAnalyserQueue.ItemAt(i);
231 // if AddAnalyser fails at least don't leak
232 if (!catchUpAnalyser->AddAnalyser(analyser))
233 delete analyser;
236 fFileAnalyserQueue.MakeEmpty();
238 catchUpAnalyser->StartAnalysing();
239 return true;
243 void
244 CatchUpManager::Stop()
246 for (int i = 0; i < fCatchUpAnalyserList.CountItems(); i++) {
247 CatchUpAnalyser* catchUpAnalyser = fCatchUpAnalyserList.ItemAt(i);
248 catchUpAnalyser->Stop();
249 catchUpAnalyser->PostMessage(B_QUIT_REQUESTED);
251 fCatchUpAnalyserList.MakeEmpty();