summaryrefslogtreecommitdiffstats
path: root/cpukit/libnetworking/rtems/rtems_syscall.c
diff options
context:
space:
mode:
authorSebastian Huber <sebastian.huber@embedded-brains.de>2020-03-10 17:07:19 +0100
committerSebastian Huber <sebastian.huber@embedded-brains.de>2020-03-13 09:57:04 +0100
commitc2287ba2cff59a50848151833404bce0e3cf0a70 (patch)
tree24fbd290baf4722b2dd56df731f44b41b6765c45 /cpukit/libnetworking/rtems/rtems_syscall.c
parentmrm332-testsuite.tcfg: Add dl01 (diff)
downloadrtems-c2287ba2cff59a50848151833404bce0e3cf0a70.tar.bz2
libio: Robust file descriptor reference counting
There was a race conditon in the reference counting of file descriptors during a close() operation. After the call to the close handler, the rtems_libio_free() function cleared the flags to zero. However, at this point in time there may still exist some holders of the file descriptor. With RTEMS_DEBUG enabled this could lead to failed assertions in rtems_libio_iop_drop(). Change the code to use only atomic read-modify-write operations on the rtems_libio_iop::flags.
Diffstat (limited to 'cpukit/libnetworking/rtems/rtems_syscall.c')
-rw-r--r--cpukit/libnetworking/rtems/rtems_syscall.c10
1 files changed, 7 insertions, 3 deletions
diff --git a/cpukit/libnetworking/rtems/rtems_syscall.c b/cpukit/libnetworking/rtems/rtems_syscall.c
index 5fa0e7d10c..56a8530564 100644
--- a/cpukit/libnetworking/rtems/rtems_syscall.c
+++ b/cpukit/libnetworking/rtems/rtems_syscall.c
@@ -87,7 +87,7 @@ rtems_bsdnet_makeFdForSocket (void *so)
iop->pathinfo.handlers = &socket_handlers;
iop->pathinfo.mt_entry = &rtems_filesystem_null_mt_entry;
rtems_filesystem_location_add_to_mt_entry(&iop->pathinfo);
- rtems_libio_iop_flags_initialize(iop, LIBIO_FLAGS_READ_WRITE);
+ rtems_libio_iop_flags_set(iop, LIBIO_FLAGS_OPEN | LIBIO_FLAGS_READ_WRITE);
return fd;
}
@@ -739,14 +739,18 @@ rtems_bsdnet_write (rtems_libio_t *iop, const void *buffer, size_t count)
static int
so_ioctl (rtems_libio_t *iop, struct socket *so, uint32_t command, void *buffer)
{
+ unsigned int nonblock;
+
switch (command) {
case FIONBIO:
+ nonblock = rtems_libio_fcntl_flags (O_NONBLOCK);
+
if (*(int *)buffer) {
- iop->flags |= O_NONBLOCK;
+ rtems_libio_iop_flags_set (iop, nonblock);
so->so_state |= SS_NBIO;
}
else {
- iop->flags &= ~O_NONBLOCK;
+ rtems_libio_iop_flags_clear (iop, nonblock);
so->so_state &= ~SS_NBIO;
}
return 0;