* 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:
@@ -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();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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,
|
||||||
|
|||||||
Reference in New Issue
Block a user