xref: /haiku/src/servers/index/VolumeWatcher.h (revision 1026b0a1a76dc88927bb8175c470f638dc5464ee)
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 
25 
26 class VolumeWatcher;
27 
28 
29 class WatchNameHandler : public NodeMonitorHandler {
30 public:
31 								WatchNameHandler(VolumeWatcher* volumeWatcher);
32 
33 			void				EntryCreated(const char *name, ino_t directory,
34 									dev_t device, ino_t node);
35 			void				EntryRemoved(const char *name, ino_t directory,
36 									dev_t device, ino_t node);
37 			void				EntryMoved(const char *name,
38 									const char *fromName, ino_t from_directory,
39 									ino_t to_directory, dev_t device,
40 									ino_t node, dev_t nodeDevice);
41 			void				StatChanged(ino_t node, dev_t device,
42 									int32 statFields);
43 
44 			void				MessageReceived(BMessage* msg);
45 private:
46 			VolumeWatcher*		fVolumeWatcher;
47 };
48 
49 
50 typedef std::vector<entry_ref> EntryRefVector;
51 
52 
53 class VolumeWatcher;
54 
55 
56 const uint32 kTriggerWork = '&twk';	// what a bad message
57 
58 
59 class VolumeWorker : public AnalyserDispatcher
60 {
61 public:
62 								VolumeWorker(VolumeWatcher* watcher);
63 
64 			void				MessageReceived(BMessage *message);
65 
66 			bool				IsBusy();
67 
68 private:
69 			void				_Work();
70 
71 			void				_SetBusy(bool busy = true);
72 
73 			VolumeWatcher*		fVolumeWatcher;
74 			vint32				fBusy;
75 };
76 
77 
78 class VolumeWatcherBase {
79 public:
80 								VolumeWatcherBase(const BVolume& volume);
81 
82 			const BVolume&		Volume() { return fVolume; }
83 
84 			bool				Enabled() { return fEnabled; }
85 			bigtime_t			GetLastUpdated() { return fLastUpdated; }
86 
87 protected:
88 			bool				ReadSettings();
89 			bool				WriteSettings();
90 
91 			BVolume				fVolume;
92 
93 			bool				fEnabled;
94 
95 			bigtime_t			fLastUpdated;
96 };
97 
98 
99 /*! Used to thread safe exchange refs. While the watcher thread file the current
100 list the worker thread can handle the second list. The worker thread gets his entries by calling SwapList while holding the watcher thread lock. */
101 class SwapEntryRefVector {
102 public:
103 								SwapEntryRefVector();
104 
105 			EntryRefVector*		SwapList();
106 			EntryRefVector*		CurrentList();
107 private:
108 			EntryRefVector		fFirstList;
109 			EntryRefVector		fSecondList;
110 			EntryRefVector*		fCurrentList;
111 			EntryRefVector*		fNextList;
112 };
113 
114 
115 struct list_collection
116 {
117 			EntryRefVector*		createdList;
118 			EntryRefVector*		deletedList;
119 			EntryRefVector*		modifiedList;
120 			EntryRefVector*		movedList;
121 			EntryRefVector*		movedFromList;
122 };
123 
124 
125 /*! Watch a volume and delegate changed entries to a VolumeWorker. */
126 class VolumeWatcher : public VolumeWatcherBase, public BLooper {
127 public:
128 								VolumeWatcher(const BVolume& volume);
129 								~VolumeWatcher();
130 
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 };
161 
162 
163 #endif
164