* If only files are watched, PathHandler::_AddFile() will now notify the target
when it was called from a notification function. * This means you'll no longer have to watch (and scan) directories when you're interested in new files alone. Maybe this functionality could be used for other cases as well, or be activated only via an additional flag. Opinions? Stippi? :-) * TRACE() no goes to /dev/dprintf by default, added a bit more trace output. * Automatic whitespace cleanup. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@28237 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -28,7 +28,7 @@
|
|||||||
#undef TRACE
|
#undef TRACE
|
||||||
//#define TRACE_PATH_MONITOR
|
//#define TRACE_PATH_MONITOR
|
||||||
#ifdef TRACE_PATH_MONITOR
|
#ifdef TRACE_PATH_MONITOR
|
||||||
# define TRACE(x...) printf(x)
|
# define TRACE(x...) debug_printf(x)
|
||||||
#else
|
#else
|
||||||
# define TRACE(x...) ;
|
# define TRACE(x...) ;
|
||||||
#endif
|
#endif
|
||||||
@@ -51,7 +51,7 @@ struct FileEntry {
|
|||||||
|
|
||||||
#if __GNUC__ > 3
|
#if __GNUC__ > 3
|
||||||
bool operator<(const FileEntry& a, const FileEntry& b);
|
bool operator<(const FileEntry& a, const FileEntry& b);
|
||||||
class FileEntryLess : public binary_function<FileEntry, FileEntry, bool>
|
class FileEntryLess : public binary_function<FileEntry, FileEntry, bool>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
bool operator() (const FileEntry& a, const FileEntry& b) const
|
bool operator() (const FileEntry& a, const FileEntry& b) const
|
||||||
@@ -115,13 +115,13 @@ class PathHandler : public BHandler {
|
|||||||
void _NotifyTarget(BMessage* message) const;
|
void _NotifyTarget(BMessage* message) const;
|
||||||
void _NotifyTarget(BMessage* message, const node_ref& nodeRef) const;
|
void _NotifyTarget(BMessage* message, const node_ref& nodeRef) const;
|
||||||
|
|
||||||
status_t _AddDirectory(BEntry& entry);
|
status_t _AddDirectory(BEntry& entry, bool notify = false);
|
||||||
status_t _AddDirectory(node_ref& nodeRef);
|
status_t _AddDirectory(node_ref& nodeRef, bool notify = false);
|
||||||
status_t _RemoveDirectory(const node_ref& nodeRef, ino_t directoryNode);
|
status_t _RemoveDirectory(const node_ref& nodeRef, ino_t directoryNode);
|
||||||
status_t _RemoveDirectory(BEntry& entry, ino_t directoryNode);
|
status_t _RemoveDirectory(BEntry& entry, ino_t directoryNode);
|
||||||
|
|
||||||
bool _HasFile(const node_ref& nodeRef) const;
|
bool _HasFile(const node_ref& nodeRef) const;
|
||||||
status_t _AddFile(BEntry& entry);
|
status_t _AddFile(BEntry& entry, bool notify = false);
|
||||||
status_t _RemoveFile(const node_ref& nodeRef);
|
status_t _RemoveFile(const node_ref& nodeRef);
|
||||||
status_t _RemoveFile(BEntry& entry);
|
status_t _RemoveFile(BEntry& entry);
|
||||||
|
|
||||||
@@ -206,6 +206,8 @@ PathHandler::PathHandler(const char* path, uint32 flags, BMessenger target,
|
|||||||
if (fStatus < B_OK)
|
if (fStatus < B_OK)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
TRACE("PathHandler: %s\n", path);
|
||||||
|
|
||||||
looper->Lock();
|
looper->Lock();
|
||||||
looper->AddHandler(this);
|
looper->AddHandler(this);
|
||||||
looper->Unlock();
|
looper->Unlock();
|
||||||
@@ -248,18 +250,18 @@ PathHandler::Quit()
|
|||||||
void
|
void
|
||||||
PathHandler::Dump()
|
PathHandler::Dump()
|
||||||
{
|
{
|
||||||
printf("WATCHING DIRECTORIES:\n");
|
TRACE("WATCHING DIRECTORIES:\n");
|
||||||
DirectorySet::iterator i = fDirectories.begin();
|
DirectorySet::iterator i = fDirectories.begin();
|
||||||
for (; i != fDirectories.end(); i++) {
|
for (; i != fDirectories.end(); i++) {
|
||||||
printf(" %ld:%Ld (%s)\n", i->node.device, i->node.node, i->contained
|
TRACE(" %ld:%Ld (%s)\n", i->node.device, i->node.node, i->contained
|
||||||
? "contained" : "-");
|
? "contained" : "-");
|
||||||
}
|
}
|
||||||
|
|
||||||
printf("WATCHING FILES:\n");
|
TRACE("WATCHING FILES:\n");
|
||||||
|
|
||||||
FileSet::iterator j = fFiles.begin();
|
FileSet::iterator j = fFiles.begin();
|
||||||
for (; j != fFiles.end(); j++) {
|
for (; j != fFiles.end(); j++) {
|
||||||
printf(" %ld:%Ld\n", j->ref.device, j->node);
|
TRACE(" %ld:%Ld\n", j->ref.device, j->node);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@@ -359,7 +361,7 @@ PathHandler::_EntryCreated(BMessage* message)
|
|||||||
// a new directory to watch for us
|
// a new directory to watch for us
|
||||||
if (!entryContained && !_CloserToPath(entry)
|
if (!entryContained && !_CloserToPath(entry)
|
||||||
|| parentContained && !_WatchRecursively()
|
|| parentContained && !_WatchRecursively()
|
||||||
|| _AddDirectory(entry) != B_OK
|
|| _AddDirectory(entry, true) != B_OK
|
||||||
|| _WatchFilesOnly())
|
|| _WatchFilesOnly())
|
||||||
notify = parentContained;
|
notify = parentContained;
|
||||||
// NOTE: entry is now toast after _AddDirectory() was called!
|
// NOTE: entry is now toast after _AddDirectory() was called!
|
||||||
@@ -445,13 +447,13 @@ PathHandler::_EntryMoved(BMessage* message)
|
|||||||
// there is a new directory to watch for us
|
// there is a new directory to watch for us
|
||||||
if (entryContained
|
if (entryContained
|
||||||
|| parentContained && !_WatchRecursively()) {
|
|| parentContained && !_WatchRecursively()) {
|
||||||
_AddDirectory(entry);
|
_AddDirectory(entry, true);
|
||||||
// NOTE: entry is toast now!
|
// NOTE: entry is toast now!
|
||||||
} else if (_GetClosest(fPath.Path(), false,
|
} else if (_GetClosest(fPath.Path(), false,
|
||||||
nodeRef) == B_OK) {
|
nodeRef) == B_OK) {
|
||||||
// the new directory might put us even
|
// the new directory might put us even
|
||||||
// closer to the path we are after
|
// closer to the path we are after
|
||||||
_AddDirectory(nodeRef);
|
_AddDirectory(nodeRef, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
wasAdded = true;
|
wasAdded = true;
|
||||||
@@ -619,6 +621,8 @@ PathHandler::_NotifyTarget(BMessage* message, const node_ref& nodeRef) const
|
|||||||
BMessage update(*message);
|
BMessage update(*message);
|
||||||
update.what = B_PATH_MONITOR;
|
update.what = B_PATH_MONITOR;
|
||||||
|
|
||||||
|
TRACE("_NotifyTarget(): node ref %ld.%Ld\n", nodeRef.device, nodeRef.node);
|
||||||
|
|
||||||
WatchedDirectory directory;
|
WatchedDirectory directory;
|
||||||
directory.node = nodeRef;
|
directory.node = nodeRef;
|
||||||
|
|
||||||
@@ -659,7 +663,7 @@ PathHandler::_NotifyTarget(BMessage* message, const node_ref& nodeRef) const
|
|||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
PathHandler::_AddDirectory(BEntry& entry)
|
PathHandler::_AddDirectory(BEntry& entry, bool notify)
|
||||||
{
|
{
|
||||||
WatchedDirectory directory;
|
WatchedDirectory directory;
|
||||||
status_t status = entry.GetNodeRef(&directory.node);
|
status_t status = entry.GetNodeRef(&directory.node);
|
||||||
@@ -669,7 +673,7 @@ PathHandler::_AddDirectory(BEntry& entry)
|
|||||||
#ifdef TRACE_PATH_MONITOR
|
#ifdef TRACE_PATH_MONITOR
|
||||||
{
|
{
|
||||||
BPath path(&entry);
|
BPath path(&entry);
|
||||||
printf(" ADD DIRECTORY %s, %ld:%Ld\n",
|
TRACE(" ADD DIRECTORY %s, %ld:%Ld\n",
|
||||||
path.Path(), directory.node.device, directory.node.node);
|
path.Path(), directory.node.device, directory.node.node);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@@ -703,10 +707,10 @@ PathHandler::_AddDirectory(BEntry& entry)
|
|||||||
while (dir.GetNextEntry(&entry) == B_OK) {
|
while (dir.GetNextEntry(&entry) == B_OK) {
|
||||||
if (entry.IsDirectory()) {
|
if (entry.IsDirectory()) {
|
||||||
// and here is the recursion:
|
// and here is the recursion:
|
||||||
if (_AddDirectory(entry) != B_OK)
|
if (_AddDirectory(entry, notify) != B_OK)
|
||||||
break;
|
break;
|
||||||
} else if (!_WatchFoldersOnly()) {
|
} else if (!_WatchFoldersOnly()) {
|
||||||
if (_AddFile(entry) != B_OK)
|
if (_AddFile(entry, notify) != B_OK)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -724,7 +728,7 @@ PathHandler::_AddDirectory(BEntry& entry)
|
|||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
PathHandler::_AddDirectory(node_ref& nodeRef)
|
PathHandler::_AddDirectory(node_ref& nodeRef, bool notify)
|
||||||
{
|
{
|
||||||
BDirectory directory(&nodeRef);
|
BDirectory directory(&nodeRef);
|
||||||
status_t status = directory.InitCheck();
|
status_t status = directory.InitCheck();
|
||||||
@@ -732,7 +736,7 @@ PathHandler::_AddDirectory(node_ref& nodeRef)
|
|||||||
BEntry entry;
|
BEntry entry;
|
||||||
status = directory.GetEntry(&entry);
|
status = directory.GetEntry(&entry);
|
||||||
if (status == B_OK)
|
if (status == B_OK)
|
||||||
status = _AddDirectory(entry);
|
status = _AddDirectory(entry, notify);
|
||||||
}
|
}
|
||||||
|
|
||||||
return status;
|
return status;
|
||||||
@@ -799,7 +803,7 @@ PathHandler::_HasFile(const node_ref& nodeRef) const
|
|||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
PathHandler::_AddFile(BEntry& entry)
|
PathHandler::_AddFile(BEntry& entry, bool notify)
|
||||||
{
|
{
|
||||||
if ((fFlags & (WATCH_NODE_FLAG_MASK & ~B_WATCH_DIRECTORY)) == 0)
|
if ((fFlags & (WATCH_NODE_FLAG_MASK & ~B_WATCH_DIRECTORY)) == 0)
|
||||||
return B_OK;
|
return B_OK;
|
||||||
@@ -807,7 +811,7 @@ PathHandler::_AddFile(BEntry& entry)
|
|||||||
#ifdef TRACE_PATH_MONITOR
|
#ifdef TRACE_PATH_MONITOR
|
||||||
{
|
{
|
||||||
BPath path(&entry);
|
BPath path(&entry);
|
||||||
printf(" ADD FILE %s\n", path.Path());
|
TRACE(" ADD FILE %s\n", path.Path());
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -816,9 +820,9 @@ PathHandler::_AddFile(BEntry& entry)
|
|||||||
if (status != B_OK)
|
if (status != B_OK)
|
||||||
return status;
|
return status;
|
||||||
|
|
||||||
// check if we are already know this file
|
// check if we already know this file
|
||||||
|
|
||||||
// TODO: It should be possible to ommit this check if we know it
|
// TODO: It should be possible to omit this check if we know it
|
||||||
// can't be the case (for example when adding subfolders recursively,
|
// can't be the case (for example when adding subfolders recursively,
|
||||||
// although in that case, the API user may still have added this file
|
// although in that case, the API user may still have added this file
|
||||||
// independently, so for now, it should be the safest to perform this
|
// independently, so for now, it should be the safest to perform this
|
||||||
@@ -835,6 +839,21 @@ PathHandler::_AddFile(BEntry& entry)
|
|||||||
setEntry.node = nodeRef.node;
|
setEntry.node = nodeRef.node;
|
||||||
|
|
||||||
fFiles.insert(setEntry);
|
fFiles.insert(setEntry);
|
||||||
|
|
||||||
|
if (notify && _WatchFilesOnly()) {
|
||||||
|
// We also notify our target about new files if it's only interested
|
||||||
|
// in files; it won't be notified about new directories, so it cannot
|
||||||
|
// know when to search for them.
|
||||||
|
BMessage update;
|
||||||
|
update.AddInt32("opcode", B_ENTRY_CREATED);
|
||||||
|
update.AddInt32("device", nodeRef.device);
|
||||||
|
update.AddInt64("directory", setEntry.ref.directory);
|
||||||
|
update.AddString("name", setEntry.ref.name);
|
||||||
|
update.AddBool("added", true);
|
||||||
|
|
||||||
|
_NotifyTarget(&update, nodeRef);
|
||||||
|
}
|
||||||
|
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -887,13 +906,14 @@ BPathMonitor::~BPathMonitor()
|
|||||||
BPathMonitor::_InitLockerIfNeeded()
|
BPathMonitor::_InitLockerIfNeeded()
|
||||||
{
|
{
|
||||||
static vint32 lock = 0;
|
static vint32 lock = 0;
|
||||||
|
|
||||||
if (sLocker != NULL)
|
if (sLocker != NULL)
|
||||||
return B_OK;
|
return B_OK;
|
||||||
|
|
||||||
while (sLocker == NULL) {
|
while (sLocker == NULL) {
|
||||||
if (atomic_add(&lock, 1) == 0) {
|
if (atomic_add(&lock, 1) == 0) {
|
||||||
sLocker = new (nothrow) BLocker("path monitor");
|
sLocker = new (nothrow) BLocker("path monitor");
|
||||||
|
TRACE("Create PathMonitor locker\n");
|
||||||
if (sLocker == NULL)
|
if (sLocker == NULL)
|
||||||
return B_NO_MEMORY;
|
return B_NO_MEMORY;
|
||||||
}
|
}
|
||||||
@@ -908,7 +928,7 @@ BPathMonitor::_InitLockerIfNeeded()
|
|||||||
BPathMonitor::_InitLooperIfNeeded()
|
BPathMonitor::_InitLooperIfNeeded()
|
||||||
{
|
{
|
||||||
static vint32 lock = 0;
|
static vint32 lock = 0;
|
||||||
|
|
||||||
if (sLooper != NULL)
|
if (sLooper != NULL)
|
||||||
return B_OK;
|
return B_OK;
|
||||||
|
|
||||||
@@ -916,6 +936,7 @@ BPathMonitor::_InitLooperIfNeeded()
|
|||||||
if (atomic_add(&lock, 1) == 0) {
|
if (atomic_add(&lock, 1) == 0) {
|
||||||
// first thread initializes the global looper
|
// first thread initializes the global looper
|
||||||
sLooper = new (nothrow) BLooper("PathMonitor looper");
|
sLooper = new (nothrow) BLooper("PathMonitor looper");
|
||||||
|
TRACE("Start PathMonitor looper\n");
|
||||||
if (sLooper == NULL)
|
if (sLooper == NULL)
|
||||||
return B_NO_MEMORY;
|
return B_NO_MEMORY;
|
||||||
thread_id thread = sLooper->Run();
|
thread_id thread = sLooper->Run();
|
||||||
@@ -932,6 +953,8 @@ BPathMonitor::_InitLooperIfNeeded()
|
|||||||
/*static*/ status_t
|
/*static*/ status_t
|
||||||
BPathMonitor::StartWatching(const char* path, uint32 flags, BMessenger target)
|
BPathMonitor::StartWatching(const char* path, uint32 flags, BMessenger target)
|
||||||
{
|
{
|
||||||
|
TRACE("StartWatching(%s)\n", path);
|
||||||
|
|
||||||
status_t status = _InitLockerIfNeeded();
|
status_t status = _InitLockerIfNeeded();
|
||||||
if (status != B_OK)
|
if (status != B_OK)
|
||||||
return status;
|
return status;
|
||||||
@@ -974,6 +997,8 @@ BPathMonitor::StopWatching(const char* path, BMessenger target)
|
|||||||
if (sLocker == NULL)
|
if (sLocker == NULL)
|
||||||
return B_NO_INIT;
|
return B_NO_INIT;
|
||||||
|
|
||||||
|
TRACE("StopWatching(%s)\n", path);
|
||||||
|
|
||||||
BAutolock _(sLocker);
|
BAutolock _(sLocker);
|
||||||
|
|
||||||
WatcherMap::iterator iterator = sWatchers.find(target);
|
WatcherMap::iterator iterator = sWatchers.find(target);
|
||||||
|
|||||||
Reference in New Issue
Block a user