base: Don't keep running tasks after nested run loop quits on iOS

The CoreFoundation message pump (MessagePumpCFRunLoop) scheduled an extra call
to Delegate::DoWork in the following scenario:

  1. Start a run loop and schedule DoWork.
  2. In DoWork, start a second run nested run loop which quits immediately.
  3. After the nested run loop quits, schedule another DoWork which quits the
     original run loop.

After step #3, the message pump would call DoWork again because the nested
run loop triggered the execution of the nesting deferred work source.

This patch fixes the issue by checking whether the further work is allowed
before calling DoWork. Note that this check can't be done just for the nested
deferred work source, because in the flow above that source is what triggers
the call to DoWork in step #3, i.e., the run loop hasn't quit yet at that point.

The patch also includes a fix to
WebContentsViewMacInteractiveTest.SelectMenuLifetime; the test had the
following sequence in it (while a select menu is open):

  1. Quit an outer run loop.
  2. Post a task onto an inner run loop to continue the test.

The assumption here was that a select menu causes an inner run loop to
be active while the menu is open. This wasn't strictly correct: the
inner run loop is a native (CoreFoundation) run loop as opposed to a
base::RunLoop, which can't be explicitly exited with RunLoop::Quit().
This means that the Quit() in step #1 affects the same run loop as the
PostTask in step #2, i.e., the task is prevented from running.

This patch changes the test to only quit the test run loop after the
posted task (which closes the select menu) has run.

Bug: 891670
Change-Id: I6fe21289205664c4e1b1469547495667c753f56d
Reviewed-on: https://chromium-review.googlesource.com/c/1373754
Reviewed-by: Mark Mentovai <mark@chromium.org>
Commit-Queue: Sami Kyöstilä <skyostil@chromium.org>
Cr-Commit-Position: refs/heads/master@{#615967}
3 files changed