mirror of
https://gitlab.rtems.org/rtems/rtos/rtems.git
synced 2025-12-05 23:23:13 +00:00
cpukit/close.c: Open flag corrected for busy closes
Fix closing while busy. Previously open flag in the iop would be unset despite close returning EBUSY. Updates #5311
This commit is contained in:
@@ -45,7 +45,6 @@ int close(
|
|||||||
)
|
)
|
||||||
{
|
{
|
||||||
rtems_libio_t *iop;
|
rtems_libio_t *iop;
|
||||||
unsigned int flags;
|
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
if ( (uint32_t) fd >= rtems_libio_number_iops ) {
|
if ( (uint32_t) fd >= rtems_libio_number_iops ) {
|
||||||
@@ -53,17 +52,28 @@ int close(
|
|||||||
}
|
}
|
||||||
|
|
||||||
LIBIO_GET_IOP( fd, iop );
|
LIBIO_GET_IOP( fd, iop );
|
||||||
flags = rtems_libio_iop_flags( iop );
|
|
||||||
|
|
||||||
while ( true ) {
|
while ( true ) {
|
||||||
|
unsigned int flags;
|
||||||
unsigned int desired;
|
unsigned int desired;
|
||||||
bool success;
|
bool success;
|
||||||
|
flags = rtems_libio_iop_flags( iop );
|
||||||
|
|
||||||
if ( ( flags & LIBIO_FLAGS_OPEN ) == 0 ) {
|
if ( ( flags & LIBIO_FLAGS_OPEN ) == 0 ) {
|
||||||
rtems_libio_iop_drop( iop );
|
rtems_libio_iop_drop( iop );
|
||||||
rtems_set_errno_and_return_minus_one( EBADF );
|
rtems_set_errno_and_return_minus_one( EBADF );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* When LIBIO_FLAGS_CLOSE_BUSY is not set check that only one reference
|
||||||
|
* is held to prevent closing while busy. Otherwise atomically check that
|
||||||
|
* the flags match to ensure the reference count is maintained.
|
||||||
|
*/
|
||||||
|
if ( ( flags & LIBIO_FLAGS_CLOSE_BUSY ) == 0 ) {
|
||||||
|
flags &= LIBIO_FLAGS_FLAGS_MASK;
|
||||||
|
flags |= LIBIO_FLAGS_REFERENCE_INC;
|
||||||
|
}
|
||||||
|
|
||||||
desired = flags & ~LIBIO_FLAGS_OPEN;
|
desired = flags & ~LIBIO_FLAGS_OPEN;
|
||||||
success = _Atomic_Compare_exchange_uint(
|
success = _Atomic_Compare_exchange_uint(
|
||||||
&iop->flags,
|
&iop->flags,
|
||||||
|
|||||||
Reference in New Issue
Block a user