Index: chrome/browser/automation/testing_automation_provider.cc |
diff --git a/chrome/browser/automation/testing_automation_provider.cc b/chrome/browser/automation/testing_automation_provider.cc |
index 58a04741f2109e7b289ffce7f17fd92bf98a8d0e..4f40946edfc0f95a236ab28dcdd872ae7c9a6583 100644 |
--- a/chrome/browser/automation/testing_automation_provider.cc |
+++ b/chrome/browser/automation/testing_automation_provider.cc |
@@ -20,6 +20,7 @@ |
#include "base/process.h" |
#include "base/process_util.h" |
#include "base/stringprintf.h" |
+#include "base/synchronization/waitable_event.h" |
#include "base/threading/thread_restrictions.h" |
#include "base/time.h" |
#include "base/utf_string_conversions.h" |
@@ -176,6 +177,24 @@ class AutomationInterstitialPage : public InterstitialPage { |
DISALLOW_COPY_AND_ASSIGN(AutomationInterstitialPage); |
}; |
+// Waits for all currently pending tasks on |identifier| to be processed before |
+// returning. Returns false if |identifier| is the current thread, or a task |
+// could not be posted. Returns true otherwise. |
+bool WaitForPendingTasksOn(BrowserThread::ID identifier) { |
+ // Avoid deadlocking self. |
+ if (BrowserThread::CurrentlyOn(identifier)) |
+ return false; |
+ base::WaitableEvent event(true, // manual reset |
+ false); // not initially signaled |
+ if (!BrowserThread::PostTask( |
+ identifier, |
+ FROM_HERE, |
+ base::Bind(&base::WaitableEvent::Signal, base::Unretained(&event)))) |
+ return false; |
+ event.Wait(); |
Paweł Hajdan Jr.
2011/10/19 09:20:02
I think this also returns bool, so please return e
|
+ return true; |
+} |
+ |
} // namespace |
TestingAutomationProvider::TestingAutomationProvider(Profile* profile) |
@@ -2734,12 +2753,10 @@ namespace { |
// Used by AutomationProvider::GetBrowserInfo(). |
class GetChildProcessHostInfoTask : public Task { |
public: |
- GetChildProcessHostInfoTask(base::WaitableEvent* event, |
- ListValue* child_processes) |
- : event_(event), |
- child_processes_(child_processes) {} |
+ explicit GetChildProcessHostInfoTask(ListValue* child_processes) |
+ : child_processes_(child_processes) {} |
- virtual void Run() { |
+ virtual void Run() OVERRIDE { |
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
for (BrowserChildProcessHost::Iterator iter; !iter.Done(); ++iter) { |
// Only add processes which are already started, |
@@ -2755,11 +2772,9 @@ class GetChildProcessHostInfoTask : public Task { |
item->SetInteger("pid", base::GetProcId(info->handle())); |
child_processes_->Append(item); |
} |
- event_->Signal(); |
} |
private: |
- base::WaitableEvent* const event_; // weak |
ListValue* child_processes_; |
DISALLOW_COPY_AND_ASSIGN(GetChildProcessHostInfoTask); |
@@ -2881,12 +2896,10 @@ void TestingAutomationProvider::GetBrowserInfo( |
// Add all child processes in a list of dictionaries, one dictionary item |
// per child process. |
ListValue* child_processes = new ListValue; |
- base::WaitableEvent event(true /* manual reset */, |
- false /* not initially signaled */); |
CHECK(BrowserThread::PostTask( |
BrowserThread::IO, FROM_HERE, |
- new GetChildProcessHostInfoTask(&event, child_processes))); |
- event.Wait(); |
+ new GetChildProcessHostInfoTask(child_processes))); |
+ CHECK(WaitForPendingTasksOn(BrowserThread::IO)); |
jam
2011/10/19 23:56:27
instead of blocking one thread on another, why not
|
return_value->Set("child_processes", child_processes); |
// Add all extension processes in a list of dictionaries, one dictionary |
@@ -5901,6 +5914,14 @@ void TestingAutomationProvider::SetPolicies( |
} |
} |
+ // OverridePolicies() triggers preference updates, which triggers preference |
+ // listeners. Some policies (e.g. URLBlacklist) post tasks to other message |
+ // loops before they start being enforced; make sure those tasks have |
+ // finished. |
+ CHECK(WaitForPendingTasksOn(BrowserThread::IO)); |
jam
2011/10/19 23:56:27
ditto
|
+ CHECK(WaitForPendingTasksOn(BrowserThread::FILE)); |
+ CHECK(WaitForPendingTasksOn(BrowserThread::IO)); |
+ |
reply.SendSuccess(NULL); |
#endif // defined(OFFICIAL_BUILD) |
} |