Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-05-29 07:54:24

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