diff options
author | Pedro Alves <palves@redhat.com> | 2012-06-11 20:36:53 +0000 |
---|---|---|
committer | Pedro Alves <palves@redhat.com> | 2012-06-11 20:36:53 +0000 |
commit | ddefb60ff89becf2b18d0cf7930358320c6ec0e6 (patch) | |
tree | 88f0794b9680f0b82c2def63d8ebb4794c309b58 /gdb/ser-base.c | |
parent | d5ad6aa5ce9ef3812c344bfebfb27bda36d8cb46 (diff) | |
download | gdb-ddefb60ff89becf2b18d0cf7930358320c6ec0e6.zip gdb-ddefb60ff89becf2b18d0cf7930358320c6ec0e6.tar.gz gdb-ddefb60ff89becf2b18d0cf7930358320c6ec0e6.tar.bz2 |
2012-06-11 Pedro Alves <palves@redhat.com>
* ser-base.c (run_async_handler_and_reschedule): New.
(fd_event, push_event): Use it.
* serial.c (serial_open, serial_fdopen_ops): Set the initial
reference count to 1.
(do_serial_close): Set the bufp field to NULL. Use serial_unref
instead of xfree.
(serial_is_open, serial_ref, serial_unref): New.
* serial.h (serial_open): Adjust comment.
(serial_is_open): Declare.
(serial_close): Adjust comment.
(serial_ref, serial_unref) Declare.
(struct serial): New field 'refcnt'.
Diffstat (limited to 'gdb/ser-base.c')
-rw-r--r-- | gdb/ser-base.c | 30 |
1 files changed, 25 insertions, 5 deletions
diff --git a/gdb/ser-base.c b/gdb/ser-base.c index b4399d0..2f12dfc 100644 --- a/gdb/ser-base.c +++ b/gdb/ser-base.c @@ -123,6 +123,29 @@ reschedule (struct serial *scb) } } +/* Run the SCB's async handle, and reschedule, if the handler doesn't + close SCB. */ + +static void +run_async_handler_and_reschedule (struct serial *scb) +{ + int is_open; + + /* Take a reference, so a serial_close call within the handler + doesn't make SCB a dangling pointer. */ + serial_ref (scb); + + /* Run the handler. */ + scb->async_handler (scb, scb->async_context); + + is_open = serial_is_open (scb); + serial_unref (scb); + + /* Get ready for more, if not already closed. */ + if (is_open) + reschedule (scb); +} + /* FD_EVENT: This is scheduled when the input FIFO is empty (and there is no pending error). As soon as data arrives, it is read into the input FIFO and the client notified. The client should then drain @@ -158,8 +181,7 @@ fd_event (int error, void *context) scb->bufcnt = SERIAL_ERROR; } } - scb->async_handler (scb, scb->async_context); - reschedule (scb); + run_async_handler_and_reschedule (scb); } /* PUSH_EVENT: The input FIFO is non-empty (or there is a pending @@ -173,9 +195,7 @@ push_event (void *context) struct serial *scb = context; scb->async_state = NOTHING_SCHEDULED; /* Timers are one-off */ - scb->async_handler (scb, scb->async_context); - /* re-schedule */ - reschedule (scb); + run_async_handler_and_reschedule (scb); } /* Wait for input on scb, with timeout seconds. Returns 0 on success, |