
This seems like a good seperation of the concepts (file vs. region) to me. Most of the higher level functionality in shmem could be built against the mmapped_region class. I definitely feel that this is a step in the right direction. Dave Moore 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); };