+2011-05-20  Pedro Alves  <pedro@codesourcery.com>
+
+       * infcmd.c: Include "inf-loop.h".
+       (step_once): When stepping into an inline subroutine, pretend the
+       target has run.  If the target can async, switch the inferior
+       event loop to INF_EXEC_COMPLETE.
+       * inferior.h (user_visible_resume_ptid): Declare.
+       * infrun.c (user_visible_resume_ptid): New function, factored out
+       from `resume'.
+       (resume): Use it.
+       * mi/mi-main.c (mi_execute_async_cli_command): Remove assertion
+       that the current thread is running.  Merge async and sync
+       branches.
+
 2011-05-20  Pedro Alves  <pedro@codesourcery.com>
 
        * infcmd.c (step_1): Simplify synchronous case.
 
 #include "valprint.h"
 #include "inline-frame.h"
 #include "tracepoint.h"
+#include "inf-loop.h"
 
 /* Functions exported for general use, in inferior.h: */
 
          if (!skip_subroutines && !single_inst
              && inline_skipped_frames (inferior_ptid))
            {
+             ptid_t resume_ptid;
+
+             /* Pretend that we've ran.  */
+             resume_ptid = user_visible_resume_ptid (1);
+             set_running (resume_ptid, 1);
+
              step_into_inline_frame (inferior_ptid);
              if (count > 1)
                step_once (skip_subroutines, single_inst, count - 1, thread);
              else
-               /* Pretend that we've stopped.  */
-               normal_stop ();
+               {
+                 /* Pretend that we've stopped.  */
+                 normal_stop ();
+
+                 if (target_can_async_p ())
+                   inferior_event_handler (INF_EXEC_COMPLETE, NULL);
+               }
              return;
            }
 
 
   return hw_step;
 }
 
+/* Return a ptid representing the set of threads that we will proceed,
+   in the perspective of the user/frontend.  We may actually resume
+   fewer threads at first, e.g., if a thread is stopped at a
+   breakpoint that needs stepping-off, but that should be visible to
+   the user/frontend, and neither should the frontend/user be allowed
+   to proceed any of the threads that happen to be stopped at for
+   internal run control handling, if a previous command wanted them
+   resumed.  */
+
+ptid_t
+user_visible_resume_ptid (int step)
+{
+  /* By default, resume all threads of all processes.  */
+  ptid_t resume_ptid = RESUME_ALL;
+
+  /* Maybe resume only all threads of the current process.  */
+  if (!sched_multi && target_supports_multi_process ())
+    {
+      resume_ptid = pid_to_ptid (ptid_get_pid (inferior_ptid));
+    }
+
+  /* Maybe resume a single thread after all.  */
+  if (non_stop)
+    {
+      /* With non-stop mode on, threads are always handled
+        individually.  */
+      resume_ptid = inferior_ptid;
+    }
+  else if ((scheduler_mode == schedlock_on)
+          || (scheduler_mode == schedlock_step
+              && (step || singlestep_breakpoints_inserted_p)))
+    {
+      /* User-settable 'scheduler' mode requires solo thread resume.  */
+      resume_ptid = inferior_ptid;
+    }
+
+  return resume_ptid;
+}
+
 /* Resume the inferior, but allow a QUIT.  This is useful if the user
    wants to interrupt some lengthy single-stepping operation
    (for child processes, the SIGINT goes to the inferior, and so
       /* Decide the set of threads to ask the target to resume.  Start
         by assuming everything will be resumed, than narrow the set
         by applying increasingly restricting conditions.  */
-
-      /* By default, resume all threads of all processes.  */
-      resume_ptid = RESUME_ALL;
-
-      /* Maybe resume only all threads of the current process.  */
-      if (!sched_multi && target_supports_multi_process ())
-       {
-         resume_ptid = pid_to_ptid (ptid_get_pid (inferior_ptid));
-       }
+      resume_ptid = user_visible_resume_ptid (step);
 
       /* Maybe resume a single thread after all.  */
       if (singlestep_breakpoints_inserted_p
             breakpoint, not just the one at PC.  */
          resume_ptid = inferior_ptid;
        }
-      else if (non_stop)
-       {
-         /* With non-stop mode on, threads are always handled
-            individually.  */
-         resume_ptid = inferior_ptid;
-       }
-      else if ((scheduler_mode == schedlock_on)
-              || (scheduler_mode == schedlock_step
-                  && (step || singlestep_breakpoints_inserted_p)))
-       {
-         /* User-settable 'scheduler' mode requires solo thread resume.  */
-         resume_ptid = inferior_ptid;
-       }
 
       if (gdbarch_cannot_step_breakpoint (gdbarch))
        {
 
 
   execute_command ( /*ui */ run, 0 /*from_tty */ );
 
-  if (target_can_async_p ())
-    {
-      /* If we're not executing, an exception should have been throw.  */
-      gdb_assert (is_running (inferior_ptid));
-      do_cleanups (old_cleanups);
-    }
-  else
-    {
-      /* Do this before doing any printing.  It would appear that some
-         print code leaves garbage around in the buffer.  */
-      do_cleanups (old_cleanups);
-    }
+  /* Do this before doing any printing.  It would appear that some
+     print code leaves garbage around in the buffer.  */
+  do_cleanups (old_cleanups);
 }
 
 void