* Added more tracing facilities (Function enter/exit printer)

* Decreased the node monitor activity timeout to 150 ms
* _StartNodeMonitoring() simply starts watching the root folder with the
  B_WATCH_RECURSIVELY flag set. (Requires forthcomming changes to
  BPathMonitor, but it was broken anyways.)
* _StopNodeMonitoring() returns early if node monitoring is inactive.
* When node monitoring is started after a search finished, it is done
  asynchronous, since messing with the other controls results in modification
  messages that otherwise stop node monitoring again. Now the message is
  inserted last and works reliably.
* When receiving B_PATH_MONITOR messages, they are supposed to simply contain
  a "path" field with the full path to the node that changed. That's not
  currently the case with BPathMonitor, but I will commit that stuff next.
  (Was broken before anyways.)


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@26935 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Stephan Aßmus
2008-08-11 19:08:12 +00:00
parent b815b7edc6
commit 545bce00c6
2 changed files with 72 additions and 37 deletions
+71 -37
View File
@@ -48,15 +48,36 @@
using std::nothrow; using std::nothrow;
static const bigtime_t kChangesPulseInterval = 500000; static const bigtime_t kChangesPulseInterval = 150000;
#define TRACE_NODE_MONITORING //#define TRACE_NODE_MONITORING
#ifdef TRACE_NODE_MONITORING #ifdef TRACE_NODE_MONITORING
# define TRACE_NM(x...) printf(x) # define TRACE_NM(x...) printf(x)
#else #else
# define TRACE_NM(x...) # define TRACE_NM(x...)
#endif #endif
//#define TRACE_FUNCTIONS
#ifdef TRACE_FUNCTIONS
class FunctionTracer {
public:
FunctionTracer(const char* functionName)
: fName(functionName)
{
printf("%s - enter\n", fName.String());
}
~FunctionTracer()
{
printf("%s - exit\n", fName.String());
}
private:
BString fName;
};
# define CALLED() FunctionTracer functionTracer(__PRETTY_FUNCTION__)
#else
# define CALLED()
#endif // TRACE_FUNCTIONS
GrepWindow::GrepWindow(BMessage* message) GrepWindow::GrepWindow(BMessage* message)
: BWindow(BRect(0, 0, 1, 1), NULL, B_DOCUMENT_WINDOW, 0), : BWindow(BRect(0, 0, 1, 1), NULL, B_DOCUMENT_WINDOW, 0),
@@ -234,6 +255,10 @@ void GrepWindow::MessageReceived(BMessage *message)
_OnSearchFinished(); _OnSearchFinished();
break; break;
case MSG_START_NODE_MONITORING:
_StartNodeMonitoring();
break;
case B_PATH_MONITOR: case B_PATH_MONITOR:
_OnNodeMonitorEvent(message); _OnNodeMonitorEvent(message);
break; break;
@@ -314,6 +339,8 @@ void GrepWindow::MessageReceived(BMessage *message)
void void
GrepWindow::Quit() GrepWindow::Quit()
{ {
CALLED();
_StopNodeMonitoring(); _StopNodeMonitoring();
_SavePrefs(); _SavePrefs();
@@ -689,37 +716,21 @@ GrepWindow::_SavePrefs()
void void
GrepWindow::_StartNodeMonitoring() GrepWindow::_StartNodeMonitoring()
{ {
CALLED();
_StopNodeMonitoring(); _StopNodeMonitoring();
BMessenger messenger(this); BMessenger messenger(this);
uint32 fileFlags = B_WATCH_NAME | B_WATCH_STAT; uint32 fileFlags = B_WATCH_NAME | B_WATCH_STAT | B_WATCH_ATTR;
uint32 dirFlags = B_WATCH_DIRECTORY | B_WATCH_NAME;
// watch the top level folder
// watch the top level folder only, rest should be done through filtering
// the node monitor notifications
BPath path(&fModel->fDirectory); BPath path(&fModel->fDirectory);
if (path.InitCheck() == B_OK) { if (path.InitCheck() == B_OK) {
TRACE_NM("start monitoring root folder: %s\n", path.Path()); TRACE_NM("start monitoring root folder: %s\n", path.Path());
BPrivate::BPathMonitor::StartWatching(path.Path(), dirFlags, messenger); BPrivate::BPathMonitor::StartWatching(path.Path(),
} fileFlags | B_WATCH_RECURSIVELY | B_WATCH_FILES_ONLY, messenger);
InitialIterator iterator(fModel);
BEntry entry;
while (iterator.GetTopEntry(entry)) {
path.SetTo(&entry);
if (entry.IsDirectory()) {
// subfolder
if (iterator.FollowSubdir(entry)) {
TRACE_NM("start monitoring folder: %s\n", path.Path());
BPrivate::BPathMonitor::StartWatching(path.Path(),
dirFlags | B_WATCH_RECURSIVELY, messenger);
}
} else {
// regular file
TRACE_NM("start monitoring file: %s\n", path.Path());
BPrivate::BPathMonitor::StartWatching(path.Path(), fileFlags,
messenger);
}
} }
if (fChangesPulse == NULL) { if (fChangesPulse == NULL) {
@@ -733,6 +744,11 @@ GrepWindow::_StartNodeMonitoring()
void void
GrepWindow::_StopNodeMonitoring() GrepWindow::_StopNodeMonitoring()
{ {
if (fChangesPulse == NULL)
return;
CALLED();
BPrivate::BPathMonitor::StopWatching(BMessenger(this)); BPrivate::BPathMonitor::StopWatching(BMessenger(this));
delete fChangesIterator; delete fChangesIterator;
fChangesIterator = NULL; fChangesIterator = NULL;
@@ -747,6 +763,8 @@ GrepWindow::_StopNodeMonitoring()
void void
GrepWindow::_OnStartCancel() GrepWindow::_OnStartCancel()
{ {
CALLED();
_StopNodeMonitoring(); _StopNodeMonitoring();
if (fModel->fState == STATE_IDLE) { if (fModel->fState == STATE_IDLE) {
@@ -815,8 +833,6 @@ GrepWindow::_OnSearchFinished()
{ {
fModel->fState = STATE_IDLE; fModel->fState = STATE_IDLE;
_StartNodeMonitoring();
delete fGrepper; delete fGrepper;
fGrepper = NULL; fGrepper = NULL;
@@ -835,6 +851,8 @@ GrepWindow::_OnSearchFinished()
fSearchText->SetText(fOldPattern.String()); fSearchText->SetText(fOldPattern.String());
fSearchText->TextView()->SelectAll(); fSearchText->TextView()->SelectAll();
fSearchText->SetModificationMessage(new BMessage(MSG_SEARCH_TEXT)); fSearchText->SetModificationMessage(new BMessage(MSG_SEARCH_TEXT));
PostMessage(MSG_START_NODE_MONITORING);
} }
@@ -859,21 +877,19 @@ GrepWindow::_OnNodeMonitorEvent(BMessage* message)
{ {
TRACE_NM("%s\n", opCode == B_ENTRY_CREATED ? "B_ENTRY_CREATED" TRACE_NM("%s\n", opCode == B_ENTRY_CREATED ? "B_ENTRY_CREATED"
: "B_ENTRY_REMOVED"); : "B_ENTRY_REMOVED");
const char* name;
BString path; BString path;
if (message->FindString("path", &path) == B_OK if (message->FindString("path", &path) == B_OK) {
&& message->FindString("name", &name) == B_OK) {
path << '/' << name;
if (opCode == B_ENTRY_CREATED) if (opCode == B_ENTRY_CREATED)
fChangesIterator->EntryAdded(path.String()); fChangesIterator->EntryAdded(path.String());
else else
fChangesIterator->EntryRemoved(path.String()); fChangesIterator->EntryRemoved(path.String());
} else { } else {
#ifdef TRACE_NODE_MONITORING #ifdef TRACE_NODE_MONITORING
printf("B_ENTRY_CREATED/REMOVED - incompatible message:\n"); printf("incompatible message:\n");
message->PrintToStream(); message->PrintToStream();
#endif #endif
} }
TRACE_NM("path: %s\n", path.String());
break; break;
} }
case B_ENTRY_MOVED: case B_ENTRY_MOVED:
@@ -886,17 +902,25 @@ GrepWindow::_OnNodeMonitorEvent(BMessage* message)
// it should be a combined removed/added event. // it should be a combined removed/added event.
break; break;
case B_STAT_CHANGED: case B_STAT_CHANGED:
case B_ATTR_CHANGED:
{ {
TRACE_NM("B_STAT_CHANGED\n"); TRACE_NM("%s\n", opCode == B_STAT_CHANGED ? "B_STAT_CHANGED"
: "B_ATTR_CHANGED");
// For directly watched files, the path will include the
// name. When the event occurs for a file in a watched directory,
// the message will have an extra name field for the respective
// file.
BString path; BString path;
if (message->FindString("path", &path) == B_OK) if (message->FindString("path", &path) == B_OK) {
fChangesIterator->EntryChanged(path.String()); fChangesIterator->EntryChanged(path.String());
else { } else {
#ifdef TRACE_NODE_MONITORING #ifdef TRACE_NODE_MONITORING
printf("incompatible message:\n"); printf("incompatible message:\n");
message->PrintToStream(); message->PrintToStream();
#endif #endif
} }
TRACE_NM("path: %s\n", path.String());
//message->PrintToStream();
break; break;
} }
@@ -912,7 +936,7 @@ GrepWindow::_OnNodeMonitorEvent(BMessage* message)
void void
GrepWindow::_OnNodeMonitorPulse() GrepWindow::_OnNodeMonitorPulse()
{ {
if (fChangesIterator == NULL) if (fChangesIterator == NULL || fChangesIterator->IsEmpty())
return; return;
if (system_time() - fLastNodeMonitorEvent < kChangesPulseInterval) { if (system_time() - fLastNodeMonitorEvent < kChangesPulseInterval) {
@@ -930,6 +954,10 @@ GrepWindow::_OnNodeMonitorPulse()
fOldPattern = fSearchText->Text(); fOldPattern = fSearchText->Text();
#ifdef TRACE_NODE_MONITORING
fChangesIterator->PrintToStream();
#endif
fGrepper = new (nothrow) Grepper(fOldPattern.String(), fModel, fGrepper = new (nothrow) Grepper(fOldPattern.String(), fModel,
this, fChangesIterator); this, fChangesIterator);
if (fGrepper != NULL && fGrepper->IsValid()) { if (fGrepper != NULL && fGrepper->IsValid()) {
@@ -961,6 +989,8 @@ GrepWindow::_OnReportFileName(BMessage* message)
void void
GrepWindow::_OnReportResult(BMessage* message) GrepWindow::_OnReportResult(BMessage* message)
{ {
CALLED();
entry_ref ref; entry_ref ref;
if (message->FindRef("ref", &ref) != B_OK) if (message->FindRef("ref", &ref) != B_OK)
return; return;
@@ -1205,6 +1235,8 @@ GrepWindow::_OnInvokeItem()
void void
GrepWindow::_OnSearchText() GrepWindow::_OnSearchText()
{ {
CALLED();
bool enabled = fSearchText->TextView()->TextLength() != 0; bool enabled = fSearchText->TextView()->TextLength() != 0;
fButton->SetEnabled(enabled); fButton->SetEnabled(enabled);
fSearch->SetEnabled(enabled); fSearch->SetEnabled(enabled);
@@ -1551,6 +1583,8 @@ GrepWindow::_OnNewWindow()
void void
GrepWindow::_ModelChanged() GrepWindow::_ModelChanged()
{ {
CALLED();
_StopNodeMonitoring(); _StopNodeMonitoring();
_SavePrefs(); _SavePrefs();
} }
+1
View File
@@ -49,6 +49,7 @@ enum {
MSG_INVOKE_ITEM, MSG_INVOKE_ITEM,
MSG_SELECT_HISTORY, MSG_SELECT_HISTORY,
MSG_NODE_MONITOR_PULSE, MSG_NODE_MONITOR_PULSE,
MSG_START_NODE_MONITORING,
MSG_REPORT_FILE_NAME, MSG_REPORT_FILE_NAME,
MSG_REPORT_RESULT, MSG_REPORT_RESULT,