1/*
2 * Copyright 2011, Haiku, Inc. All rights reserved.
3 * Distributed under the terms of the MIT License.
4 *
5 * Authors:
6 *		Clemens Zeidler <haiku@clemens-zeidler.de>
7 */
8#ifndef FILE_MONITOR_H
9#define FILE_MONITOR_H
10
11
12#include <map>
13#include <vector>
14
15#include <Entry.h>
16#include <Node.h>
17
18#include "NodeMonitorHandler.h"
19
20
21struct WatchedFile {
22	entry_ref		entry;
23	node_ref		node;
24	/*! Don't use it as the primary cookie storage. To be set in EntryCreated
25	in EntryViewInterface. */
26	void*			cookie;
27};
28
29
30class NodeRefComp {
31public:
32	bool
33	operator()(const node_ref& a, const node_ref& b) const
34	{
35		return a.node < b.node;
36	}
37};
38
39
40typedef std::map<node_ref, WatchedFile, NodeRefComp> WatchedFileList;
41
42
43class EntryViewInterface {
44public:
45	virtual						~EntryViewInterface() {};
46
47	virtual void				EntryCreated(WatchedFile* file) {};
48	virtual void				EntryRemoved(WatchedFile* file) {};
49	virtual void				EntryMoved(WatchedFile* file) {};
50	virtual void				StatChanged(WatchedFile* file) {};
51	virtual void				AttrChanged(WatchedFile* file) {};
52
53	virtual void				EntriesCleared() {};
54};
55
56
57const uint32 kMsgAddRefs = '&adr';
58const uint32 kMsgCleared = '&clr';
59
60
61typedef std::vector<entry_ref> RefList;
62
63
64class ReadThread;
65
66
67class FileMonitor : public NodeMonitorHandler {
68public:
69								FileMonitor(EntryViewInterface* listener);
70								~FileMonitor();
71
72			void				SetReadThread(ReadThread* readThread);
73
74			void				Reset();
75
76	virtual	void				MessageReceived(BMessage* message);
77
78	virtual void				EntryCreated(const char *name, ino_t directory,
79									dev_t device, ino_t node);
80	virtual void				EntryRemoved(const char *name, ino_t directory,
81									dev_t device, ino_t node);
82	virtual void				EntryMoved(const char *name,
83									const char *fromName, ino_t fromDirectory,
84									ino_t toDirectory, dev_t device,
85									ino_t node, dev_t nodeDevice);
86	virtual void				StatChanged(ino_t node, dev_t device,
87									int32 statFields);
88	virtual void				AttrChanged(ino_t node, dev_t device);
89
90private:
91			WatchedFile*		_FindFile(dev_t device, ino_t node);
92
93			EntryViewInterface*	fListener;
94			WatchedFileList		fWatchedFileList;
95
96			ReadThread*			fReadThread;
97			RefList*			fCurrentReadList;
98			uint32				fCurrentReadIndex;
99};
100
101
102class ReadThread {
103public:
104								ReadThread(FileMonitor* target);
105	virtual						~ReadThread() {}
106
107			status_t			Run();
108			bool				Running();
109			status_t			Wait();
110
111			void				Stop();
112			bool				Stopped();
113
114			RefList*			ReadRefList();
115			void				ReadDone();
116
117protected:
118	virtual	bool				ReadNextEntry(entry_ref& entry) = 0;
119
120			int32				Process();
121
122	friend	int32 ReadThreadFunction(void *data);
123
124			BHandler*			fTarget;
125
126			RefList				fRefList1;
127			RefList				fRefList2;
128			RefList*			fWriteRefList;
129			RefList*			fReadRefList;
130			bool				fReading;
131
132private:
133			void				_SwapLists();
134	inline	void				_PublishEntrys(BMessenger& messenger);
135
136			bool				fStopped;
137			thread_id			fThreadId;
138
139			int16				fNReaded;
140			bool				fRunning;
141};
142
143
144#endif // FILE_MONITOR_H
145