diff --git a/cpukit/libcsupport/src/libio.c b/cpukit/libcsupport/src/libio.c index 0a0c238d43..0d4525eb8a 100644 --- a/cpukit/libcsupport/src/libio.c +++ b/cpukit/libcsupport/src/libio.c @@ -156,10 +156,15 @@ void rtems_libio_free_iop( ) { size_t zero; + unsigned int flags; - rtems_libio_lock(); - - if ( !rtems_libio_iop_is_free( iop ) ) { + /* + * Use atomic test and set so the contents of the if statement + * can only be run once. Therefore only added to the free list once. + */ + flags = rtems_libio_iop_flags_set( iop, LIBIO_FLAGS_FREE ); + if ( ( flags & LIBIO_FLAGS_FREE ) == 0 ) { + rtems_libio_lock(); /* * Clear the flags. All references should have been dropped. */ @@ -176,9 +181,8 @@ void rtems_libio_free_iop( */ *rtems_libio_iop_free_tail = iop; rtems_libio_iop_free_tail = &iop->data1; + rtems_libio_unlock(); } - - rtems_libio_unlock(); } int rtems_libio_count_open_iops(