1// StatCacheServerImpl.h 2 3#ifndef STAT_CACHE_SERVER_IMPL_H 4#define STAT_CACHE_SERVER_IMPL_H 5 6#include <hash_map> 7#include <string> 8 9#include <Entry.h> 10#include <MessageQueue.h> 11#include <Node.h> 12#include <OS.h> 13 14class Directory; 15class Entry; 16class Node; 17class SymLink; 18 19// NodeRefHash 20struct NodeRefHash 21{ 22 size_t operator()(const node_ref &nodeRef) const; 23}; 24 25// EntryRefHash 26struct EntryRefHash 27{ 28 size_t operator()(const entry_ref &entryRef) const; 29}; 30 31// Referencable 32class Referencable { 33public: 34 Referencable() 35 : fReferenceCount(1), 36 fReferenceBaseCount(0) 37 { 38 } 39 40 virtual ~Referencable() 41 { 42 } 43 44 void AddReference() 45 { 46 fReferenceCount++; 47 } 48 49 bool RemoveReference() 50 { 51 if (--fReferenceCount <= fReferenceBaseCount) { 52 Unreferenced(); 53 return true; 54 } 55 return false; 56 } 57 58 int32 CountReferences() const 59 { 60 return fReferenceCount; 61 } 62 63protected: 64 virtual void Unreferenced() {}; 65 66protected: 67 int32 fReferenceCount; 68 int32 fReferenceBaseCount; 69 bool fDeleteWhenUnreferenced; 70}; 71 72// Entry 73class Entry : public Referencable { 74public: 75 Entry(); 76 ~Entry(); 77 78 status_t SetTo(Directory *parent, const char *name); 79 80 Directory *GetParent() const; 81 82 const char *GetName() const; 83 84 void SetNode(Node *node); 85 Node *GetNode() const; 86 87 void SetPrevious(Entry *entry); 88 Entry *GetPrevious() const; 89 void SetNext(Entry *entry); 90 Entry *GetNext() const; 91 92 entry_ref GetEntryRef() const; 93 status_t GetPath(string& path); 94 95protected: 96 virtual void Unreferenced(); 97 98private: 99 Directory *fParent; 100 string fName; 101 Node *fNode; 102 Entry *fPrevious; 103 Entry *fNext; 104}; 105 106// Node 107class Node : public Referencable { 108public: 109 Node(const struct stat &st); 110 virtual ~Node(); 111 112 virtual status_t SetTo(Entry *entry); 113 114 status_t GetPath(string& path); 115 116 const struct stat &GetStat() const; 117 status_t GetStat(struct stat *st); 118 status_t UpdateStat(); 119 void MarkStatInvalid(); 120 121 void SetEntry(Entry *entry); 122 Entry *GetEntry() const; 123 124 node_ref GetNodeRef() const; 125 126protected: 127 virtual void Unreferenced(); 128 129protected: 130 Entry *fEntry; 131 struct stat fStat; 132 bool fStatValid; 133}; 134 135// Directory 136class Directory : public Node { 137public: 138 Directory(const struct stat &st); 139 ~Directory(); 140 141 virtual status_t SetTo(Entry *entry); 142 143 status_t FindEntry(const char *name, Entry **entry); 144 Entry *GetFirstEntry() const; 145 Entry *GetNextEntry(Entry *entry) const; 146 147 status_t ReadAllEntries(); 148 149 bool IsComplete() const; 150 151 void AddEntry(Entry *entry); 152 void RemoveEntry(Entry *entry); 153 154private: 155 Entry *fFirstEntry; 156 Entry *fLastEntry; 157 bool fIsComplete; 158}; 159 160// SymLink 161class SymLink : public Node { 162public: 163 SymLink(const struct stat &st); 164 ~SymLink(); 165 166 virtual status_t SetTo(Entry *entry); 167 168 const char *GetTarget() const; 169 170private: 171 string fTarget; 172}; 173 174// NodeMonitor 175class NodeMonitor : public BLooper { 176public: 177 NodeMonitor(); 178 virtual ~NodeMonitor(); 179 180 status_t Init(); 181 182 virtual void MessageReceived(BMessage *message); 183 184 status_t StartWatching(Node *node); 185 status_t StopWatching(Node *node); 186 187 status_t GetNextMonitoringMessage(BMessage **message); 188 189private: 190 int32 fCurrentNodeMonitorLimit; 191 BMessageQueue fMessageQueue; 192 sem_id fMessageCountSem; 193}; 194 195// PathResolver 196class PathResolver { 197public: 198 PathResolver(); 199 200 status_t FindEntry(const char *path, bool traverse, Entry **_entry); 201 status_t FindEntry(Entry *entry, const char *path, bool traverse, 202 Entry **_entry); 203 status_t FindNode(const char *path, bool traverse, Node **node); 204 205 status_t ResolveSymlink(Node *node, Node **_node); 206 status_t ResolveSymlink(Node *node, Entry **entry); 207 status_t ResolveSymlink(Entry *entry, Entry **_entry); 208 209private: 210 int32 fSymLinkCounter; 211}; 212 213// NodeManager 214class NodeManager : public BLocker { 215public: 216 NodeManager(); 217 ~NodeManager(); 218 219 static NodeManager *GetDefault(); 220 221 status_t Init(); 222 223 Directory *GetRootDirectory() const; 224 225 Node *GetNode(const node_ref &nodeRef); 226 Entry *GetEntry(const entry_ref &entryRef); 227 228 status_t CreateEntry(const entry_ref &entryRef, const node_ref *nodeRef, 229 Entry **_entry); 230 status_t CreateDirectory(const node_ref &nodeRef, Directory **_dir); 231 232 void RemoveEntry(Entry *entry); 233 void MoveEntry(Entry *entry, const entry_ref &newRef, 234 const node_ref &nodeRef); 235 236 void EntryUnreferenced(Entry *entry); 237 void NodeUnreferenced(Node *node); 238 239 status_t StartWatching(Node *node); 240 status_t StopWatching(Node *node); 241 242private: 243 static int32 _NodeMonitoringProcessorEntry(void *data); 244 int32 _NodeMonitoringProcessor(); 245 246 status_t _CreateNode(Entry *entry, Node **_node); 247 248 void _EntryCreated(BMessage *message); 249 void _EntryRemoved(BMessage *message); 250 void _EntryMoved(BMessage *message); 251 void _StatChanged(BMessage *message); 252 253private: 254 typedef hash_map<entry_ref, Entry*, EntryRefHash> EntryMap; 255 typedef hash_map<node_ref, Node*, NodeRefHash> NodeMap; 256 257 EntryMap fEntries; 258 NodeMap fNodes; 259 Directory *fRootDirectory; 260 NodeMonitor *fNodeMonitor; 261 thread_id fNodeMonitoringProcessor; 262 263 static NodeManager sManager; 264}; 265 266#endif // STAT_CACHE_SERVER_IMPL_H 267