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]

ser-unix.c:do_unix_readchar() Don't timeout when told not to


A while back, folks in the eCos team reported that you could get "Watchdog
has expired. Target detached." messages even when the watchdog wasn't set.
The GDB team reacted in disbelief :-).

After getting irritated by it this evening, I looked for and found the
problem: do_unix_readchar() could still return SERIAL_TIMEOUT, even when the
requested timeout was -1 (i.e. infinite).

The attached patch fixes the problem, and I used the opportunity to make the
code slightly more robust, and more similar to e.g. do_hardwire_readchar in
the same file.

I don't have write permission, so please check this in. Thanks,

Jifl

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.


-- 
Red Hat, 35 Cambridge Place, Cambridge, UK. CB2 1NS  Tel: +44 (1223) 728762
"Plan to be spontaneous tomorrow."  ||  These opinions are all my own fault
Index: ser-unix.c
===================================================================
RCS file: /cvs/src/src/gdb/ser-unix.c,v
retrieving revision 1.2
diff -u -5 -p -c -r1.2 ser-unix.c
*** ser-unix.c	2000/02/09 08:52:47	1.2
--- ser-unix.c	2000/03/20 07:30:48
*************** do_unix_readchar (serial_t scb, int time
*** 908,920 ****
    /* We have to be able to keep the GUI alive here, so we break the original
       timeout into steps of 1 second, running the "keep the GUI alive" hook 
       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)
      {
  
        /* N.B. The UI may destroy our world (for instance by calling
           remote_stop,) in which case we want to get out of here as
--- 908,920 ----
    /* We have to be able to keep the GUI alive here, so we break the original
       timeout into steps of 1 second, running the "keep the GUI alive" hook 
       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)
      {
  
        /* N.B. The UI may destroy our world (for instance by calling
           remote_stop,) in which case we want to get out of here as
*************** do_unix_readchar (serial_t scb, int time
*** 926,980 ****
  	{
  	  if (ui_loop_hook (0))
  	    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. */
  
  /* Return the next character from the input FIFO.  If the FIFO is
--- 926,967 ----
  	{
  	  if (ui_loop_hook (0))
  	    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. */
  
  /* Return the next character from the input FIFO.  If the FIFO is

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