diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index 41cc38bd3a8..92cab61e250 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,3 +1,22 @@
+2001-06-06  Mark Kettenis  <kettenis@gnu.org>
+
+	* lin-lwp.c (struct lwp_info): Add member `resumed'.
+	(iterate_over_lwps): Make sure we can handle CALLBACK deleting the
+	LWP it's called for.
+	(lin_lwp_attach): Mark LWP as resumed to make sure the fake
+	SIGSTOP is reported.
+	(resume_clear_callback): New function.
+	(resume_set_callback): New function.
+	(lin_lwp_resume): Mark all LWP's that we're going to resume as
+	resumed, and unmark all others.
+	(status_callback): Only report a pending wait status if we pretend
+	that LP has been resumed.
+	(resumed_callback): New function.
+	(lin_lwp_wait): Add assertions to check that LWP's are properly
+	marked as resumed.  Partially revert 2001-05-25 patch by Michael
+	Snyder: do not resume all threads.  Add comment explaining the
+	problems associated with this bit of code.
+
 2001-06-07  Keith Seitz  <keiths@redhat.com>
 
 	* MAINTAINTERS: Syd Polk is stepping down from
diff --git a/gdb/lin-lwp.c b/gdb/lin-lwp.c
index 0948a543161..91f3691903b 100644
--- a/gdb/lin-lwp.c
+++ b/gdb/lin-lwp.c
@@ -82,6 +82,14 @@ struct lwp_info
   /* Non-zero if this LWP is stopped.  */
   int stopped;
 
+  /* Non-zero if this LWP will be/has been resumed.  Note that an LWP
+     can be marked both as stopped and resumed at the same time.  This
+     happens if we try to resume an LWP that has a wait status
+     pending.  We shouldn't let the LWP run until that wait status has
+     been processed, but we should not report that wait status if GDB
+     didn't try to let the LWP run.  */
+  int resumed;
+
   /* If non-zero, a pending wait status.  */
   int status;
 
@@ -249,11 +257,14 @@ find_lwp_pid (ptid_t ptid)
 struct lwp_info *
 iterate_over_lwps (int (*callback) (struct lwp_info *, void *), void *data)
 {
-  struct lwp_info *lp;
+  struct lwp_info *lp, *lpnext;
 
-  for (lp = lwp_list; lp; lp = lp->next)
-    if ((*callback) (lp, data))
-      return lp;
+  for (lp = lwp_list; lp; lp = lpnext)
+    {
+      lpnext = lp->next;
+      if ((*callback) (lp, data))
+	return lp;
+    }
 
   return NULL;
 }
@@ -357,6 +368,7 @@ lin_lwp_attach (char *args, int from_tty)
 
   /* Fake the SIGSTOP that core GDB expects.  */
   lp->status = W_STOPCODE (SIGSTOP);
+  lp->resumed = 1;
 }
 
 static int
@@ -475,6 +487,20 @@ resume_callback (struct lwp_info *lp, void *data)
   return 0;
 }
 
+static int
+resume_clear_callback (struct lwp_info *lp, void *data)
+{
+  lp->resumed = 0;
+  return 0;
+}
+
+static int
+resume_set_callback (struct lwp_info *lp, void *data)
+{
+  lp->resumed = 1;
+  return 0;
+}
+
 static void
 lin_lwp_resume (ptid_t ptid, int step, enum target_signal signo)
 {
@@ -487,6 +513,11 @@ lin_lwp_resume (ptid_t ptid, int step, enum target_signal signo)
      processes, but give the signal only to this one'.  */
   resume_all = (PIDGET (ptid) == -1) || !step;
 
+  if (resume_all)
+    iterate_over_lwps (resume_set_callback, NULL);
+  else
+    iterate_over_lwps (resume_clear_callback, NULL);
+
   /* If PID is -1, it's the current inferior that should be
      handled specially.  */
   if (PIDGET (ptid) == -1)
@@ -500,6 +531,9 @@ lin_lwp_resume (ptid_t ptid, int step, enum target_signal signo)
       /* Remember if we're stepping.  */
       lp->step = step;
 
+      /* Mark this LWP as resumed.  */
+      lp->resumed = 1;
+
       /* If we have a pending wait status for this thread, there is no
          point in resuming the process.  */
       if (lp->status)
@@ -663,7 +697,9 @@ stop_wait_callback (struct lwp_info *lp, void *data)
 static int
 status_callback (struct lwp_info *lp, void *data)
 {
-  return (lp->status != 0);
+  /* Only report a pending wait status if we pretend that this has
+     indeed been resumed.  */
+  return (lp->status != 0 && lp->resumed);
 }
 
 /* Return non-zero if LP isn't stopped.  */
@@ -674,6 +710,14 @@ running_callback (struct lwp_info *lp, void *data)
   return (lp->stopped == 0);
 }
 
+/* Return non-zero if LP has been resumed.  */
+
+static int
+resumed_callback (struct lwp_info *lp, void *data)
+{
+  return lp->resumed;
+}
+
 static ptid_t
 lin_lwp_wait (ptid_t ptid, struct target_waitstatus *ourstatus)
 {
@@ -691,6 +735,9 @@ lin_lwp_wait (ptid_t ptid, struct target_waitstatus *ourstatus)
 
  retry:
 
+  /* Make sure there is at least one thread that has been resumed.  */
+  gdb_assert (iterate_over_lwps (resumed_callback, NULL));
+
   /* First check if there is a LWP with a wait status pending.  */
   if (pid == -1)
     {
@@ -754,6 +801,7 @@ lin_lwp_wait (ptid_t ptid, struct target_waitstatus *ourstatus)
       child_resume (pid_to_ptid (GET_LWP (lp->ptid)), lp->step,
                     TARGET_SIGNAL_0);
       lp->stopped = 0;
+      gdb_assert (lp->resumed);
 
       /* This should catch the pending SIGSTOP.  */
       stop_wait_callback (lp, NULL);
@@ -840,6 +888,7 @@ lin_lwp_wait (ptid_t ptid, struct target_waitstatus *ourstatus)
 	      child_resume (pid_to_ptid (GET_LWP (lp->ptid)), lp->step,
 	                    TARGET_SIGNAL_0);
 	      lp->stopped = 0;
+	      gdb_assert (lp->resumed);
 
 	      /* Discard the event.  */
 	      status = 0;
@@ -883,14 +932,13 @@ lin_lwp_wait (ptid_t ptid, struct target_waitstatus *ourstatus)
 	  && signal_print_state (signo) == 0
 	  && signal_pass_state (signo) == 1)
 	{
-	  /* First mark this LWP as "not stopped", so that
-	     resume_callback will not resume it. */
-	  lp->stopped = 0;
-	  /* Resume all threads except this one
-	     (mainly to get the newly attached ones). */
-	  iterate_over_lwps (resume_callback, NULL);
-	  /* Now resume this thread, forwarding the signal to it. */
+	  /* FIMXE: kettenis/2001-06-06: Should we resume all threads
+             here?  It is not clear we should.  GDB may not expect
+             other threads to run.  On the other hand, not resuming
+             newly attached threads may cause an unwanted delay in
+             getting them running.  */
 	  child_resume (pid_to_ptid (GET_LWP (lp->ptid)), lp->step, signo);
+	  lp->stopped = 0;
 	  status = 0;
 	  goto retry;
 	}