| Index: chrome/browser/sync/test/integration/passwords_helper.cc
|
| diff --git a/chrome/browser/sync/test/integration/passwords_helper.cc b/chrome/browser/sync/test/integration/passwords_helper.cc
|
| index 7e3cf9404d06da0850dc792db1f9b19dbba25939..7fd71e12a79472c8670003e25d97ac74f7af18e3 100644
|
| --- a/chrome/browser/sync/test/integration/passwords_helper.cc
|
| +++ b/chrome/browser/sync/test/integration/passwords_helper.cc
|
| @@ -207,16 +207,50 @@ class SamePasswordFormsChecker : public MultiClientStatusChangeChecker {
|
|
|
| virtual bool IsExitConditionSatisfied() OVERRIDE;
|
| virtual std::string GetDebugMessage() const OVERRIDE;
|
| +
|
| + private:
|
| + bool in_progress_;
|
| + bool needs_recheck_;
|
| };
|
|
|
| SamePasswordFormsChecker::SamePasswordFormsChecker()
|
| : MultiClientStatusChangeChecker(
|
| - sync_datatype_helper::test()->GetSyncServices()) {}
|
| + sync_datatype_helper::test()->GetSyncServices()),
|
| + in_progress_(false),
|
| + needs_recheck_(false) {}
|
|
|
| SamePasswordFormsChecker::~SamePasswordFormsChecker() {}
|
|
|
| +// This method needs protection against re-entrancy.
|
| +//
|
| +// This function indirectly calls GetLogins(), which starts a RunLoop on the UI
|
| +// thread. This can be a problem, since the next task to execute could very
|
| +// well contain a ProfileSyncService::OnStateChanged() event, which would
|
| +// trigger another call to this here function, and start another layer of
|
| +// nested RunLoops. That makes the StatusChangeChecker's Quit() method
|
| +// ineffective.
|
| +//
|
| +// The work-around is to not allow re-entrancy. But we can't just drop
|
| +// IsExitConditionSatisifed() calls if one is already in progress. Instead, we
|
| +// set a flag to ask the current execution of IsExitConditionSatisfied() to be
|
| +// re-run. This ensures that the return value is always based on the most
|
| +// up-to-date state.
|
| bool SamePasswordFormsChecker::IsExitConditionSatisfied() {
|
| - return AllProfilesContainSamePasswordForms();
|
| + if (in_progress_) {
|
| + LOG(WARNING) << "Setting flag and returning early to prevent nesting.";
|
| + needs_recheck_ = true;
|
| + return false;
|
| + }
|
| +
|
| + // Keep retrying until we get a good reading.
|
| + bool result = false;
|
| + in_progress_ = true;
|
| + do {
|
| + needs_recheck_ = false;
|
| + result = AllProfilesContainSamePasswordForms();
|
| + } while (needs_recheck_);
|
| + in_progress_ = false;
|
| + return result;
|
| }
|
|
|
| std::string SamePasswordFormsChecker::GetDebugMessage() const {
|
|
|