# HG changeset patch # User asl # Date 1119981372 0 # Node ID d3a8cc4f7931565356650923cebe989a92516cde # Parent 7725d216c7bc61ade37d06dd728b59a47cb23f18 * src/common/serial.c (serial_select): Swap the DSR locks and mutex locks around to avoid deadlocks with the rest of the code which uses this order. diff --git a/packages/io/serial/current/ChangeLog b/packages/io/serial/current/ChangeLog --- a/packages/io/serial/current/ChangeLog +++ b/packages/io/serial/current/ChangeLog @@ -1,3 +1,9 @@ +2005-06-27 Andrew Lunn + + * src/common/serial.c (serial_select): Swap the DSR locks and + mutex locks around to avoid deadlocks with the rest of the code + which uses this order. + 2005-06-17 Andreas Gaer * src/common/serial.c (serial_select): Lock DSRs inside diff --git a/packages/io/serial/current/src/common/serial.c b/packages/io/serial/current/src/common/serial.c --- a/packages/io/serial/current/src/common/serial.c +++ b/packages/io/serial/current/src/common/serial.c @@ -509,14 +509,14 @@ serial_select(cyg_io_handle_t handle, cy serial_channel *chan = (serial_channel *)t->priv; cyg_bool retval = false; - cyg_drv_dsr_lock(); // Avoid races - switch( which ) { case CYG_FREAD: { cbuf_t *cbuf = &chan->in_cbuf; + cyg_drv_mutex_lock(&cbuf->lock); + cyg_drv_dsr_lock(); // Avoid races // Check for data in the input buffer. If there is none, // register the select operation, otherwise return true. @@ -524,7 +524,9 @@ serial_select(cyg_io_handle_t handle, cy if( cbuf->nb == 0 ) cyg_selrecord( info, &cbuf->selinfo ); else retval = true; - cyg_drv_mutex_unlock(&cbuf->lock); + + cyg_drv_dsr_unlock(); + cyg_drv_mutex_unlock(&cbuf->lock); } break; @@ -533,10 +535,13 @@ serial_select(cyg_io_handle_t handle, cy // Check for space in the output buffer. If there is none, // register the select operation, otherwise return true. + int space ; cbuf_t *cbuf = &chan->out_cbuf; + cyg_drv_mutex_lock(&cbuf->lock); - - int space = cbuf->len - cbuf->nb; + cyg_drv_dsr_lock(); // Avoid races + + space = cbuf->len - cbuf->nb; #ifdef CYGPKG_IO_SERIAL_FLOW_CONTROL if ( (space < cbuf->low_water) || (chan->flow_desc.flags & CYG_SERIAL_FLOW_OUT_THROTTLED) ) @@ -546,7 +551,8 @@ serial_select(cyg_io_handle_t handle, cy cyg_selrecord( info, &cbuf->selinfo ); #endif else retval = true; - + + cyg_drv_dsr_unlock(); cyg_drv_mutex_unlock(&cbuf->lock); } break; @@ -554,8 +560,6 @@ serial_select(cyg_io_handle_t handle, cy case 0: // exceptions - none supported break; } - - cyg_drv_dsr_unlock(); return retval; #else