From 77ca66cdb7b44669fc03e80e084234bee21bfd0e Mon Sep 17 00:00:00 2001 From: Ingo Weinhold Date: Thu, 20 Jun 2013 13:59:22 +0200 Subject: [PATCH] BPathMonitor: make the node watching mechanism configurable Add inner class BWatchingInterface and method SetWatchingInterface(). This abstracts the calls to watch_node() and stop_watching(), thus making it possible to use the path monitor in Tracker. --- headers/private/storage/PathMonitor.h | 32 +++++++++++- src/kits/storage/PathMonitor.cpp | 73 +++++++++++++++++++++++++-- 2 files changed, 99 insertions(+), 6 deletions(-) diff --git a/headers/private/storage/PathMonitor.h b/headers/private/storage/PathMonitor.h index c32e94eebb..777ffd892d 100644 --- a/headers/private/storage/PathMonitor.h +++ b/headers/private/storage/PathMonitor.h @@ -1,5 +1,5 @@ /* - * Copyright 2007-2008, Haiku Inc. All Rights Reserved. + * Copyright 2007-2013, Haiku Inc. All Rights Reserved. * Distributed under the terms of the MIT License. */ #ifndef _PATH_MONITOR_H @@ -18,9 +18,14 @@ #define B_PATH_MONITOR '_PMN' + namespace BPrivate { + class BPathMonitor { +public: + class BWatchingInterface; + public: static status_t StartWatching(const char* path, uint32 flags, BMessenger target); @@ -29,6 +34,10 @@ public: BMessenger target); static status_t StopWatching(BMessenger target); + static void SetWatchingInterface( + BWatchingInterface* watchingInterface); + // pass NULL to reset to default + private: BPathMonitor(); ~BPathMonitor(); @@ -37,6 +46,27 @@ private: static void _Init(); }; + +/*! Base class just delegates to the respective C functions. + */ +class BPathMonitor::BWatchingInterface { +public: + BWatchingInterface(); + virtual ~BWatchingInterface(); + + virtual status_t WatchNode(const node_ref* node, uint32 flags, + const BMessenger& target); + virtual status_t WatchNode(const node_ref* node, uint32 flags, + const BHandler* handler, + const BLooper* looper = NULL); + + virtual status_t StopWatching(const BMessenger& target); + virtual status_t StopWatching(const BHandler* handler, + const BLooper* looper = NULL); +}; + + } // namespace BPrivate + #endif // _PATH_MONITOR_H diff --git a/src/kits/storage/PathMonitor.cpp b/src/kits/storage/PathMonitor.cpp index dfa21376ee..cab06a52da 100644 --- a/src/kits/storage/PathMonitor.cpp +++ b/src/kits/storage/PathMonitor.cpp @@ -147,6 +147,8 @@ static pthread_once_t sInitOnce = PTHREAD_ONCE_INIT; static WatcherMap sWatchers; static BLocker* sLocker = NULL; static BLooper* sLooper = NULL; +static BPathMonitor::BWatchingInterface* sDefaultWatchingInterface = NULL; +static BPathMonitor::BWatchingInterface* sWatchingInterface = NULL; static status_t @@ -248,7 +250,7 @@ void PathHandler::Quit() { if (sLooper->Lock()) { - stop_watching(this); + sWatchingInterface->StopWatching(this); sLooper->RemoveHandler(this); sLooper->Unlock(); } @@ -706,7 +708,7 @@ PathHandler::_AddDirectory(BEntry& entry, bool notify) else flags = B_WATCH_DIRECTORY; - status = watch_node(&directory.node, flags, this); + status = sWatchingInterface->WatchNode(&directory.node, flags, this); if (status != B_OK) return status; @@ -765,7 +767,7 @@ PathHandler::_RemoveDirectory(const node_ref& nodeRef, ino_t directoryNode) if (iterator == fDirectories.end()) return B_ENTRY_NOT_FOUND; - watch_node(&directory.node, B_STOP_WATCHING, this); + sWatchingInterface->WatchNode(&directory.node, B_STOP_WATCHING, this); node_ref directoryRef; directoryRef.device = nodeRef.device; @@ -852,7 +854,8 @@ PathHandler::_AddFile(BEntry& entry, bool notify) if (_HasFile(nodeRef)) return B_OK; - status = watch_node(&nodeRef, (fFlags & WATCH_NODE_FLAG_MASK), this); + status = sWatchingInterface->WatchNode(&nodeRef, + (fFlags & WATCH_NODE_FLAG_MASK), this); if (status != B_OK) return status; @@ -893,7 +896,7 @@ PathHandler::_RemoveFile(const node_ref& nodeRef) if (iterator == fFiles.end()) return B_ENTRY_NOT_FOUND; - watch_node(&nodeRef, B_STOP_WATCHING, this); + sWatchingInterface->WatchNode(&nodeRef, B_STOP_WATCHING, this); fFiles.erase(iterator); return B_OK; } @@ -991,6 +994,13 @@ BPathMonitor::_Init() if (sLocker == NULL) return; + sDefaultWatchingInterface = new(std::nothrow) BWatchingInterface; + if (sDefaultWatchingInterface == NULL) + return; + + if (sWatchingInterface == NULL) + SetWatchingInterface(sDefaultWatchingInterface); + BLooper* looper = new (nothrow) BLooper("PathMonitor looper"); TRACE("Start PathMonitor looper\n"); if (looper == NULL) @@ -1106,4 +1116,57 @@ BPathMonitor::StopWatching(BMessenger target) return B_OK; } + +/*static*/ void +BPathMonitor::SetWatchingInterface(BWatchingInterface* watchingInterface) +{ + sWatchingInterface = watchingInterface != NULL + ? watchingInterface : sDefaultWatchingInterface; +} + + +// #pragma mark - BWatchingInterface + + +BPathMonitor::BWatchingInterface::BWatchingInterface() +{ +} + + +BPathMonitor::BWatchingInterface::~BWatchingInterface() +{ +} + + +status_t +BPathMonitor::BWatchingInterface::WatchNode(const node_ref* node, uint32 flags, + const BMessenger& target) +{ + return watch_node(node, flags, target); +} + + +status_t +BPathMonitor::BWatchingInterface::WatchNode(const node_ref* node, uint32 flags, + const BHandler* handler, const BLooper* looper) +{ + return watch_node(node, flags, handler, looper); +} + + +status_t +BPathMonitor::BWatchingInterface::StopWatching(const BMessenger& target) +{ + return stop_watching(target); +} + + +status_t +BPathMonitor::BWatchingInterface::StopWatching(const BHandler* handler, + const BLooper* looper) +{ + return stop_watching(handler, looper); +} + + } // namespace BPrivate