This is the mail archive of the
gdb-patches@sourceware.cygnus.com
mailing list for the GDB project.
ser-unix.c:do_unix_readchar() Don't timeout when told not to
- To: gdb-patches at sourceware dot cygnus dot com
- Subject: ser-unix.c:do_unix_readchar() Don't timeout when told not to
- From: Jonathan Larmour <jlarmour at redhat dot co dot uk>
- Date: Mon, 20 Mar 2000 07:42:07 +0000
- CC: Alex Schuilenburg <alexs at redhat dot co dot uk>
- Organization: Red Hat UK Ltd.
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