This is the mail archive of the gdb-patches@sourceware.cygnus.com mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

[patch] Revert ser-unix.c


FYI,

I've committed the following which reverts:

http://sourceware.cygnus.com/ml/gdb-patches/2000-q1/msg00803.html
Tue Mar 28 18:19:50 2000  Andrew Cagney  <cagney@b1.cygnus.com>

        From 2000-03-20 Jonathan Larmour <jlarmour@redhat.co.uk>:
        * ser-unix.c (do_unix_readchar): Reorganise to be more robust,
        particularly ensuring it can't return SERIAL_TIMEOUT when told
        not to time out.

When there is a positive timeout, but no pending data, read() is is
called and it will block.   When there is a negative timeout
ser_unix_wait_for() may never return meaning that ui_loop_hook() is
never called.

Going back to the original code/problem.  I'm going to ``react in
dis-belief''.  Jonathan, can you explain exactly how the function comes
to return a TIMEOUT?  As far as I can tell, it will only return a
timeout when:

	o	timeout reaches/== zero

	o	read() returns zero characters.

Assuming it is the second one, I don't see how read() can return zero
characters as we've previously been told by select() that data is
pending.  Hmm, whats the OS, what is the target, ...

Studying the reverted code, I've noticed the problems:

	o	when timeout<0, it is decremented
		but that wouldn't matter as the chance
		of the timeout wrapping back to zero
		is low.

	o	ser_unix_wait_for() waits on both
		readfds and exceptfds.  When an
		exceptfd it should return error.

but in either case I can't see them being the cause of the bogus
timeout.

	Andrew
Sat Jul  1 17:47:08 2000  Andrew Cagney  <cagney@b1.cygnus.com>

	* ser-unix.c (do_unix_readchar): Revert Tue Mar 28 18:19:50 2000
 	Andrew Cagney <cagney@b1.cygnus.com>.  Locks up when no data is
 	pending.

Index: ser-unix.c
===================================================================
RCS file: /cvs/src/src/gdb/ser-unix.c,v
retrieving revision 1.3
diff -p -r1.3 ser-unix.c
*** ser-unix.c	2000/03/28 08:24:28	1.3
--- ser-unix.c	2000/07/01 07:52:18
*************** do_unix_readchar (serial_t scb, int time
*** 910,918 ****
       each time through the loop.
  
       Also, timeout = 0 means to poll, so we just set the delta to 0, so we
!      will only go through the loop once. timeout < 0 means to wait forever. */
  
!   delta = (timeout <= 0 ? 0 : 1);
    while (1)
      {
  
--- 910,918 ----
       each time through the loop.
  
       Also, timeout = 0 means to poll, so we just set the delta to 0, so we
!      will only go through the loop once. */
  
!   delta = (timeout == 0 ? 0 : 1);
    while (1)
      {
  
*************** do_unix_readchar (serial_t scb, int time
*** 928,965 ****
  	    return SERIAL_TIMEOUT;
  	}
  
!       status = ser_unix_wait_for (scb, timeout < 0 ? timeout : delta);
        timeout -= delta;
  
!       /* If we got an error back from wait_for, then we can return */
  
!       if (status == SERIAL_ERROR)
!         return status;
  
!       status = read (scb->fd, scb->buf, BUFSIZ);
  
!       if (status <= 0)
!         {
!           if (status == 0)
!             {
!               if (timeout != 0)
!                 continue;
!               else
!                 return SERIAL_TIMEOUT;	/* 0 chars means timeout [may need to
! 					   distinguish between EOF & timeouts
! 					   someday] */
!             }
! 	  else if (errno == EINTR)
!             continue;
!           else
! 	    return SERIAL_ERROR;	/* Got an error from read */
  	}
  
!       scb->bufcnt = status;
!       scb->bufcnt--;
!       scb->bufp = scb->buf;
!       return *scb->bufp++;
      }
  }
  
  /* Perform operations common to both old and new readchar. */
--- 928,978 ----
  	    return SERIAL_TIMEOUT;
  	}
  
!       status = ser_unix_wait_for (scb, delta);
        timeout -= delta;
  
!       /* If we got a character or an error back from wait_for, then we can 
!          break from the loop before the timeout is completed. */
  
!       if (status != SERIAL_TIMEOUT)
! 	{
! 	  break;
! 	}
  
!       /* If we have exhausted the original timeout, then generate
!          a SERIAL_TIMEOUT, and pass it out of the loop. */
  
!       else if (timeout == 0)
! 	{
! 	  status = SERIAL_TIMEOUT;
! 	  break;
  	}
+     }
+ 
+   if (status < 0)
+     return status;
  
!   while (1)
!     {
!       status = read (scb->fd, scb->buf, BUFSIZ);
!       if (status != -1 || errno != EINTR)
! 	break;
!     }
! 
!   if (status <= 0)
!     {
!       if (status == 0)
! 	return SERIAL_TIMEOUT;	/* 0 chars means timeout [may need to
! 				   distinguish between EOF & timeouts
! 				   someday] */
!       else
! 	return SERIAL_ERROR;	/* Got an error from read */
      }
+ 
+   scb->bufcnt = status;
+   scb->bufcnt--;
+   scb->bufp = scb->buf;
+   return *scb->bufp++;
  }
  
  /* Perform operations common to both old and new readchar. */

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]