374 lines
16 KiB
Diff
374 lines
16 KiB
Diff
Index: trace_message_filter.cc
|
|
===================================================================
|
|
--- trace_message_filter.cc (revision 247552)
|
|
+++ trace_message_filter.cc (working copy)
|
|
@@ -121,7 +121,7 @@
|
|
if (is_awaiting_end_ack_) {
|
|
is_awaiting_end_ack_ = false;
|
|
TracingControllerImpl::GetInstance()->OnDisableRecordingAcked(
|
|
- known_categories);
|
|
+ this, known_categories);
|
|
} else {
|
|
NOTREACHED();
|
|
}
|
|
@@ -132,7 +132,8 @@
|
|
// but check in case the child process is compromised.
|
|
if (is_awaiting_capture_monitoring_snapshot_ack_) {
|
|
is_awaiting_capture_monitoring_snapshot_ack_ = false;
|
|
- TracingControllerImpl::GetInstance()->OnCaptureMonitoringSnapshotAcked();
|
|
+ TracingControllerImpl::GetInstance()->OnCaptureMonitoringSnapshotAcked(
|
|
+ this);
|
|
} else {
|
|
NOTREACHED();
|
|
}
|
|
@@ -160,7 +161,7 @@
|
|
if (is_awaiting_buffer_percent_full_ack_) {
|
|
is_awaiting_buffer_percent_full_ack_ = false;
|
|
TracingControllerImpl::GetInstance()->OnTraceBufferPercentFullReply(
|
|
- percent_full);
|
|
+ this, percent_full);
|
|
} else {
|
|
NOTREACHED();
|
|
}
|
|
Index: tracing_controller_impl.cc
|
|
===================================================================
|
|
--- tracing_controller_impl.cc (revision 247552)
|
|
+++ tracing_controller_impl.cc (working copy)
|
|
@@ -177,7 +177,7 @@
|
|
is_recording_ = true;
|
|
|
|
// Notify all child processes.
|
|
- for (TraceMessageFilterMap::iterator it = trace_message_filters_.begin();
|
|
+ for (TraceMessageFilterSet::iterator it = trace_message_filters_.begin();
|
|
it != trace_message_filters_.end(); ++it) {
|
|
it->get()->SendBeginTracing(category_filter, trace_options);
|
|
}
|
|
@@ -212,21 +212,20 @@
|
|
// Count myself (local trace) in pending_disable_recording_ack_count_,
|
|
// acked below.
|
|
pending_disable_recording_ack_count_ = trace_message_filters_.size() + 1;
|
|
+ pending_disable_recording_filters_ = trace_message_filters_;
|
|
|
|
- // Handle special case of zero child processes by immediately telling the
|
|
- // caller that tracing has ended. Use asynchronous OnDisableRecordingAcked
|
|
- // to avoid recursive call back to the caller.
|
|
+ // Handle special case of zero child processes by immediately flushing the
|
|
+ // trace log. Once the flush has completed the caller will be notified that
|
|
+ // tracing has ended.
|
|
if (pending_disable_recording_ack_count_ == 1) {
|
|
- // Ack asynchronously now, because we don't have any children to wait for.
|
|
- std::vector<std::string> category_groups;
|
|
- TraceLog::GetInstance()->GetKnownCategoryGroups(&category_groups);
|
|
- BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
|
|
- base::Bind(&TracingControllerImpl::OnDisableRecordingAcked,
|
|
- base::Unretained(this), category_groups));
|
|
+ // Flush asynchronously now, because we don't have any children to wait for.
|
|
+ TraceLog::GetInstance()->Flush(
|
|
+ base::Bind(&TracingControllerImpl::OnLocalTraceDataCollected,
|
|
+ base::Unretained(this)));
|
|
}
|
|
|
|
// Notify all child processes.
|
|
- for (TraceMessageFilterMap::iterator it = trace_message_filters_.begin();
|
|
+ for (TraceMessageFilterSet::iterator it = trace_message_filters_.begin();
|
|
it != trace_message_filters_.end(); ++it) {
|
|
it->get()->SendEndTracing();
|
|
}
|
|
@@ -256,7 +255,7 @@
|
|
static_cast<TraceLog::Options>(monitoring_tracing_options));
|
|
|
|
// Notify all child processes.
|
|
- for (TraceMessageFilterMap::iterator it = trace_message_filters_.begin();
|
|
+ for (TraceMessageFilterSet::iterator it = trace_message_filters_.begin();
|
|
it != trace_message_filters_.end(); ++it) {
|
|
it->get()->SendEnableMonitoring(category_filter,
|
|
static_cast<TraceLog::Options>(monitoring_tracing_options));
|
|
@@ -278,7 +277,7 @@
|
|
TraceLog::GetInstance()->SetDisabled();
|
|
|
|
// Notify all child processes.
|
|
- for (TraceMessageFilterMap::iterator it = trace_message_filters_.begin();
|
|
+ for (TraceMessageFilterSet::iterator it = trace_message_filters_.begin();
|
|
it != trace_message_filters_.end(); ++it) {
|
|
it->get()->SendDisableMonitoring();
|
|
}
|
|
@@ -313,20 +312,20 @@
|
|
// acked below.
|
|
pending_capture_monitoring_snapshot_ack_count_ =
|
|
trace_message_filters_.size() + 1;
|
|
+ pending_capture_monitoring_filters_ = trace_message_filters_;
|
|
|
|
- // Handle special case of zero child processes by immediately telling the
|
|
- // caller that capturing snapshot has ended. Use asynchronous
|
|
- // OnCaptureMonitoringSnapshotAcked to avoid recursive call back to the
|
|
- // caller.
|
|
+ // Handle special case of zero child processes by immediately flushing the
|
|
+ // trace log. Once the flush has completed the caller will be notified that
|
|
+ // the capture snapshot has ended.
|
|
if (pending_capture_monitoring_snapshot_ack_count_ == 1) {
|
|
- // Ack asynchronously now, because we don't have any children to wait for.
|
|
- BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
|
|
- base::Bind(&TracingControllerImpl::OnCaptureMonitoringSnapshotAcked,
|
|
+ // Flush asynchronously now, because we don't have any children to wait for.
|
|
+ TraceLog::GetInstance()->FlushButLeaveBufferIntact(
|
|
+ base::Bind(&TracingControllerImpl::OnLocalMonitoringTraceDataCollected,
|
|
base::Unretained(this)));
|
|
}
|
|
|
|
// Notify all child processes.
|
|
- for (TraceMessageFilterMap::iterator it = trace_message_filters_.begin();
|
|
+ for (TraceMessageFilterSet::iterator it = trace_message_filters_.begin();
|
|
it != trace_message_filters_.end(); ++it) {
|
|
it->get()->SendCaptureMonitoringSnapshot();
|
|
}
|
|
@@ -350,18 +349,20 @@
|
|
// Count myself in pending_trace_buffer_percent_full_ack_count_, acked below.
|
|
pending_trace_buffer_percent_full_ack_count_ =
|
|
trace_message_filters_.size() + 1;
|
|
+ pending_trace_buffer_percent_full_filters_ = trace_message_filters_;
|
|
maximum_trace_buffer_percent_full_ = 0;
|
|
|
|
- // Handle special case of zero child processes.
|
|
- if (pending_trace_buffer_percent_full_ack_count_ == 1) {
|
|
- BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
|
|
- base::Bind(&TracingControllerImpl::OnTraceBufferPercentFullReply,
|
|
- base::Unretained(this),
|
|
- TraceLog::GetInstance()->GetBufferPercentFull()));
|
|
- }
|
|
+ // Call OnTraceBufferPercentFullReply unconditionally for the browser process.
|
|
+ // This will result in immediate execution of the callback if there are no
|
|
+ // child processes.
|
|
+ BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
|
|
+ base::Bind(&TracingControllerImpl::OnTraceBufferPercentFullReply,
|
|
+ base::Unretained(this),
|
|
+ scoped_refptr<TraceMessageFilter>(),
|
|
+ TraceLog::GetInstance()->GetBufferPercentFull()));
|
|
|
|
// Notify all child processes.
|
|
- for (TraceMessageFilterMap::iterator it = trace_message_filters_.begin();
|
|
+ for (TraceMessageFilterSet::iterator it = trace_message_filters_.begin();
|
|
it != trace_message_filters_.end(); ++it) {
|
|
it->get()->SendGetTraceBufferPercentFull();
|
|
}
|
|
@@ -386,7 +387,7 @@
|
|
base::Bind(&TracingControllerImpl::OnWatchEventMatched,
|
|
base::Unretained(this)));
|
|
|
|
- for (TraceMessageFilterMap::iterator it = trace_message_filters_.begin();
|
|
+ for (TraceMessageFilterSet::iterator it = trace_message_filters_.begin();
|
|
it != trace_message_filters_.end(); ++it) {
|
|
it->get()->SendSetWatchEvent(category_name, event_name);
|
|
}
|
|
@@ -399,7 +400,7 @@
|
|
if (!can_cancel_watch_event())
|
|
return false;
|
|
|
|
- for (TraceMessageFilterMap::iterator it = trace_message_filters_.begin();
|
|
+ for (TraceMessageFilterSet::iterator it = trace_message_filters_.begin();
|
|
it != trace_message_filters_.end(); ++it) {
|
|
it->get()->SendCancelWatchEvent();
|
|
}
|
|
@@ -440,15 +441,54 @@
|
|
return;
|
|
}
|
|
|
|
+ // If a filter is removed while a response from that filter is pending then
|
|
+ // simulate the response. Otherwise the response count will be wrong and the
|
|
+ // completion callback will never be executed.
|
|
+ if (pending_disable_recording_ack_count_ > 0) {
|
|
+ TraceMessageFilterSet::const_iterator it =
|
|
+ pending_disable_recording_filters_.find(trace_message_filter);
|
|
+ if (it != pending_disable_recording_filters_.end()) {
|
|
+ BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
|
|
+ base::Bind(&TracingControllerImpl::OnDisableRecordingAcked,
|
|
+ base::Unretained(this),
|
|
+ make_scoped_refptr(trace_message_filter),
|
|
+ std::vector<std::string>()));
|
|
+ }
|
|
+ }
|
|
+ if (pending_capture_monitoring_snapshot_ack_count_ > 0) {
|
|
+ TraceMessageFilterSet::const_iterator it =
|
|
+ pending_capture_monitoring_filters_.find(trace_message_filter);
|
|
+ if (it != pending_capture_monitoring_filters_.end()) {
|
|
+ BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
|
|
+ base::Bind(&TracingControllerImpl::OnCaptureMonitoringSnapshotAcked,
|
|
+ base::Unretained(this),
|
|
+ make_scoped_refptr(trace_message_filter)));
|
|
+ }
|
|
+ }
|
|
+ if (pending_trace_buffer_percent_full_ack_count_ > 0) {
|
|
+ TraceMessageFilterSet::const_iterator it =
|
|
+ pending_trace_buffer_percent_full_filters_.find(trace_message_filter);
|
|
+ if (it != pending_trace_buffer_percent_full_filters_.end()) {
|
|
+ BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
|
|
+ base::Bind(&TracingControllerImpl::OnTraceBufferPercentFullReply,
|
|
+ base::Unretained(this),
|
|
+ make_scoped_refptr(trace_message_filter),
|
|
+ 0));
|
|
+ }
|
|
+ }
|
|
+
|
|
trace_message_filters_.erase(trace_message_filter);
|
|
}
|
|
|
|
void TracingControllerImpl::OnDisableRecordingAcked(
|
|
+ TraceMessageFilter* trace_message_filter,
|
|
const std::vector<std::string>& known_category_groups) {
|
|
if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) {
|
|
BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
|
|
base::Bind(&TracingControllerImpl::OnDisableRecordingAcked,
|
|
- base::Unretained(this), known_category_groups));
|
|
+ base::Unretained(this),
|
|
+ make_scoped_refptr(trace_message_filter),
|
|
+ known_category_groups));
|
|
return;
|
|
}
|
|
|
|
@@ -459,6 +499,12 @@
|
|
if (pending_disable_recording_ack_count_ == 0)
|
|
return;
|
|
|
|
+ if (trace_message_filter &&
|
|
+ !pending_disable_recording_filters_.erase(trace_message_filter)) {
|
|
+ // The response from the specified message filter has already been received.
|
|
+ return;
|
|
+ }
|
|
+
|
|
if (--pending_disable_recording_ack_count_ == 1) {
|
|
// All acks from subprocesses have been received. Now flush the local trace.
|
|
// During or after this call, our OnLocalTraceDataCollected will be
|
|
@@ -500,17 +546,25 @@
|
|
result_file_.reset();
|
|
}
|
|
|
|
-void TracingControllerImpl::OnCaptureMonitoringSnapshotAcked() {
|
|
+void TracingControllerImpl::OnCaptureMonitoringSnapshotAcked(
|
|
+ TraceMessageFilter* trace_message_filter) {
|
|
if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) {
|
|
BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
|
|
base::Bind(&TracingControllerImpl::OnCaptureMonitoringSnapshotAcked,
|
|
- base::Unretained(this)));
|
|
+ base::Unretained(this),
|
|
+ make_scoped_refptr(trace_message_filter)));
|
|
return;
|
|
}
|
|
|
|
if (pending_capture_monitoring_snapshot_ack_count_ == 0)
|
|
return;
|
|
|
|
+ if (trace_message_filter &&
|
|
+ !pending_capture_monitoring_filters_.erase(trace_message_filter)) {
|
|
+ // The response from the specified message filter has already been received.
|
|
+ return;
|
|
+ }
|
|
+
|
|
if (--pending_capture_monitoring_snapshot_ack_count_ == 1) {
|
|
// All acks from subprocesses have been received. Now flush the local trace.
|
|
// During or after this call, our OnLocalMonitoringTraceDataCollected
|
|
@@ -585,7 +639,7 @@
|
|
// Simulate an DisableRecordingAcked for the local trace.
|
|
std::vector<std::string> category_groups;
|
|
TraceLog::GetInstance()->GetKnownCategoryGroups(&category_groups);
|
|
- OnDisableRecordingAcked(category_groups);
|
|
+ OnDisableRecordingAcked(NULL, category_groups);
|
|
}
|
|
|
|
void TracingControllerImpl::OnLocalMonitoringTraceDataCollected(
|
|
@@ -598,20 +652,30 @@
|
|
return;
|
|
|
|
// Simulate an CaptureMonitoringSnapshotAcked for the local trace.
|
|
- OnCaptureMonitoringSnapshotAcked();
|
|
+ OnCaptureMonitoringSnapshotAcked(NULL);
|
|
}
|
|
|
|
-void TracingControllerImpl::OnTraceBufferPercentFullReply(float percent_full) {
|
|
+void TracingControllerImpl::OnTraceBufferPercentFullReply(
|
|
+ TraceMessageFilter* trace_message_filter,
|
|
+ float percent_full) {
|
|
if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) {
|
|
BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
|
|
base::Bind(&TracingControllerImpl::OnTraceBufferPercentFullReply,
|
|
- base::Unretained(this), percent_full));
|
|
+ base::Unretained(this),
|
|
+ make_scoped_refptr(trace_message_filter),
|
|
+ percent_full));
|
|
return;
|
|
}
|
|
|
|
if (pending_trace_buffer_percent_full_ack_count_ == 0)
|
|
return;
|
|
|
|
+ if (trace_message_filter &&
|
|
+ !pending_trace_buffer_percent_full_filters_.erase(trace_message_filter)) {
|
|
+ // The response from the specified message filter has already been received.
|
|
+ return;
|
|
+ }
|
|
+
|
|
maximum_trace_buffer_percent_full_ =
|
|
std::max(maximum_trace_buffer_percent_full_, percent_full);
|
|
|
|
@@ -621,15 +685,6 @@
|
|
maximum_trace_buffer_percent_full_);
|
|
pending_trace_buffer_percent_full_callback_.Reset();
|
|
}
|
|
-
|
|
- if (pending_trace_buffer_percent_full_ack_count_ == 1) {
|
|
- // The last ack represents local trace, so we need to ack it now. Note that
|
|
- // this code only executes if there were child processes.
|
|
- BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
|
|
- base::Bind(&TracingControllerImpl::OnTraceBufferPercentFullReply,
|
|
- base::Unretained(this),
|
|
- TraceLog::GetInstance()->GetBufferPercentFull()));
|
|
- }
|
|
}
|
|
|
|
void TracingControllerImpl::OnWatchEventMatched() {
|
|
Index: tracing_controller_impl.h
|
|
===================================================================
|
|
--- tracing_controller_impl.h (revision 247552)
|
|
+++ tracing_controller_impl.h (working copy)
|
|
@@ -55,7 +55,7 @@
|
|
virtual bool CancelWatchEvent() OVERRIDE;
|
|
|
|
private:
|
|
- typedef std::set<scoped_refptr<TraceMessageFilter> > TraceMessageFilterMap;
|
|
+ typedef std::set<scoped_refptr<TraceMessageFilter> > TraceMessageFilterSet;
|
|
class ResultFile;
|
|
|
|
friend struct base::DefaultLazyInstanceTraits<TracingControllerImpl>;
|
|
@@ -107,23 +107,30 @@
|
|
bool has_more_events);
|
|
|
|
void OnDisableRecordingAcked(
|
|
+ TraceMessageFilter* trace_message_filter,
|
|
const std::vector<std::string>& known_category_groups);
|
|
void OnResultFileClosed();
|
|
|
|
- void OnCaptureMonitoringSnapshotAcked();
|
|
+ void OnCaptureMonitoringSnapshotAcked(
|
|
+ TraceMessageFilter* trace_message_filter);
|
|
void OnMonitoringSnapshotFileClosed();
|
|
|
|
- void OnTraceBufferPercentFullReply(float percent_full);
|
|
+ void OnTraceBufferPercentFullReply(
|
|
+ TraceMessageFilter* trace_message_filter,
|
|
+ float percent_full);
|
|
|
|
void OnWatchEventMatched();
|
|
|
|
- TraceMessageFilterMap trace_message_filters_;
|
|
+ TraceMessageFilterSet trace_message_filters_;
|
|
// Pending acks for DisableRecording.
|
|
int pending_disable_recording_ack_count_;
|
|
+ TraceMessageFilterSet pending_disable_recording_filters_;
|
|
// Pending acks for CaptureMonitoringSnapshot.
|
|
int pending_capture_monitoring_snapshot_ack_count_;
|
|
+ TraceMessageFilterSet pending_capture_monitoring_filters_;
|
|
// Pending acks for GetTraceBufferPercentFull.
|
|
int pending_trace_buffer_percent_full_ack_count_;
|
|
+ TraceMessageFilterSet pending_trace_buffer_percent_full_filters_;
|
|
float maximum_trace_buffer_percent_full_;
|
|
|
|
bool is_recording_;
|