Index: io/serial/current/ChangeLog =================================================================== RCS file: /cvs/ecos/ecos/packages/io/serial/current/ChangeLog,v retrieving revision 1.62 diff -u -r1.62 ChangeLog --- io/serial/current/ChangeLog 20 Jun 2005 18:23:29 -0000 1.62 +++ io/serial/current/ChangeLog 27 Jun 2005 19:51:55 -0000 @@ -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 Index: io/serial/current/src/common/serial.c =================================================================== RCS file: /cvs/ecos/ecos/packages/io/serial/current/src/common/serial.c,v retrieving revision 1.27 diff -u -r1.27 serial.c --- io/serial/current/src/common/serial.c 20 Jun 2005 18:15:00 -0000 1.27 +++ io/serial/current/src/common/serial.c 27 Jun 2005 19:51:56 -0000 @@ -508,15 +508,15 @@ cyg_devtab_entry_t *t = (cyg_devtab_entry_t *)handle; serial_channel *chan = (serial_channel *)t->priv; cyg_bool retval = false; + cbuf_t *cbuf = &chan->in_cbuf; - cyg_drv_dsr_lock(); // Avoid races + cyg_drv_mutex_lock(&cbuf->lock); 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,8 @@ if( cbuf->nb == 0 ) cyg_selrecord( info, &cbuf->selinfo ); else retval = true; - cyg_drv_mutex_unlock(&cbuf->lock); + + cyg_drv_dsr_unlock(); } break; @@ -533,10 +534,11 @@ // Check for space in the output buffer. If there is none, // register the select operation, otherwise return true. - cbuf_t *cbuf = &chan->out_cbuf; - cyg_drv_mutex_lock(&cbuf->lock); + int space ; - 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,8 +548,9 @@ cyg_selrecord( info, &cbuf->selinfo ); #endif else retval = true; - - cyg_drv_mutex_unlock(&cbuf->lock); + + cyg_drv_dsr_unlock(); + } break; @@ -555,7 +558,7 @@ break; } - cyg_drv_dsr_unlock(); + cyg_drv_mutex_unlock(&cbuf->lock); return retval; #else