Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-30 09:44:13

0001 //////////////////////////////////////////////////////////////////////////////
0002 //
0003 // (C) Copyright Ion Gaztanaga 2005-2012. Distributed under the Boost
0004 // Software License, Version 1.0. (See accompanying file
0005 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
0006 //
0007 // See http://www.boost.org/libs/interprocess for documentation.
0008 //
0009 //////////////////////////////////////////////////////////////////////////////
0010 
0011 #ifndef BOOST_INTERPROCESS_WINDOWS_SHARED_MEMORY_HPP
0012 #define BOOST_INTERPROCESS_WINDOWS_SHARED_MEMORY_HPP
0013 
0014 #ifndef BOOST_CONFIG_HPP
0015 #  include <boost/config.hpp>
0016 #endif
0017 #
0018 #if defined(BOOST_HAS_PRAGMA_ONCE)
0019 #  pragma once
0020 #endif
0021 
0022 #include <boost/interprocess/detail/config_begin.hpp>
0023 #include <boost/interprocess/detail/workaround.hpp>
0024 
0025 #include <boost/interprocess/permissions.hpp>
0026 #include <boost/interprocess/detail/simple_swap.hpp>
0027 #include <boost/interprocess/detail/char_wchar_holder.hpp>
0028 
0029 #if !defined(BOOST_INTERPROCESS_WINDOWS)
0030 #error "This header can only be used in Windows operating systems"
0031 #endif
0032 
0033 #include <boost/interprocess/creation_tags.hpp>
0034 #include <boost/interprocess/exceptions.hpp>
0035 #include <boost/interprocess/detail/utilities.hpp>
0036 #include <boost/interprocess/detail/os_file_functions.hpp>
0037 #include <boost/interprocess/interprocess_fwd.hpp>
0038 #include <boost/interprocess/exceptions.hpp>
0039 #include <boost/interprocess/detail/win32_api.hpp>
0040 #include <cstddef>
0041 #include <boost/cstdint.hpp>
0042 
0043 
0044 //!\file
0045 //!Describes a class representing a native windows shared memory.
0046 
0047 namespace boost {
0048 namespace interprocess {
0049 
0050 //!A class that wraps the native Windows shared memory
0051 //!that is implemented as a file mapping of the paging file.
0052 //!Unlike shared_memory_object, windows_shared_memory has
0053 //!no kernel persistence and the shared memory is destroyed
0054 //!when all processes destroy all their windows_shared_memory
0055 //!objects and mapped regions for the same shared memory
0056 //!or the processes end/crash.
0057 //!
0058 //!Warning: Windows native shared memory and interprocess portable
0059 //!shared memory (boost::interprocess::shared_memory_object)
0060 //!can't communicate between them.
0061 class windows_shared_memory
0062 {
0063    #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
0064    //Non-copyable and non-assignable
0065    BOOST_MOVABLE_BUT_NOT_COPYABLE(windows_shared_memory)
0066    #endif   //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
0067 
0068    public:
0069    //!Default constructor.
0070    //!Represents an empty windows_shared_memory.
0071    windows_shared_memory() BOOST_NOEXCEPT;
0072 
0073    //!Creates a new native shared memory with name "name" and at least size "size",
0074    //!with the access mode "mode".
0075    //!If the file previously exists, throws an error.
0076    windows_shared_memory(create_only_t, const char *name, mode_t mode, std::size_t size, const permissions& perm = permissions())
0077    {  this->priv_open_or_create(ipcdetail::DoCreate, name, mode, size, perm);  }
0078 
0079    //!Tries to create a shared memory object with name "name" and at least size "size", with the
0080    //!access mode "mode". If the file previously exists, it tries to open it with mode "mode".
0081    //!Otherwise throws an error.
0082    windows_shared_memory(open_or_create_t, const char *name, mode_t mode, std::size_t size, const permissions& perm = permissions())
0083    {  this->priv_open_or_create(ipcdetail::DoOpenOrCreate, name, mode, size, perm);  }
0084 
0085    //!Tries to open a shared memory object with name "name", with the access mode "mode".
0086    //!If the file does not previously exist, it throws an error.
0087    windows_shared_memory(open_only_t, const char *name, mode_t mode)
0088    {  this->priv_open_or_create(ipcdetail::DoOpen, name, mode, 0, permissions());  }
0089 
0090    //!Creates a new native shared memory with name "name" and at least size "size",
0091    //!with the access mode "mode".
0092    //!If the file previously exists, throws an error.
0093    windows_shared_memory(create_only_t, const wchar_t *name, mode_t mode, std::size_t size, const permissions& perm = permissions())
0094    {  this->priv_open_or_create(ipcdetail::DoCreate, name, mode, size, perm);  }
0095 
0096    //!Tries to create a shared memory object with name "name" and at least size "size", with the
0097    //!access mode "mode". If the file previously exists, it tries to open it with mode "mode".
0098    //!Otherwise throws an error.
0099    windows_shared_memory(open_or_create_t, const wchar_t *name, mode_t mode, std::size_t size, const permissions& perm = permissions())
0100    {  this->priv_open_or_create(ipcdetail::DoOpenOrCreate, name, mode, size, perm);  }
0101 
0102    //!Tries to open a shared memory object with name "name", with the access mode "mode".
0103    //!If the file does not previously exist, it throws an error.
0104    windows_shared_memory(open_only_t, const wchar_t *name, mode_t mode)
0105    {  this->priv_open_or_create(ipcdetail::DoOpen, name, mode, 0, permissions());  }
0106 
0107    //!Moves the ownership of "moved"'s shared memory object to *this.
0108    //!After the call, "moved" does not represent any shared memory object.
0109    //!Does not throw
0110    windows_shared_memory(BOOST_RV_REF(windows_shared_memory) moved) BOOST_NOEXCEPT
0111       : m_handle(0)
0112    {  this->swap(moved);   }
0113 
0114    //!Moves the ownership of "moved"'s shared memory to *this.
0115    //!After the call, "moved" does not represent any shared memory.
0116    //!Does not throw
0117    windows_shared_memory &operator=(BOOST_RV_REF(windows_shared_memory) moved) BOOST_NOEXCEPT
0118    {
0119       windows_shared_memory tmp(boost::move(moved));
0120       this->swap(tmp);
0121       return *this;
0122    }
0123 
0124    //!Swaps to shared_memory_objects. Does not throw
0125    void swap(windows_shared_memory &other) BOOST_NOEXCEPT;
0126 
0127    //!Destroys *this. All mapped regions are still valid after
0128    //!destruction. When all mapped regions and windows_shared_memory
0129    //!objects referring the shared memory are destroyed, the
0130    //!operating system will destroy the shared memory.
0131    ~windows_shared_memory();
0132 
0133    //!Returns the name of the shared memory.
0134    const char *get_name() const BOOST_NOEXCEPT;
0135 
0136    //!Returns access mode
0137    mode_t get_mode() const BOOST_NOEXCEPT;
0138 
0139    //!Returns the mapping handle. Never throws
0140    mapping_handle_t get_mapping_handle() const BOOST_NOEXCEPT;
0141 
0142    //!Returns the size of the windows shared memory. It will be a 4K rounded
0143    //!size of the "size" passed in the constructor.
0144    offset_t get_size() const BOOST_NOEXCEPT;
0145 
0146    #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
0147    private:
0148 
0149    //!Closes a previously opened file mapping. Never throws.
0150    void priv_close();
0151 
0152    //!Closes a previously opened file mapping. Never throws.
0153    template <class CharT>
0154    bool priv_open_or_create(ipcdetail::create_enum_t type, const CharT *filename, mode_t mode, std::size_t size, const permissions& perm = permissions());
0155 
0156    void *         m_handle;
0157    mode_t         m_mode;
0158    char_wchar_holder m_name;
0159    #endif   //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
0160 };
0161 
0162 #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
0163 
0164 inline windows_shared_memory::windows_shared_memory() BOOST_NOEXCEPT
0165    :  m_handle(0)
0166 {}
0167 
0168 inline windows_shared_memory::~windows_shared_memory()
0169 {  this->priv_close(); }
0170 
0171 inline const char *windows_shared_memory::get_name() const BOOST_NOEXCEPT
0172 {  return m_name.getn(); }
0173 
0174 inline void windows_shared_memory::swap(windows_shared_memory &other) BOOST_NOEXCEPT
0175 {
0176    (simple_swap)(m_handle,  other.m_handle);
0177    (simple_swap)(m_mode,    other.m_mode);
0178    m_name.swap(other.m_name);
0179 }
0180 
0181 inline mapping_handle_t windows_shared_memory::get_mapping_handle() const BOOST_NOEXCEPT
0182 {  mapping_handle_t mhnd = { m_handle, true};   return mhnd;   }
0183 
0184 inline mode_t windows_shared_memory::get_mode() const BOOST_NOEXCEPT
0185 {  return m_mode; }
0186 
0187 inline offset_t windows_shared_memory::get_size() const BOOST_NOEXCEPT
0188 {
0189    offset_t size; //This shall never fail
0190    return (m_handle && winapi::get_file_mapping_size(m_handle, size)) ? size : 0;
0191 }
0192 
0193 template <class CharT>
0194 inline bool windows_shared_memory::priv_open_or_create
0195    (ipcdetail::create_enum_t type, const CharT *filename, mode_t mode, std::size_t size, const permissions& perm)
0196 {
0197    if (filename){
0198       m_name = filename;
0199    }
0200    else{
0201       m_name = "";
0202    }
0203 
0204    unsigned long protection = 0;
0205    unsigned long map_access = 0;
0206 
0207    switch(mode)
0208    {
0209       //"protection" is for "create_file_mapping"
0210       //"map_access" is for "open_file_mapping"
0211       //Add section query (strange that read or access does not grant it...)
0212       //to obtain the size of the mapping. copy_on_write is equal to section_query.
0213       case read_only:
0214          protection   |= winapi::page_readonly;
0215          map_access   |= winapi::file_map_read | winapi::section_query;
0216       break;
0217       case read_write:
0218          protection   |= winapi::page_readwrite;
0219          map_access   |= winapi::file_map_write | winapi::section_query;
0220       break;
0221       case copy_on_write:
0222          protection   |= winapi::page_writecopy;
0223          map_access   |= winapi::file_map_copy;
0224       break;
0225       default:
0226          {
0227             error_info err(mode_error);
0228             throw interprocess_exception(err);
0229          }
0230       break;
0231    }
0232 
0233    switch(type){
0234       case ipcdetail::DoOpen:
0235          m_handle = winapi::open_file_mapping(map_access, filename);
0236       break;
0237       case ipcdetail::DoCreate:
0238       case ipcdetail::DoOpenOrCreate:
0239       {
0240          m_handle = winapi::create_file_mapping
0241             ( winapi::invalid_handle_value, protection, size, filename
0242             , (winapi::interprocess_security_attributes*)perm.get_permissions());
0243       }
0244       break;
0245       default:
0246          {
0247             error_info err = other_error;
0248             throw interprocess_exception(err);
0249          }
0250    }
0251 
0252    if(!m_handle || (type == ipcdetail::DoCreate && winapi::get_last_error() == winapi::error_already_exists)){
0253       error_info err = system_error_code();
0254       this->priv_close();
0255       throw interprocess_exception(err);
0256    }
0257 
0258    m_mode = mode;
0259    return true;
0260 }
0261 
0262 inline void windows_shared_memory::priv_close()
0263 {
0264    if(m_handle){
0265       winapi::close_handle(m_handle);
0266       m_handle = 0;
0267    }
0268 }
0269 
0270 #endif   //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
0271 
0272 }  //namespace interprocess {
0273 }  //namespace boost {
0274 
0275 #include <boost/interprocess/detail/config_end.hpp>
0276 
0277 #endif   //BOOST_INTERPROCESS_WINDOWS_SHARED_MEMORY_HPP