* linux-nat.c (linux_nat_wait_1): Bail out, if TARGET_WNOHANG and
authorPedro Alves <palves@redhat.com>
Fri, 9 Oct 2009 01:57:12 +0000 (01:57 +0000)
committerPedro Alves <palves@redhat.com>
Fri, 9 Oct 2009 01:57:12 +0000 (01:57 +0000)
we found no event while waiting for a specific LWP.
* infrun.c (handle_inferior_event): Handle TARGET_WAITKIND_IGNORE
before anything else.

gdb/ChangeLog
gdb/infrun.c
gdb/linux-nat.c

index 77987ca15fab5e621a381d885b3d1c2587879b8b..c18ed8011c7e0200326c999ceedb2a81a41eb32a 100644 (file)
@@ -1,3 +1,10 @@
+2009-10-09  Pedro Alves  <pedro@codesourcery.com>
+
+       * linux-nat.c (linux_nat_wait_1): Bail out, if TARGET_WNOHANG and
+       we found no event while waiting for a specific LWP.
+       * infrun.c (handle_inferior_event): Handle TARGET_WAITKIND_IGNORE
+       before anything else.
+
 2009-10-09  Pedro Alves  <pedro@codesourcery.com>
 
        * procfs.c (procfs_make_note_section): Always output a NT_PSTATUS
index 4ce07d9dcf0f78fc1598e23a81394ed342707f24..203ab5d5cad0b415695e141033bdd071c947241f 100644 (file)
@@ -2443,9 +2443,25 @@ handle_inferior_event (struct execution_control_state *ecs)
   struct symtab_and_line stop_pc_sal;
   enum stop_kind stop_soon;
 
+  if (ecs->ws.kind == TARGET_WAITKIND_IGNORE)
+    {
+      /* We had an event in the inferior, but we are not interested in
+        handling it at this level.  The lower layers have already
+        done what needs to be done, if anything.
+
+        One of the possible circumstances for this is when the
+        inferior produces output for the console.  The inferior has
+        not stopped, and we are ignoring the event.  Another possible
+        circumstance is any event which the lower level knows will be
+        reported multiple times without an intervening resume.  */
+      if (debug_infrun)
+       fprintf_unfiltered (gdb_stdlog, "infrun: TARGET_WAITKIND_IGNORE\n");
+      prepare_to_wait (ecs);
+      return;
+    }
+
   if (ecs->ws.kind != TARGET_WAITKIND_EXITED
-      && ecs->ws.kind != TARGET_WAITKIND_SIGNALLED
-      && ecs->ws.kind != TARGET_WAITKIND_IGNORE)
+      && ecs->ws.kind != TARGET_WAITKIND_SIGNALLED)
     {
       struct inferior *inf = find_inferior_pid (ptid_get_pid (ecs->ptid));
       gdb_assert (inf);
@@ -2479,22 +2495,19 @@ handle_inferior_event (struct execution_control_state *ecs)
   /* Dependent on the current PC value modified by adjust_pc_after_break.  */
   reinit_frame_cache ();
 
-  if (ecs->ws.kind != TARGET_WAITKIND_IGNORE)
-    {
-      breakpoint_retire_moribund ();
-
-      /* Mark the non-executing threads accordingly.  In all-stop, all
-        threads of all processes are stopped when we get any event
-        reported.  In non-stop mode, only the event thread stops.  If
-        we're handling a process exit in non-stop mode, there's
-        nothing to do, as threads of the dead process are gone, and
-        threads of any other process were left running.  */
-      if (!non_stop)
-       set_executing (minus_one_ptid, 0);
-      else if (ecs->ws.kind != TARGET_WAITKIND_SIGNALLED
-              && ecs->ws.kind != TARGET_WAITKIND_EXITED)
-       set_executing (inferior_ptid, 0);
-    }
+  breakpoint_retire_moribund ();
+
+  /* Mark the non-executing threads accordingly.  In all-stop, all
+     threads of all processes are stopped when we get any event
+     reported.  In non-stop mode, only the event thread stops.  If
+     we're handling a process exit in non-stop mode, there's nothing
+     to do, as threads of the dead process are gone, and threads of
+     any other process were left running.  */
+  if (!non_stop)
+    set_executing (minus_one_ptid, 0);
+  else if (ecs->ws.kind != TARGET_WAITKIND_SIGNALLED
+          && ecs->ws.kind != TARGET_WAITKIND_EXITED)
+    set_executing (inferior_ptid, 0);
 
   switch (infwait_state)
     {
@@ -2777,21 +2790,6 @@ handle_inferior_event (struct execution_control_state *ecs)
       print_stop_reason (NO_HISTORY, 0);
       stop_stepping (ecs);
       return;
-
-      /* We had an event in the inferior, but we are not interested
-         in handling it at this level. The lower layers have already
-         done what needs to be done, if anything.
-
-         One of the possible circumstances for this is when the
-         inferior produces output for the console. The inferior has
-         not stopped, and we are ignoring the event.  Another possible
-         circumstance is any event which the lower level knows will be
-         reported multiple times without an intervening resume.  */
-    case TARGET_WAITKIND_IGNORE:
-      if (debug_infrun)
-        fprintf_unfiltered (gdb_stdlog, "infrun: TARGET_WAITKIND_IGNORE\n");
-      prepare_to_wait (ecs);
-      return;
     }
 
   if (ecs->new_thread_event)
index f4f843bf0ef13cf7e56803cae080bcc363588145..bde73117de8af311d5e2a074803ab5e7d59e6a4e 100644 (file)
@@ -3255,6 +3255,17 @@ retry:
              sigsuspend (&suspend_mask);
            }
        }
+      else if (target_options & TARGET_WNOHANG)
+       {
+         /* No interesting event for PID yet.  */
+         ourstatus->kind = TARGET_WAITKIND_IGNORE;
+
+         if (debug_linux_nat_async)
+           fprintf_unfiltered (gdb_stdlog, "LLW: exit (ignore)\n");
+
+         restore_child_signals_mask (&prev_mask);
+         return minus_one_ptid;
+       }
 
       /* We shouldn't end up here unless we want to try again.  */
       gdb_assert (lp == NULL);