1 /* 2 * Copyright 2010, Haiku. 3 * Distributed under the terms of the MIT License. 4 * 5 * Authors: 6 * Clemens Zeidler <haiku@clemens-zeidler.de> 7 */ 8 #ifndef VOLUME_WATCHER_H 9 #define VOLUME_WATCHER_H 10 11 12 #include <vector> 13 14 #include <Debug.h> 15 #include <Handler.h> 16 #include <NodeMonitorHandler.h> 17 #include <Volume.h> 18 19 #include <ObjectList.h> 20 21 #include "AnalyserDispatcher.h" 22 #include "CatchUpManager.h" 23 #include "IndexServerAddOn.h" 24 #include "ModifiedNotifications.h" 25 26 27 class VolumeWatcher; 28 29 30 class WatchNameHandler : public NodeMonitorHandler { 31 public: 32 WatchNameHandler(VolumeWatcher* volumeWatcher); 33 34 void EntryCreated(const char *name, ino_t directory, 35 dev_t device, ino_t node); 36 void EntryRemoved(const char *name, ino_t directory, 37 dev_t device, ino_t node); 38 void EntryMoved(const char *name, 39 const char *fromName, ino_t from_directory, 40 ino_t to_directory, dev_t device, 41 ino_t node, dev_t nodeDevice); 42 void StatChanged(ino_t node, dev_t device, 43 int32 statFields); 44 private: 45 VolumeWatcher* fVolumeWatcher; 46 }; 47 48 49 typedef std::vector<entry_ref> EntryRefVector; 50 51 52 class VolumeWatcher; 53 54 55 const uint32 kTriggerWork = '&twk'; // what a bad message 56 57 58 class VolumeWorker : public AnalyserDispatcher 59 { 60 public: 61 VolumeWorker(VolumeWatcher* watcher); 62 63 void MessageReceived(BMessage *message); 64 65 bool IsBusy(); 66 67 private: 68 void _Work(); 69 70 void _SetBusy(bool busy = true); 71 72 VolumeWatcher* fVolumeWatcher; 73 vint32 fBusy; 74 }; 75 76 77 class VolumeWatcherBase { 78 public: 79 VolumeWatcherBase(const BVolume& volume); 80 81 const BVolume& Volume() { return fVolume; } 82 83 bool Enabled() { return fEnabled; } 84 bigtime_t GetLastUpdated() { return fLastUpdated; } 85 86 protected: 87 bool ReadSettings(); 88 bool WriteSettings(); 89 90 BVolume fVolume; 91 92 bool fEnabled; 93 94 bigtime_t fLastUpdated; 95 }; 96 97 98 /*! Used to thread safe exchange refs. While the watcher thread file the current 99 list the worker thread can handle the second list. The worker thread gets his entries by calling SwapList while holding the watcher thread lock. */ 100 class SwapEntryRefVector { 101 public: 102 SwapEntryRefVector(); 103 104 EntryRefVector* SwapList(); 105 EntryRefVector* CurrentList(); 106 private: 107 EntryRefVector fFirstList; 108 EntryRefVector fSecondList; 109 EntryRefVector* fCurrentList; 110 EntryRefVector* fNextList; 111 }; 112 113 114 struct list_collection 115 { 116 EntryRefVector* createdList; 117 EntryRefVector* deletedList; 118 EntryRefVector* modifiedList; 119 EntryRefVector* movedList; 120 EntryRefVector* movedFromList; 121 }; 122 123 124 /*! Watch a volume and delegate changed entries to a VolumeWorker. */ 125 class VolumeWatcher : public VolumeWatcherBase, public BLooper { 126 public: 127 VolumeWatcher(const BVolume& volume); 128 ~VolumeWatcher(); 129 130 void MessageReceived(BMessage *message); 131 bool StartWatching(); 132 void Stop(); 133 134 //! thread safe 135 bool AddAnalyser(FileAnalyser* analyser); 136 bool RemoveAnalyser(const BString& name); 137 138 void GetSecureEntries(list_collection& collection); 139 140 bool FindEntryRef(ino_t node, dev_t device, 141 entry_ref& entry); 142 143 private: 144 friend class WatchNameHandler; 145 146 void _NewEntriesArrived(); 147 148 bool fWatching; 149 150 WatchNameHandler fWatchNameHandler; 151 152 SwapEntryRefVector fCreatedList; 153 SwapEntryRefVector fDeleteList; 154 SwapEntryRefVector fModifiedList; 155 SwapEntryRefVector fMovedList; 156 SwapEntryRefVector fMovedFromList; 157 158 VolumeWorker* fVolumeWorker; 159 CatchUpManager fCatchUpManager; 160 ModfiedNotifications fModfiedNotifications; 161 }; 162 163 164 #endif 165