Author: czeidler Date: 2010-10-28 23:21:40 +0200 (Thu, 28 Oct 2010) New Revision: 39177 Changeset: http://dev.haiku-os.org/changeset/39177 Added: haiku/trunk/src/servers/index/ haiku/trunk/src/servers/index/AnalyserDispatcher.h haiku/trunk/src/servers/index/CatchUpManager.cpp haiku/trunk/src/servers/index/CatchUpManager.h haiku/trunk/src/servers/index/IndexServer.cpp haiku/trunk/src/servers/index/IndexServer.h haiku/trunk/src/servers/index/Jamfile haiku/trunk/src/servers/index/ModifiedNotifications.cpp haiku/trunk/src/servers/index/ModifiedNotifications.h haiku/trunk/src/servers/index/VolumeWatcher.cpp haiku/trunk/src/servers/index/VolumeWatcher.h haiku/trunk/src/servers/index/index_server.rdef haiku/trunk/src/servers/index/main.cpp Removed: haiku/trunk/src/servers/index_server/ Modified: haiku/trunk/src/servers/Jamfile Log: Rename index_server to index as pointed out by Philippe. Modified: haiku/trunk/src/servers/Jamfile =================================================================== --- haiku/trunk/src/servers/Jamfile 2010-10-28 20:57:11 UTC (rev 39176) +++ haiku/trunk/src/servers/Jamfile 2010-10-28 21:21:40 UTC (rev 39177) @@ -4,7 +4,7 @@ SubInclude HAIKU_TOP src servers bluetooth ; SubInclude HAIKU_TOP src servers cddb_daemon ; SubInclude HAIKU_TOP src servers debug ; -SubInclude HAIKU_TOP src servers index_server ; +SubInclude HAIKU_TOP src servers index ; SubInclude HAIKU_TOP src servers input ; SubInclude HAIKU_TOP src servers mail ; SubInclude HAIKU_TOP src servers media ; Added: haiku/trunk/src/servers/index/AnalyserDispatcher.h =================================================================== --- haiku/trunk/src/servers/index/AnalyserDispatcher.h (rev 0) +++ haiku/trunk/src/servers/index/AnalyserDispatcher.h 2010-10-28 21:21:40 UTC (rev 39177) @@ -0,0 +1,55 @@ +/* + * Copyright 2010, Haiku. + * Distributed under the terms of the MIT License. + * + * Authors: + * Clemens Zeidler <haiku@xxxxxxxxxxxxxxxxxx> + */ +#ifndef ANALYSER_DISPATCHER +#define ANALYSER_DISPATCHER + + +#include <Looper.h> +#include <String.h> + +#include "IndexServerAddOn.h" + + +class FileAnalyser; + + +class AnalyserDispatcher : public BLooper { +public: + AnalyserDispatcher(const char* name); + ~AnalyserDispatcher(); + + void Stop(); + bool Stopped(); + + bool Busy(); + + void AnalyseEntry(const entry_ref& ref); + void DeleteEntry(const entry_ref& ref); + void MoveEntry(const entry_ref& oldRef, + const entry_ref& newRef); + void LastEntry(); + + //! thread safe + bool AddAnalyser(FileAnalyser* analyser); + bool RemoveAnalyser(const BString& name); + + void WriteAnalyserSettings(); + void SetSyncPosition(bigtime_t time); + void SetWatchingStart(bigtime_t time); + void SetWatchingPosition(bigtime_t time); + +protected: + FileAnalyserList fFileAnalyserList; + +private: + FileAnalyser* _FindAnalyser(const BString& name); + + vint32 fStopped; +}; + +#endif // ANALYSER_DISPATCHER Added: haiku/trunk/src/servers/index/CatchUpManager.cpp =================================================================== --- haiku/trunk/src/servers/index/CatchUpManager.cpp (rev 0) +++ haiku/trunk/src/servers/index/CatchUpManager.cpp 2010-10-28 21:21:40 UTC (rev 39177) @@ -0,0 +1,253 @@ +/* + * Copyright 2010, Haiku. + * Distributed under the terms of the MIT License. + * + * Authors: + * Clemens Zeidler <haiku@xxxxxxxxxxxxxxxxxx> + */ + +#include "CatchUpManager.h" + +#include <vector> + +#include <Debug.h> +#include <Query.h> + +#include "IndexServer.h" + + +const uint32 kCatchUp = '&CaU'; +const uint32 kCatchUpDone = '&CUD'; + +const bigtime_t kSecond = 1000000; + + +CatchUpAnalyser::CatchUpAnalyser(const BVolume& volume, time_t start, + time_t end, BHandler* manager) + : + AnalyserDispatcher("CatchUpAnalyser"), + + fVolume(volume), + fStart(start), + fEnd(end), + fCatchUpManager(manager) +{ + +} + + +void +CatchUpAnalyser::MessageReceived(BMessage *message) +{ + switch (message->what) { + case kCatchUp: + _CatchUp(); + break; + + default: + BLooper::MessageReceived(message); + } +} + + +void +CatchUpAnalyser::StartAnalysing() +{ + PostMessage(kCatchUp); + Run(); +} + + +void +CatchUpAnalyser::AnalyseEntry(const entry_ref& ref) +{ + for (int i = 0; i < fFileAnalyserList.CountItems(); i++) { + FileAnalyser* analyser = fFileAnalyserList.ItemAt(i); + const analyser_settings& settings = analyser->CachedSettings(); + if (settings.syncPosition / kSecond >= fStart + && settings.watchingStart / kSecond <= fEnd) + analyser->AnalyseEntry(ref); + } +} + + +void +CatchUpAnalyser::_CatchUp() +{ + STRACE("_CatchUp start %i, end %i\n", (int)fStart, (int)fEnd); + for (int i = 0; i < fFileAnalyserList.CountItems(); i++) + STRACE("- Analyser %s\n", fFileAnalyserList.ItemAt(i)->Name().String()); + + BQuery query; + query.SetVolume(&fVolume); + query.PushAttr("last_modified"); + query.PushInt32(fStart); + query.PushOp(B_GE); + query.PushAttr("last_modified"); + query.PushInt32(fEnd); + query.PushOp(B_LE); + query.PushOp(B_AND); + + query.Fetch(); + + std::vector<entry_ref> entryList; + entry_ref ref; + while (query.GetNextRef(&ref) == B_OK) + entryList.push_back(ref); + + printf("CatchUpAnalyser:: entryList.size() %i\n", (int)entryList.size()); + + if (entryList.size() == 0) + return; + + for (uint32 i = 0; i < entryList.size(); i++) { + if (Stopped()) + return; + if (i % 100 == 0) + printf("Catch up: %i/%i\n", (int)i,(int)entryList.size()); + AnalyseEntry(entryList[i]); + } + LastEntry(); + + _WriteSyncSatus(fEnd * kSecond); + printf("Catched up.\n"); + + BMessenger managerMessenger(fCatchUpManager); + BMessage msg(kCatchUpDone); + msg.AddPointer("Analyser", this); + managerMessenger.SendMessage(&msg); +} + + +void +CatchUpAnalyser::_WriteSyncSatus(bigtime_t syncTime) +{ + for (int i = 0; i < fFileAnalyserList.CountItems(); i++) { + AnalyserSettings* settings = fFileAnalyserList.ItemAt(i)->Settings(); + ASSERT(settings); + settings->SetSyncPosition(syncTime); + settings->WriteSettings(); + } + +} + + +CatchUpManager::CatchUpManager(const BVolume& volume) + : + fVolume(volume) +{ + +} + + +CatchUpManager::~CatchUpManager() +{ + Stop(); + + for (int i = 0; i < fFileAnalyserQueue.CountItems(); i++) + delete fFileAnalyserQueue.ItemAt(i); +} + + +void +CatchUpManager::MessageReceived(BMessage *message) +{ + CatchUpAnalyser* analyser; + switch (message->what) { + case kCatchUpDone: + message->AddPointer("Analyser", &analyser); + fCatchUpAnalyserList.RemoveItem(analyser); + analyser->PostMessage(B_QUIT_REQUESTED); + break; + + default: + BHandler::MessageReceived(message); + } +} + + +bool +CatchUpManager::AddAnalyser(const FileAnalyser* analyserOrg) +{ + IndexServer* server = (IndexServer*)be_app; + FileAnalyser* analyser = server->CreateFileAnalyser(analyserOrg->Name(), + fVolume); + if (!analyser) + return false; + ASSERT(analyserOrg->Settings()); + analyser->SetSettings(analyserOrg->Settings()); + + bool status = fFileAnalyserQueue.AddItem(analyser); + if (!status) + delete analyser; + return status; +} + + +void +CatchUpManager::RemoveAnalyser(const BString& name) +{ + for (int i = 0; i < fFileAnalyserQueue.CountItems(); i++) { + FileAnalyser* analyser = fFileAnalyserQueue.ItemAt(i); + if (analyser->Name() == name) { + fFileAnalyserQueue.RemoveItem(analyser); + delete analyser; + } + } + + for (int i = 0; i < fCatchUpAnalyserList.CountItems(); i++) + fCatchUpAnalyserList.ItemAt(i)->RemoveAnalyser(name); +} + + +bool +CatchUpManager::CatchUp() +{ + STRACE("CatchUpManager::CatchUp()\n"); + bigtime_t startBig = real_time_clock_usecs(); + bigtime_t endBig = 0; + for (int i = 0; i < fFileAnalyserQueue.CountItems(); i++) { + FileAnalyser* analyser = fFileAnalyserQueue.ItemAt(i); + analyser->UpdateSettingsCache(); + const analyser_settings& settings = analyser->CachedSettings(); + STRACE("%s, %i, %i\n", analyser->Name().String(), + (int)settings.syncPosition, (int)settings.watchingStart); + if (settings.syncPosition < startBig) + startBig = settings.syncPosition; + if (settings.watchingStart > endBig) + endBig = settings.watchingStart; + } + + CatchUpAnalyser* catchUpAnalyser = new CatchUpAnalyser(fVolume, + startBig / kSecond, endBig / kSecond, this); + if (!catchUpAnalyser) + return false; + if (!fCatchUpAnalyserList.AddItem(catchUpAnalyser)) { + delete catchUpAnalyser; + return false; + } + + for (int i = 0; i < fFileAnalyserQueue.CountItems(); i++) { + FileAnalyser* analyser = fFileAnalyserQueue.ItemAt(i); + // if AddAnalyser fails at least don't leak + if (!catchUpAnalyser->AddAnalyser(analyser)) + delete analyser; + + } + fFileAnalyserQueue.MakeEmpty(); + + catchUpAnalyser->StartAnalysing(); + return true; +} + + +void +CatchUpManager::Stop() +{ + for (int i = 0; i < fCatchUpAnalyserList.CountItems(); i++) { + CatchUpAnalyser* catchUpAnalyser = fCatchUpAnalyserList.ItemAt(i); + catchUpAnalyser->Stop(); + catchUpAnalyser->PostMessage(B_QUIT_REQUESTED); + } + fCatchUpAnalyserList.MakeEmpty(); +} Added: haiku/trunk/src/servers/index/CatchUpManager.h =================================================================== --- haiku/trunk/src/servers/index/CatchUpManager.h (rev 0) +++ haiku/trunk/src/servers/index/CatchUpManager.h 2010-10-28 21:21:40 UTC (rev 39177) @@ -0,0 +1,77 @@ +/* + * Copyright 2010, Haiku. + * Distributed under the terms of the MIT License. + * + * Authors: + * Clemens Zeidler <haiku@xxxxxxxxxxxxxxxxxx> + */ +#ifndef CATCH_UP_MANAGER_H +#define CATCH_UP_MANAGER_H + + +#include "AnalyserDispatcher.h" + + +#define DEBUG_CATCH_UP +#ifdef DEBUG_CATCH_UP +#include <stdio.h> +# define STRACE(x...) printf(x) +#else +# define STRACE(x...) ; +#endif + + +class CatchUpAnalyser : public AnalyserDispatcher { +public: + CatchUpAnalyser(const BVolume& volume, + time_t start, time_t end, + BHandler* manager); + + void MessageReceived(BMessage *message); + void StartAnalysing(); + + void AnalyseEntry(const entry_ref& ref); + + const BVolume& Volume() { return fVolume; } + +private: + void _CatchUp(); + void _WriteSyncSatus(bigtime_t syncTime); + + BVolume fVolume; + time_t fStart; + time_t fEnd; + + BHandler* fCatchUpManager; +}; + + +typedef BObjectList<CatchUpAnalyser> CatchUpAnalyserList; + + +class CatchUpManager : public BHandler { +public: + CatchUpManager(const BVolume& volume); + ~CatchUpManager(); + + void MessageReceived(BMessage *message); + + //! Add analyser to the queue. + bool AddAnalyser(const FileAnalyser* analyser); + void RemoveAnalyser(const BString& name); + + //! Spawn a CatchUpAnalyser and fill it with the analyser in the + //! queue + bool CatchUp(); + //! Stop all catch up threads and put the analyser back into the + //! queue. + void Stop(); + +private: + BVolume fVolume; + + FileAnalyserList fFileAnalyserQueue; + CatchUpAnalyserList fCatchUpAnalyserList; +}; + +#endif Added: haiku/trunk/src/servers/index/IndexServer.cpp =================================================================== --- haiku/trunk/src/servers/index/IndexServer.cpp (rev 0) +++ haiku/trunk/src/servers/index/IndexServer.cpp 2010-10-28 21:21:40 UTC (rev 39177) @@ -0,0 +1,364 @@ +/* + * Copyright 2010, Haiku. + * Distributed under the terms of the MIT License. + * + * Authors: + * Clemens Zeidler <haiku@xxxxxxxxxxxxxxxxxx> + */ + +#include "IndexServer.h" + +#include <Directory.h> +#include <driver_settings.h> +#include <FindDirectory.h> +#include <Path.h> +#include <String.h> + +#include <syscalls.h> + + +VolumeObserverHandler::VolumeObserverHandler(IndexServer* indexServer) + : + fIndexServer(indexServer) +{ + +} + + +void +VolumeObserverHandler::MessageReceived(BMessage* message) +{ + if (message->what != B_NODE_MONITOR) + return; + + dev_t device; + int32 opcode; + message->FindInt32("opcode", &opcode) ; + switch (opcode) { + case B_DEVICE_MOUNTED : + message->FindInt32("new device", &device); + fIndexServer->AddVolume(BVolume(device)); + break ; + + case B_DEVICE_UNMOUNTED : + message->FindInt32("device", &device); + fIndexServer->RemoveVolume(BVolume(device)); + break ; + } +} + + +AnalyserMonitorHandler::AnalyserMonitorHandler(IndexServer* indexServer) + : + fIndexServer(indexServer) +{ + +} + + +void +AnalyserMonitorHandler::AddOnEnabled(const add_on_entry_info* entryInfo) +{ + entry_ref ref; + make_entry_ref(entryInfo->dir_nref.device, entryInfo->dir_nref.node, + entryInfo->name, &ref); + fIndexServer->RegisterAddOn(ref); +}; + + +void +AnalyserMonitorHandler::AddOnDisabled(const add_on_entry_info* entryInfo) +{ + entry_ref ref; + make_entry_ref(entryInfo->dir_nref.device, entryInfo->dir_nref.node, + entryInfo->name, &ref); + fIndexServer->UnregisterAddOn(ref); +}; + + +IndexServer::IndexServer() + : + BApplication("application/x-vnd.Haiku-index_server"), + + fVolumeObserverHandler(this), + fAddOnMonitorHandler(this), + fPulseRunner(NULL) +{ + AddHandler(&fVolumeObserverHandler); + AddHandler(&fAddOnMonitorHandler); +} + + +IndexServer::~IndexServer() +{ + for (int i = 0; i < fAddOnList.CountItems(); i++) { + IndexServerAddOn* addon = fAddOnList.ItemAt(i); + for (int i = 0; i < fVolumeWatcherList.CountItems(); i++) + fVolumeWatcherList.ItemAt(i)->RemoveAnalyser(addon->Name()); + image_id image = addon->ImageId(); + delete addon; + unload_add_on(image); + } + + _StopWatchingVolumes(); + + delete fPulseRunner; + + RemoveHandler(&fVolumeObserverHandler); + RemoveHandler(&fAddOnMonitorHandler); +} + + +void +IndexServer::ReadyToRun() +{ + _StartWatchingAddOns(); + _StartWatchingVolumes(); +} + + +void +IndexServer::MessageReceived(BMessage *message) +{ + BApplication::MessageReceived(message); +} + + +bool +IndexServer::QuitRequested() +{ + _StopWatchingVolumes(); + return BApplication::QuitRequested(); +} + + +void +IndexServer::AddVolume(const BVolume& volume) +{ + // ignore volumes like / or /dev + if (volume.Capacity() == 0) + return; + + // check if volume is already in our list + for (int i = 0; i < fVolumeWatcherList.CountItems(); i++) { + VolumeWatcher* current = fVolumeWatcherList.ItemAt(i); + if (current->Volume() == volume) + return; + } + + char name[256]; + volume.GetName(name); + STRACE("IndexServer::AddVolume %s\n", name); + + VolumeWatcher* watcher = new VolumeWatcher(volume); +/* if (!watcher->Enabled()) { + delete watcher; + return; + }*/ + fVolumeWatcherList.AddItem(watcher); + _SetupVolumeWatcher(watcher); + watcher->StartWatching(); +} + + +void +IndexServer::RemoveVolume(const BVolume& volume) +{ + VolumeWatcher* watcher = NULL; + for (int i = 0; i < fVolumeWatcherList.CountItems(); i++) { + VolumeWatcher* current = fVolumeWatcherList.ItemAt(i); + if (current->Volume() == volume) { + watcher = current; + break; + } + } + + if (!watcher) + return; + + watcher->Stop(); + fVolumeWatcherList.RemoveItem(watcher); + watcher->PostMessage(B_QUIT_REQUESTED); +} + + +void +IndexServer::RegisterAddOn(entry_ref ref) +{ + STRACE("RegisterAddOn %s\n", ref.name); + + BPath path(&ref); + image_id image = load_add_on(path.Path()); + if (image < 0) + return; + + create_index_server_addon* createFunc; + + // Get the instantiation function + status_t status = get_image_symbol(image, "instantiate_index_server_addon", + B_SYMBOL_TYPE_TEXT, (void**)&createFunc); + if (status != B_OK) { + unload_add_on(image); + return; + } + + IndexServerAddOn* addon = createFunc(image, ref.name); + if (!addon) { + unload_add_on(image); + return; + } + if (!fAddOnList.AddItem(addon)) { + unload_add_on(image); + return; + } + + for (int i = 0; i < fVolumeWatcherList.CountItems(); i++) { + VolumeWatcher* watcher = fVolumeWatcherList.ItemAt(i); + FileAnalyser* analyser = _SetupFileAnalyser(addon, watcher->Volume()); + if (!analyser) + continue; + if (!watcher->AddAnalyser(analyser)) + delete analyser; + } + +} + + +void +IndexServer::UnregisterAddOn(entry_ref ref) +{ + IndexServerAddOn* addon = _FindAddon(ref.name); + if (!addon) + return; + + for (int i = 0; i < fVolumeWatcherList.CountItems(); i++) + fVolumeWatcherList.ItemAt(i)->RemoveAnalyser(addon->Name()); + + fAddOnList.RemoveItem(addon); + unload_add_on(addon->ImageId()); + delete addon; +} + + +FileAnalyser* +IndexServer::CreateFileAnalyser(const BString& name, const BVolume& volume) +{ + Lock(); + IndexServerAddOn* addon = _FindAddon(name); + if (!addon) { + Unlock(); + return NULL; + } + FileAnalyser* analyser = addon->CreateFileAnalyser(volume); + Unlock(); + return analyser; +} + + +void +IndexServer::_StartWatchingVolumes() +{ + BVolume volume; + while (fVolumeRoster.GetNextVolume(&volume) != B_BAD_VALUE) + AddVolume(volume); + fVolumeRoster.StartWatching(this); +} + + +void +IndexServer::_StopWatchingVolumes() +{ + STRACE("_StopWatchingVolumes\n"); + + for (int i = 0; i < fVolumeWatcherList.CountItems(); i++) { + VolumeWatcher* watcher = fVolumeWatcherList.ItemAt(i); + watcher->Stop(); + watcher->PostMessage(B_QUIT_REQUESTED); + } + fVolumeWatcherList.MakeEmpty(); +} + + +void +IndexServer::_SetupVolumeWatcher(VolumeWatcher* watcher) +{ + for (int i = 0; i < fAddOnList.CountItems(); i++) { + IndexServerAddOn* addon = fAddOnList.ItemAt(i); + FileAnalyser* analyser = _SetupFileAnalyser(addon, watcher->Volume()); + if (!analyser) + continue; + if (!watcher->AddAnalyser(analyser)) + delete analyser; + } +} + + +FileAnalyser* +IndexServer::_SetupFileAnalyser(IndexServerAddOn* addon, const BVolume& volume) +{ + FileAnalyser* analyser = addon->CreateFileAnalyser(volume); + if (!analyser) + return NULL; + AnalyserSettings* settings = new AnalyserSettings(analyser->Name(), + analyser->Volume()); + BReference<AnalyserSettings> settingsRef(settings, true); + if (!settings) { + delete analyser; + return NULL; + } + analyser->SetSettings(settings); + return analyser; +} + + +void +IndexServer::_StartWatchingAddOns() +{ + AddHandler(&fAddOnMonitorHandler); + BMessage pulse(B_PULSE); + fPulseRunner = new BMessageRunner(&fAddOnMonitorHandler, &pulse, 1000000LL); + // the monitor handler needs a pulse to check if add-ons are ready + + char parameter[32]; + size_t parameterLength = sizeof(parameter); + bool safeMode = false; + if (_kern_get_safemode_option(B_SAFEMODE_SAFE_MODE, parameter, + ¶meterLength) == B_OK) { + if (!strcasecmp(parameter, "enabled") || !strcasecmp(parameter, "on") + || !strcasecmp(parameter, "true") || !strcasecmp(parameter, "yes") + || !strcasecmp(parameter, "enable") || !strcmp(parameter, "1")) + safeMode = true; + } + + // load dormant media nodes + const directory_which directories[] = { + B_USER_ADDONS_DIRECTORY, + B_COMMON_ADDONS_DIRECTORY, + B_BEOS_ADDONS_DIRECTORY + }; + + // when safemode, only B_BEOS_ADDONS_DIRECTORY is used + for (uint32 i = safeMode ? 2 : 0; + i < sizeof(directories) / sizeof(directory_which); i++) { + BDirectory directory; + node_ref nodeRef; + BPath path; + if (find_directory(directories[i], &path) == B_OK + && path.Append("index_server") == B_OK + && directory.SetTo(path.Path()) == B_OK + && directory.GetNodeRef(&nodeRef) == B_OK) + fAddOnMonitorHandler.AddDirectory(&nodeRef, true); + } +} + + +IndexServerAddOn* +IndexServer::_FindAddon(const BString& name) +{ + for (int i = 0; i < fAddOnList.CountItems(); i++) { + IndexServerAddOn* current = fAddOnList.ItemAt(i); + if (current->Name() == name) + return current; + } + return NULL; +} Added: haiku/trunk/src/servers/index/IndexServer.h =================================================================== --- haiku/trunk/src/servers/index/IndexServer.h (rev 0) +++ haiku/trunk/src/servers/index/IndexServer.h 2010-10-28 21:21:40 UTC (rev 39177) @@ -0,0 +1,100 @@ +/* + * Copyright 2010, Haiku. + * Distributed under the terms of the MIT License. + * + * Authors: + * Clemens Zeidler <haiku@xxxxxxxxxxxxxxxxxx> + */ +#ifndef INDEX_SERVER_H +#define INDEX_SERVER_H + + +#include <Application.h> +#include <MessageRunner.h> +#include <VolumeRoster.h> + +#include <AddOnMonitorHandler.h> +#include <ObjectList.h> + +#include "IndexServerAddOn.h" +#include "VolumeWatcher.h" + + +#define DEBUG_INDEX_SERVER +#ifdef DEBUG_INDEX_SERVER +#include <stdio.h> +# define STRACE(x...) printf(x) +#else +# define STRACE(x...) ; +#endif + + +class IndexServer; + + +class VolumeObserverHandler : public BHandler { +public: + VolumeObserverHandler(IndexServer* indexServer); + void MessageReceived(BMessage *message); +private: + IndexServer* fIndexServer; +}; + + +class AnalyserMonitorHandler : public AddOnMonitorHandler { +public: + AnalyserMonitorHandler( + IndexServer* indexServer); + +private: + void AddOnEnabled( + const add_on_entry_info* entryInfo); + void AddOnDisabled( + const add_on_entry_info* entryInfo); + + IndexServer* fIndexServer; +}; + + +class IndexServer : public BApplication { +public: + IndexServer(); + virtual ~IndexServer(); + + virtual void ReadyToRun(); + virtual void MessageReceived(BMessage *message); + + virtual bool QuitRequested(); + + void AddVolume(const BVolume& volume); + void RemoveVolume(const BVolume& volume); + + void RegisterAddOn(entry_ref ref); + void UnregisterAddOn(entry_ref ref); + + //! thread safe + FileAnalyser* CreateFileAnalyser(const BString& name, + const BVolume& volume); +private: + void _StartWatchingVolumes(); + void _StopWatchingVolumes(); + + void _SetupVolumeWatcher(VolumeWatcher* watcher); + FileAnalyser* _SetupFileAnalyser(IndexServerAddOn* addon, + const BVolume& volume); + void _StartWatchingAddOns(); + + inline IndexServerAddOn* _FindAddon(const BString& name); + + BVolumeRoster fVolumeRoster; + BObjectList<VolumeWatcher> fVolumeWatcherList; + BObjectList<IndexServerAddOn> fAddOnList; + + VolumeObserverHandler fVolumeObserverHandler; + + AnalyserMonitorHandler fAddOnMonitorHandler; + BMessageRunner* fPulseRunner; +}; + + +#endif Added: haiku/trunk/src/servers/index/Jamfile =================================================================== --- haiku/trunk/src/servers/index/Jamfile (rev 0) +++ haiku/trunk/src/servers/index/Jamfile 2010-10-28 21:21:40 UTC (rev 39177) @@ -0,0 +1,28 @@ +SubDir HAIKU_TOP src servers index ; + +AddResources index_server : index_server.rdef ; + +UsePrivateHeaders index_server shared storage kernel app ; +UsePrivateSystemHeaders ; + +Server index_server : + CatchUpManager.cpp + main.cpp + IndexServer.cpp + IndexServerAddOn.cpp + ModifiedNotifications.cpp + VolumeWatcher.cpp + + # storage + AddOnMonitorHandler.cpp + NodeMonitorHandler.cpp + : + be + $(TARGET_LIBSTDC++) +; + +SEARCH on [ FGristFiles AddOnMonitorHandler.cpp NodeMonitorHandler.cpp ] + += [ FDirName $(SUBDIR) $(DOTDOT) $(DOTDOT) kits storage ] ; + +SEARCH on [ FGristFiles IndexServerAddOn.cpp ] + += [ FDirName $(SUBDIR) $(DOTDOT) $(DOTDOT) add-ons index_server ] ; Added: haiku/trunk/src/servers/index/ModifiedNotifications.cpp =================================================================== --- haiku/trunk/src/servers/index/ModifiedNotifications.cpp (rev 0) +++ haiku/trunk/src/servers/index/ModifiedNotifications.cpp 2010-10-28 21:21:40 UTC (rev 39177) @@ -0,0 +1,86 @@ +/* + * Copyright 2010, Haiku. + * Distributed under the terms of the MIT License. + * + * Authors: + * Clemens Zeidler <haiku@xxxxxxxxxxxxxxxxxx> + */ + +#include "ModifiedNotifications.h" + +#include "fs_query.h" + +#include <MessengerPrivate.h> +#include <syscalls.h> + +#include "query_private.h" + + +NotifyAllQuery::NotifyAllQuery() + : + fQueryFd(-1) +{ + +} + + +NotifyAllQuery::~NotifyAllQuery() +{ + StopWatching(); +} + + +status_t +NotifyAllQuery::StartWatching(const BVolume& volume, const char* query, + const BMessenger& target) +{ + if (fQueryFd >= 0) + return B_NOT_ALLOWED; + + BMessenger::Private messengerPrivate(const_cast<BMessenger&>(target)); + port_id port = messengerPrivate.Port(); + long token = (messengerPrivate.IsPreferredTarget() ? -1 + : messengerPrivate.Token()); + + fQueryFd = _kern_open_query(volume.Device(), query, strlen(query), + B_LIVE_QUERY | B_ATTR_CHANGE_NOTIFICATION, port, token); + if (fQueryFd < 0) + return fQueryFd; + return B_OK; +} + + +status_t +NotifyAllQuery::StopWatching() +{ + status_t error = B_OK; + if (fQueryFd >= 0) { + error = _kern_close(fQueryFd); + fQueryFd = -1; + } + return error; +} + + +ModfiedNotifications::~ModfiedNotifications() +{ + StopWatching(); +} [... truncated: 856 lines follow ...]