serial: fix warning when driver doesn't support closing_wait (bgo #630670)

It appears that GIOChannel might also do some flushing, so make sure
our warning captures that delay if there is one.  Also be paranoid
and make sure nothing reset our closing_wait value.
This commit is contained in:
Dan Williams
2012-11-08 12:17:00 -06:00
parent 191eabe952
commit e798b6e663

View File

@@ -902,7 +902,7 @@ mm_serial_port_open (MMSerialPort *self, GError **error)
/* Don't wait for pending data when closing the port; this can cause some /* Don't wait for pending data when closing the port; this can cause some
* stupid devices that don't respond to URBs on a particular port to hang * stupid devices that don't respond to URBs on a particular port to hang
* for 30 seconds when probin fails. * for 30 seconds when probing fails. See GNOME bug #630670.
*/ */
if (ioctl (priv->fd, TIOCGSERIAL, &sinfo) == 0) { if (ioctl (priv->fd, TIOCGSERIAL, &sinfo) == 0) {
sinfo.closing_wait = ASYNC_CLOSING_WAIT_NONE; sinfo.closing_wait = ASYNC_CLOSING_WAIT_NONE;
@@ -980,11 +980,25 @@ mm_serial_port_close (MMSerialPort *self)
if (priv->fd >= 0) { if (priv->fd >= 0) {
GTimeVal tv_start, tv_end; GTimeVal tv_start, tv_end;
struct serial_struct sinfo;
mm_info ("(%s) closing serial port...", device); mm_info ("(%s) closing serial port...", device);
mm_port_set_connected (MM_PORT (self), FALSE); mm_port_set_connected (MM_PORT (self), FALSE);
/* Paranoid: ensure our closing_wait value is still set so we ignore
* pending data when closing the port. See GNOME bug #630670.
*/
if (ioctl (priv->fd, TIOCGSERIAL, &sinfo) == 0) {
if (sinfo.closing_wait != ASYNC_CLOSING_WAIT_NONE) {
mm_warn ("(%s): serial port closing_wait was reset!", device);
sinfo.closing_wait = ASYNC_CLOSING_WAIT_NONE;
(void) ioctl (priv->fd, TIOCSSERIAL, &sinfo);
}
}
g_get_current_time (&tv_start);
if (priv->channel) { if (priv->channel) {
g_source_remove (priv->watch_id); g_source_remove (priv->watch_id);
priv->watch_id = 0; priv->watch_id = 0;
@@ -993,8 +1007,6 @@ mm_serial_port_close (MMSerialPort *self)
priv->channel = NULL; priv->channel = NULL;
} }
g_get_current_time (&tv_start);
tcsetattr (priv->fd, TCSANOW, &priv->old_t); tcsetattr (priv->fd, TCSANOW, &priv->old_t);
tcflush (priv->fd, TCIOFLUSH); tcflush (priv->fd, TCIOFLUSH);
close (priv->fd); close (priv->fd);