// StatCacheServerImpl.h #ifndef STAT_CACHE_SERVER_IMPL_H #define STAT_CACHE_SERVER_IMPL_H #include #include #include #include #include #include class Directory; class Entry; class Node; class SymLink; // NodeRefHash struct NodeRefHash { size_t operator()(const node_ref &nodeRef) const; }; // EntryRefHash struct EntryRefHash { size_t operator()(const entry_ref &entryRef) const; }; // Referencable class Referencable { public: Referencable() : fReferenceCount(1), fReferenceBaseCount(0) { } virtual ~Referencable() { } void AddReference() { fReferenceCount++; } bool RemoveReference() { if (--fReferenceCount <= fReferenceBaseCount) { Unreferenced(); return true; } return false; } int32 CountReferences() const { return fReferenceCount; } protected: virtual void Unreferenced() {}; protected: int32 fReferenceCount; int32 fReferenceBaseCount; bool fDeleteWhenUnreferenced; }; // Entry class Entry : public Referencable { public: Entry(); ~Entry(); status_t SetTo(Directory *parent, const char *name); Directory *GetParent() const; const char *GetName() const; void SetNode(Node *node); Node *GetNode() const; void SetPrevious(Entry *entry); Entry *GetPrevious() const; void SetNext(Entry *entry); Entry *GetNext() const; entry_ref GetEntryRef() const; status_t GetPath(string& path); protected: virtual void Unreferenced(); private: Directory *fParent; string fName; Node *fNode; Entry *fPrevious; Entry *fNext; }; // Node class Node : public Referencable { public: Node(const struct stat &st); virtual ~Node(); virtual status_t SetTo(Entry *entry); status_t GetPath(string& path); const struct stat &GetStat() const; status_t GetStat(struct stat *st); status_t UpdateStat(); void MarkStatInvalid(); void SetEntry(Entry *entry); Entry *GetEntry() const; node_ref GetNodeRef() const; protected: virtual void Unreferenced(); protected: Entry *fEntry; struct stat fStat; bool fStatValid; }; // Directory class Directory : public Node { public: Directory(const struct stat &st); ~Directory(); virtual status_t SetTo(Entry *entry); status_t FindEntry(const char *name, Entry **entry); Entry *GetFirstEntry() const; Entry *GetNextEntry(Entry *entry) const; status_t ReadAllEntries(); bool IsComplete() const; void AddEntry(Entry *entry); void RemoveEntry(Entry *entry); private: Entry *fFirstEntry; Entry *fLastEntry; bool fIsComplete; }; // SymLink class SymLink : public Node { public: SymLink(const struct stat &st); ~SymLink(); virtual status_t SetTo(Entry *entry); const char *GetTarget() const; private: string fTarget; }; // NodeMonitor class NodeMonitor : public BLooper { public: NodeMonitor(); virtual ~NodeMonitor(); status_t Init(); virtual void MessageReceived(BMessage *message); status_t StartWatching(Node *node); status_t StopWatching(Node *node); status_t GetNextMonitoringMessage(BMessage **message); private: int32 fCurrentNodeMonitorLimit; BMessageQueue fMessageQueue; sem_id fMessageCountSem; }; // PathResolver class PathResolver { public: PathResolver(); status_t FindEntry(const char *path, bool traverse, Entry **_entry); status_t FindEntry(Entry *entry, const char *path, bool traverse, Entry **_entry); status_t FindNode(const char *path, bool traverse, Node **node); status_t ResolveSymlink(Node *node, Node **_node); status_t ResolveSymlink(Node *node, Entry **entry); status_t ResolveSymlink(Entry *entry, Entry **_entry); private: int32 fSymLinkCounter; }; // NodeManager class NodeManager : public BLocker { public: NodeManager(); ~NodeManager(); static NodeManager *GetDefault(); status_t Init(); Directory *GetRootDirectory() const; Node *GetNode(const node_ref &nodeRef); Entry *GetEntry(const entry_ref &entryRef); status_t CreateEntry(const entry_ref &entryRef, const node_ref *nodeRef, Entry **_entry); status_t CreateDirectory(const node_ref &nodeRef, Directory **_dir); void RemoveEntry(Entry *entry); void MoveEntry(Entry *entry, const entry_ref &newRef, const node_ref &nodeRef); void EntryUnreferenced(Entry *entry); void NodeUnreferenced(Node *node); status_t StartWatching(Node *node); status_t StopWatching(Node *node); private: static int32 _NodeMonitoringProcessorEntry(void *data); int32 _NodeMonitoringProcessor(); status_t _CreateNode(Entry *entry, Node **_node); void _EntryCreated(BMessage *message); void _EntryRemoved(BMessage *message); void _EntryMoved(BMessage *message); void _StatChanged(BMessage *message); private: typedef hash_map EntryMap; typedef hash_map NodeMap; EntryMap fEntries; NodeMap fNodes; Directory *fRootDirectory; NodeMonitor *fNodeMonitor; thread_id fNodeMonitoringProcessor; static NodeManager sManager; }; #endif // STAT_CACHE_SERVER_IMPL_H