VideoTools
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
gsharedmemory.h
Go to the documentation of this file.
1 //
2 // Copyright (C) 2017 Graeme Walker
3 //
4 // This program is free software: you can redistribute it and/or modify
5 // it under the terms of the GNU General Public License as published by
6 // the Free Software Foundation, either version 3 of the License, or
7 // (at your option) any later version.
8 //
9 // This program is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU General Public License for more details.
13 //
14 // You should have received a copy of the GNU General Public License
15 // along with this program. If not, see <http://www.gnu.org/licenses/>.
16 // ===
17 ///
18 /// \file gsharedmemory.h
19 ///
20 
21 #ifndef G_SHARED_MEMORY__H
22 #define G_SHARED_MEMORY__H
23 
24 #include "gdef.h"
25 #include "gsignalsafe.h"
26 #include "gexception.h"
27 #include <string>
28 #include <vector>
29 
30 namespace G
31 {
32  class SharedMemory ;
33 }
34 
35 /// \class G::SharedMemory
36 /// A POSIX shared memory class. Anonymous shared memory can be inherited across
37 /// a fork(); shared memory associated with an open file descriptor can be
38 /// inherited across a fork() and exec(); and shared memory associated with
39 /// a filesystem path can be shared freely by name.
40 ///
42 {
43 public:
44  G_EXCEPTION( Error , "shared memory error" ) ;
45  struct Control /// Overload discriminator for G::SharedMemory
46  {} ;
47 
48  explicit SharedMemory( size_t size ) ;
49  ///< Constructor for a new anonymous segment, typically used across
50  ///< a fork().
51 
52  explicit SharedMemory( int fd ) ;
53  ///< Constructor for a segment inherited via a file descriptor,
54  ///< typically across fork()/exec(). The file is closed by the
55  ///< destructor. See also: inherit(), fd()
56 
57  explicit SharedMemory( const std::string & name ) ;
58  ///< Constructor for an existing named segment. Throws if
59  ///< it does not exist.
60 
61  SharedMemory( const std::string & name , size_t size ) ;
62  ///< Constructor for a new named segment. Throws if it already
63  ///< exists. The destructor will call unlink().
64 
65  SharedMemory( size_t size , Control ) ;
66  ///< Constructor overload for control segments that might
67  ///< contain semaphores.
68 
69  SharedMemory( int fd , Control ) ;
70  ///< Constructor overload for control segments that might
71  ///< contain semaphores.
72 
73  SharedMemory( const std::string & name , Control ) ;
74  ///< Constructor overload for control segments that might
75  ///< contain semaphores.
76 
77  SharedMemory( const std::string & name , size_t size , Control ) ;
78  ///< Constructor overload for control segments that might
79  ///< contain semaphores.
80 
81  ~SharedMemory() ;
82  ///< Destructor. The memory is unmapped and, where relevant,
83  ///< the newly-created named segment is unlink()ed.
84 
85  size_t size() const ;
86  ///< Returns the segment size. This is affected by remap().
87 
88  void unlink() ;
89  ///< Unlinks the segment from the filesystem. Typically
90  ///< used for early cleanup when doing fork()/exec().
91  ///< Does not throw.
92 
93  static std::string delete_( const std::string & name , bool control_segment ) ;
94  ///< Unlinks the segment from the filesystem. Typically
95  ///< used administratively, especially on BSD. Returns a
96  ///< failure reason, or the empty string on success.
97 
98  static void cleanup( SignalSafe , const char * os_name , void (*fn)(SignalSafe,void*) ) ;
99  ///< An exit handler that unlinks the named shared memory segment
100  ///< and calls the user's function for the memory contents. Use
101  ///< osName() for the segment name.
102 
103  static void trap( SignalSafe , const char * os_name , void (*fn)(SignalSafe,void*) ) ;
104  ///< An exit handler that calls the user's function on the shared
105  ///< memory contents. Use osName() for the segment name.
106 
107  static std::string osName( const std::string & name ) ;
108  ///< Converts the segment name to an internal form that can be
109  ///< passed to cleanup() or trap().
110 
111  int fd() const ;
112  ///< Returns the file descriptor. Returns -1 for anonymous segments.
113 
114  void inherit() ;
115  ///< Marks fd() as inherited across exec() ie. no-close-on-exec.
116 
117  void * ptr() const ;
118  ///< Returns the mapped address.
119 
120  bool remap( size_t , bool may_move , bool no_throw = false ) ;
121  ///< Resizes and remaps the shared memory. Addresses may change if 'may_move'
122  ///< is true, but when false resizing will be less likely to succeed.
123  ///< Throws or returns false on error depending on 'no_throw'.
124  ///< Do not use this if there are semaphores inside the shared
125  ///< memory.
126 
127  static void help( const std::string & ) ;
128  ///< Sets some error-message help text for the case when named shared memory
129  ///< cannot be created because it already exists.
130 
131  static void prefix( const std::string & ) ;
132  ///< Sets a prefix for shared memory names, used by osName(). This method
133  ///< has to be called early and consistently (if called at all) in all
134  ///< cooperating programs. Does nothing if the prefix starts with a
135  ///< double-underscore.
136 
137  static std::string prefix() ;
138  ///< Returns the prefix, as set by by a call to the other overload.
139 
140  static void filetext( const std::string & ) ;
141  ///< Sets some help text that gets written into the placeholder files.
142 
143  static std::vector<std::string> list( bool os_names = false ) ;
144  ///< Returns a list of possible control segment names.
145 
146 private:
147  struct Imp
148  {
149  Imp() ;
150  ~Imp() ;
151  int fd() const ;
152  void swap( Imp & ) ;
153  void unlink() ;
154  //
155  std::string m_unlink_name ;
156  int m_fd ;
157  void * m_p ;
158  size_t m_size ;
159  //
160  private: Imp( const Imp & ) ;
161  private: void operator=( const Imp & ) ;
162  } ;
163 
164 private:
165  SharedMemory( const SharedMemory & ) ;
166  void operator=( const SharedMemory & ) ;
167  void init( const std::string & , int , size_t , int , bool ) ;
168  static void createMarker( const std::string & ) ;
169  static void deleteMarker( const std::string & ) ;
170  static void deleteMarker( SignalSafe , const char * ) ;
171  static void listImp( std::vector<std::string> & , const std::string & , const std::string & , bool ) ;
172 
173 private:
174  Imp m_imp ;
175 } ;
176 
177 #endif
void * ptr() const
Returns the mapped address.
static void help(const std::string &)
Sets some error-message help text for the case when named shared memory cannot be created because it ...
An empty structure that is used to indicate a signal-safe, reentrant implementation.
Definition: gsignalsafe.h:36
static std::string prefix()
Returns the prefix, as set by by a call to the other overload.
void inherit()
Marks fd() as inherited across exec() ie. no-close-on-exec.
static std::string delete_(const std::string &name, bool control_segment)
Unlinks the segment from the filesystem.
static std::vector< std::string > list(bool os_names=false)
Returns a list of possible control segment names.
int fd() const
Returns the file descriptor. Returns -1 for anonymous segments.
Overload discriminator for G::SharedMemory.
Definition: gsharedmemory.h:45
~SharedMemory()
Destructor.
bool remap(size_t, bool may_move, bool no_throw=false)
Resizes and remaps the shared memory.
static void trap(SignalSafe, const char *os_name, void(*fn)(SignalSafe, void *))
An exit handler that calls the user's function on the shared memory contents.
A POSIX shared memory class.
Definition: gsharedmemory.h:41
SharedMemory(size_t size)
Constructor for a new anonymous segment, typically used across a fork().
void unlink()
Unlinks the segment from the filesystem.
static void cleanup(SignalSafe, const char *os_name, void(*fn)(SignalSafe, void *))
An exit handler that unlinks the named shared memory segment and calls the user's function for the me...
static std::string osName(const std::string &name)
Converts the segment name to an internal form that can be passed to cleanup() or trap().
static void filetext(const std::string &)
Sets some help text that gets written into the placeholder files.
size_t size() const
Returns the segment size. This is affected by remap().