On Friday, 21 July 2017 16:26:20 PDT Alexander Zaitsev wrote:
> Hello.
>
> In 2006 Ion Gaztañaga (Boost.Interprocess and other great libraries author,
> email: igaztanaga at gmail dot com) wrote proposal about memory mapped
> files and shared memory for C++ (Document number: N2044=06-0114). But the
> proposal is forgotten now.
>
> I want to reborn it, because i think it's very important thing for C++.
>
> Please read the proposal and discuss about it.
Looks interesting, but falls short because it leaves extremely important
things out.
* needs an exception-free API
* Execute permissions are missing. Your classes support only as read-only,
read-write or invalid. But memory mapped objects have more flags, especially
the execute permission. In fact, the ability to *deny* execution is an
important security feature.
* "copy on write" is probably the wrong name for the "private" property. It's
unintuitive that it would apply to a read-only region, but it does. It
indicates whether you want to see changes made by other processes or not. I
advise changing the name back to "private" vs "shared".
* std::size_t may be the wrong type for the map size. It's valid for all
modern architectures, but in theory it just has to be wide enough to hold the
size of the biggest object. We may want instead to change the wording of this
type's definition (though note it's also in POSIX).
* Please update the address parameter to be nullptr, not 0, and update the
get_address() documentation. Do all OSes guarantee they will map where asked?
(We can probably safely assume that mapping at nullptr is not supported by the
C++ standard)
* For offset_t, you may want to use the filesystem API's offset type.
* For the flush() function, you need a way to explain whether it is needed or
not. Most memory mappings don't need it.
If you were thinking of msync(), then you're missing the arguments to that
function.
* I'm missing an equivalent of madvise() / posix_madvise()
* std::file_mapping needs a way to refer to an already-open file, without
needing to know its name (assuming it even has one). O_TMPFILE and memfd files
on Linux don't.
* what happens to the memory region if the std::file_mapping object is
destroyed? On one hand, RAII principles would say the mapping is undone; on
another, that's not how the low-level OS works and it's often useful to retain
a mapping forever, without having to keep a (polymorphic) object around that
will never, ever be used again.
* std::shared_memory_object needs to specify which type of shared memory it
is. On Unix systems, we have two: POSIX (sys/mman.h, shm_open()) and System V
(sys/shm.h, shmget()), with Linux having recently added a third (memfd). They
are completely disjoint namespaces and are identified differently.
* POSIX shared memory has the semantics of a file, including the access
permissions. Please merge with the filesystem API where they've looked into
that. I suspect Windows ones are similar.
* the System V shared memory uses a key_t object for identification, not a
"const char *name". You can use a simple narrow-character string, but you need
to provide an "int proj_id" so it can be passed through ftok(3).
* just like path names, on Windows shared memory segments are not narrow
characters. You need to provide a wchar_t overload for Windows.
* Using truncate() for growing is weird. I know the POSIX API does that, but
bad prior art is not good reason. What did the filesystem API choose? If given
the option, I'd recommend "resize".
* Please write something about what happens if you map a size larger than the
object's size. Our experience in Qt is that some systems allow this,
automatically growing the object that backs it, while others will just crash
your application. It's ok to write that it's implementation-defined, but you
need to write it.
* for that matter, please update the API with the ability to seal memory-
mappable objects. See
https://lwn.net/Articles/593918/,
http://man7.org/linux/man-pages/man2/memfd_create.2.html. This was added to
Linux specifically to avoid DoS attacks where processes of different privileges
are operating on the same shared memory object. Of course, implementation-
defined whether this is supported, but it's an important security feature we
should encourage application writers to use.
* you'll want to investigate cross-process thread signalling (semaphores) too.
Eventually, we'll need to discuss std::mutex on memory-mapped regions.
--
Thiago Macieira - thiago (AT)
macieira.info - thiago (AT)
kde.org
Software Architect - Intel Open Source Technology Center