[haiku-commits] r39177 - in haiku/trunk/src/servers: . index

  • From: clemens.zeidler@xxxxxxxxxxxxxx
  • To: haiku-commits@xxxxxxxxxxxxx
  • Date: Thu, 28 Oct 2010 23:21:41 +0200 (CEST)

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,
+                       &parameterLength) == 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 ...]

Other related posts:

  • » [haiku-commits] r39177 - in haiku/trunk/src/servers: . index - clemens . zeidler