Boost logo

Boost :

From: Andrew J Bromage (ajb_at_[hidden])
Date: 2006-02-08 22:40:59


G'day Ion.

Ion Gaztañaga <igaztanaga <at> gmail.com> writes:

> I hope you can find to do a review, since it seems you have experience
> with memory mappings.

I hope so too. :-)

> If I understand this correctly, you want a class that can map more than
> a fragment of a file holding a single file descriptor, is that right?

Well... I want a way to do that, whether it's a single class or not.

When I first thought about it, the approach that I considered was to use
two classes. mmaped_file represents a file which has zero or more mmaped
regions, and mmaped_region which represents a single region. Off the top
of my head, something like this might be appropriate:

    class mmapped_file : private boost::noncopyable
    {
    public:
        /* A slightly richer set of access modes. If the operating system does
           not support some mode, the library should pick a mode that at least
           allows the required mode. (e.g. if the OS doesn't support write-only
           mode, read-write mode is an appropriate substitute since it allows
           writing. */
        typedef enum {
                  none_mode = 0x00, ro_mode = 0x01, wo_mode = 0x02, rw_mode =
0x03, access_mode_mask = 0xff
        } accessmode;

        /* Open a file, RAII style. Throws an exception on failure. */
        mmapped_file(const char* filename, accessmode mode);

        /* Closes the file. Does not throw. */
        ~mmapped_file();

        /* XXX Support for iterating through the mapped regions? */
    };

    class mmaped_region : private boost::noncopyable
    {
    public:
        /* Map a region from an mmaped_file. Throws an exception on failure. */
        mmaped_region(shared_ptr<mmaped_file>& file, fileoff_t offset,
                      size_t size, mmaped_file::accessmode mode);

        /* Unmap the region. Does not throw. */
        ~mmapped_region();

        /* Get the size of the mapped region. Does not throw. */
        std::size_t get_size() const;

        /* Get a pointer to the base of the mapped region. Does not throw. */
        void* get_base() const;

        /* Get the file offset of the beginning of the mapped region. Does not
throw. */
        fileoff_t get_file_offset() const;

        /* Flush an area of the mapped region. Does not throw. */
        bool flush(size_t mapping_offset = 0, size_t numbytes = 0);
    };

mmaped_region holds a shared_ptr to an mmaped_file, so that when the
last mapped region is destroyed, the file is closed (assuming someone
else isn't holding onto if, of course).

Cheers,
Andrew Bromage


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk