XRootD
XrdSysShmem.hh
Go to the documentation of this file.
1 //-----------------------------------------------------------------------------
2 // Copyright (c) 2013 by European Organization for Nuclear Research (CERN)
3 // Author: Michal Simon <michal.simon@cern.ch>
4 //-----------------------------------------------------------------------------
5 // This file is part of the XRootD software suite.
6 //
7 // XRootD is free software: you can redistribute it and/or modify
8 // it under the terms of the GNU Lesser General Public License as published by
9 // the Free Software Foundation, either version 3 of the License, or
10 // (at your option) any later version.
11 //
12 // XRootD is distributed in the hope that it will be useful,
13 // but WITHOUT ANY WARRANTY; without even the implied warranty of
14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 // GNU General Public License for more details.
16 //
17 // You should have received a copy of the GNU Lesser General Public License
18 // along with XRootD. If not, see <http://www.gnu.org/licenses/>.
19 //
20 // In applying this licence, CERN does not waive the privileges and immunities
21 // granted to it by virtue of its status as an Intergovernmental Organization
22 // or submit itself to any jurisdiction.
23 //-----------------------------------------------------------------------------
24 
25 #ifndef SRC_XRDSYS_XRDSYSSHMEM_HH_
26 #define SRC_XRDSYS_XRDSYSSHMEM_HH_
27 
28 #include <string>
29 #include <tuple>
30 
31 #include <sys/mman.h>
32 #include <sys/stat.h>
33 #include <fcntl.h>
34 #include <unistd.h>
35 
36 namespace XrdSys
37 {
38 
42  struct shm_error : public std::exception
43  {
44  shm_error( int errcode ) :
45  errcode( errcode ), errmsg( strerror( errcode )){ }
46 
47  const int errcode; //> errno
48  const std::string errmsg; //> error message
49  };
50 
54  struct shm
55  {
65  inline static std::tuple<void*, size_t> create( const std::string &name, size_t size )
66  {
67  int fd = shm_open( name.c_str(), O_CREAT | O_RDWR, 0600 );
68  if( fd < 0 )
69  throw shm_error( errno );
70  if( ftruncate( fd, size ) < 0 )
71  {
72  if( errno != EINVAL )
73  throw shm_error( errno );
74  }
75  struct stat statbuf;
76  if( fstat( fd, &statbuf ) < 0 )
77  throw shm_error( errno );
78  size = statbuf.st_size;
79  void *mem = map_shm( fd, size );
80  close( fd );
81  return std::make_tuple( mem, size );
82  }
83 
92  template<typename T>
93  inline static std::tuple<T*, size_t> get( const std::string &name )
94  {
95  int fd = shm_open( name.c_str(), O_RDWR, 0600 );
96  if( fd < 0 )
97  throw shm_error( errno );
98  struct stat statbuf;
99  if( fstat( fd, &statbuf ) < 0 )
100  throw shm_error( errno );
101  size_t size = statbuf.st_size;
102  void *mem = map_shm( fd, size );
103  close( fd );
104  return std::make_tuple( reinterpret_cast<T*>( mem ), size );
105  }
106 
118  template<typename T>
119  inline static std::tuple<T*, size_t> make_array( const std::string &name, size_t count )
120  {
121  auto tpl = create( name, count * sizeof( T ) );
122  T* arr = reinterpret_cast<T*>( std::get<0>( tpl ) );
123  size_t size = std::get<1>( tpl );
124  for( size_t i = 0; i < count; ++i )
125  new( arr + i ) T();
126  return std::make_tuple( arr, size );
127  }
128 
141  template<typename T, typename... Args>
142  inline static std::tuple<T*, size_t> make_array( const std::string &name, size_t count, Args&&... args )
143  {
144  auto tpl = create( name, count * sizeof( T ) );
145  T* arr = reinterpret_cast<T*>( std::get<0>( tpl ) );
146  size_t size = std::get<1>( tpl );
147  for( size_t i = 0; i < count; ++i )
148  new( arr + i ) T( std::forward<Args...>( args... ) );
149  return std::make_tuple( arr, size );
150  }
151 
152  private:
161  inline static void* map_shm( int fd, size_t size )
162  {
163  void *mem = mmap( nullptr, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0 );
164  if( mem == MAP_FAILED )
165  {
166  mem = nullptr;
167  throw shm_error( errno );
168  }
169  return mem;
170  }
171  };
172 }
173 
174 
175 
176 #endif /* SRC_XRDSYS_XRDSYSSHMEM_HH_ */
int stat(const char *path, struct stat *buf)
int ftruncate(int fildes, off_t offset)
int fstat(int fildes, struct stat *buf)
#define close(a)
Definition: XrdPosix.hh:43
shm_error(int errcode)
Definition: XrdSysShmem.hh:44
const int errcode
Definition: XrdSysShmem.hh:47
const std::string errmsg
Definition: XrdSysShmem.hh:48
static std::tuple< T *, size_t > make_array(const std::string &name, size_t count)
Definition: XrdSysShmem.hh:119
static std::tuple< void *, size_t > create(const std::string &name, size_t size)
Definition: XrdSysShmem.hh:65
static std::tuple< T *, size_t > get(const std::string &name)
Definition: XrdSysShmem.hh:93
static std::tuple< T *, size_t > make_array(const std::string &name, size_t count, Args &&... args)
Definition: XrdSysShmem.hh:142