diff options
author | Gedare Bloom <gedare@rtems.org> | 2017-03-15 14:31:00 -0400 |
---|---|---|
committer | Gedare Bloom <gedare@rtems.org> | 2017-05-05 10:34:08 -0400 |
commit | 87de70a2984cece87db94f4b445589c4e24e5c77 (patch) | |
tree | 945d211b09e3b7714a2bba6d06ceae7a601d4116 /cpukit/libcsupport/src/libio.c | |
parent | posix: Add mmap/unmap support for mapping files. (diff) | |
download | rtems-87de70a2984cece87db94f4b445589c4e24e5c77.tar.bz2 |
posix/mman: add mmap support for shm objects
Update #2859.
Diffstat (limited to 'cpukit/libcsupport/src/libio.c')
-rw-r--r-- | cpukit/libcsupport/src/libio.c | 32 |
1 files changed, 30 insertions, 2 deletions
diff --git a/cpukit/libcsupport/src/libio.c b/cpukit/libcsupport/src/libio.c index 22be6411a2..e89634f090 100644 --- a/cpukit/libcsupport/src/libio.c +++ b/cpukit/libcsupport/src/libio.c @@ -138,8 +138,36 @@ void rtems_libio_free( rtems_libio_lock(); iop->flags = 0; - iop->data1 = rtems_libio_iop_freelist; - rtems_libio_iop_freelist = iop; + /* If the mapping_refcnt is non-zero, the deferred free will be + * called by munmap. The iop is no longer good to use, but it cannot + * be recycled until the mapped file is unmapped. deferred free knows + * it can recycle the iop in case flags == 0 and iop->data1 == iop, + * since these two conditions are not otherwise satisifed at + * the same time. It may be possible that iop->data1 == iop when + * flags != 0 because data1 is private to the driver. However, flags == 0 + * means a freed iop, and an iop on the freelist cannot store a pointer + * to itself in data1, or else the freelist is corrupted. We can't use + * NULL in data1 as an indicator because it is used by the tail of the + * freelist. */ + if ( iop->mapping_refcnt == 0 ) { + iop->data1 = rtems_libio_iop_freelist; + rtems_libio_iop_freelist = iop; + } else { + iop->data1 = iop; + } rtems_libio_unlock(); } + +void rtems_libio_check_deferred_free( + rtems_libio_t *iop +) +{ + rtems_libio_lock(); + if ( iop->mapping_refcnt == 0 && iop->flags == 0 && iop->data1 == iop) { + /* No mappings and rtems_libio_free already called, recycle the iop */ + iop->data1 = rtems_libio_iop_freelist; + rtems_libio_iop_freelist = iop; + } + rtems_libio_unlock(); +} |