SCL  1.0
Standard Control Library : Control, dynamics, physics, and simulation
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Friends Macros Groups Pages
CSharedMemory.hpp
1 /* This file is part of sUtil, a random collection of utilities.
2 
3 sUtil is free software; you can redistribute it and/or
4 modify it under the terms of the GNU Lesser General Public
5 License as published by the Free Software Foundation; either
6 version 3 of the License, or (at your option) any later version.
7 
8 Alternatively, you can redistribute it and/or
9 modify it under the terms of the GNU General Public License as
10 published by the Free Software Foundation; either version 2 of
11 the License, or (at your option) any later version.
12 
13 sUtil is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
17 
18 You should have received a copy of the GNU Lesser General Public
19 License and a copy of the GNU General Public License along with
20 sUtil. If not, see <http://www.gnu.org/licenses/>.
21  */
22 /* \file CSharedMemory.hpp
23  *
24  * Created on: Sep 14, 2011
25  *
26  * Copyright (C) 2011, Samir Menon <smenon@stanford.edu>
27  */
28 
29 #ifndef CUNIXSHAREDMEMORY_HPP_
30 #define CUNIXSHAREDMEMORY_HPP_
31 
32 //Required for shared memory on Linux
33 #include <sys/ipc.h>
34 #include <sys/shm.h>
35 #include <sys/types.h>
36 
37 #include <stdio.h>
38 
39 namespace sutil
40 {
65  template<typename MemType, typename SignalType>
67  {
68  public:
69  CSharedMemory(const key_t& arg_shmem_key, const SignalType& arg_term_cond):
70  data_(0), data_signal_(0), data_terminate_(arg_term_cond),
71  key_(arg_shmem_key), has_been_init_(false) {}
72 
73  ~CSharedMemory(){}
74 
76  bool shmCreate()
77  {
78  //Don't grab another chunk of memory if already have one.
79  if(has_been_init_)
80  { return false; }
81 
82  //Get the shared memory {MemType, SignalType}. The SignalType is for signaling.
83  //IPC_CREAT creates the mem, and 0666 sets a+rw access
84  shmem_id_ = shmget(key_, sizeof(MemType)+sizeof(SignalType), IPC_CREAT | 0666);
85  if (shmem_id_ < 0)
86  {
87  perror("CSharedMemory::create() : Error: shmget could not create shared memory");
88  return false;
89  }
90 
91  //Attach the shared memory to a local variable
92  void* shmem = shmat(shmem_id_, NULL, 0);
93  //Returns "(void*) -1" on error
94  if(shmem == (void *) -1)
95  {
96  perror("CSharedMemory::create() : Error: shmat could not attach shared memory");
97  return false;
98  }
99 
100  data_signal_ = reinterpret_cast<SignalType*>(shmem);
101  data_ = reinterpret_cast<MemType*>(data_signal_+sizeof(SignalType));
102 
103  //Server initialized
104  has_been_init_ = true;
105 
106  return true;
107  }
108 
110  bool shmRead()
111  {
112  //Don't grab another chunk of memory if already have one.
113  if(has_been_init_)
114  { return false; }
115 
116  //Get the shared memory {MemType, SignalType}. The SignalType is for signaling.
117  //0666 sets a+rw access
118  shmem_id_ = shmget(key_, sizeof(MemType)+sizeof(SignalType), 0666);
119  if (shmem_id_ < 0)
120  {
121  perror("CSharedMemory::create() : Error: shmget could not create shared memory");
122  return false;
123  }
124 
125  //Attach the shared memory to a local variable
126  void* shmem = shmat(shmem_id_, NULL, 0);
127  //Returns "(void*) -1" on error
128  if(shmem == (void *) -1)
129  {
130  perror("CSharedMemory::create() : Error: shmat could not attach shared memory");
131  return false;
132  }
133 
134  data_signal_ = reinterpret_cast<SignalType*>(shmem);
135  data_ = reinterpret_cast<MemType*>(data_signal_+sizeof(SignalType));
136 
137  //Client initialized
138  has_been_init_ = true;
139 
140  return true;
141  }
142 
144  bool shmAlive()
145  {
146  if(has_been_init_)
147  { return (*data_signal_) != data_terminate_; }
148  return false;
149  }
150 
153  {
154  if(has_been_init_)
155  {
157  { return false; }
158 
159  if(0 != shmdt(reinterpret_cast<const void *>(data_signal_)))
160  {
161  perror("CSharedMemory::detach() : Error: shmat could not detach shared memory");
162  return false;
163  }
164 
165  has_been_init_ = false;
166  return true;
167  }
168  return false;
169  }
170 
172  bool shmDetach()
173  {
174  if(has_been_init_)
175  {
177 
178  if(0 != shmdt(reinterpret_cast<const void *>(data_signal_)))
179  {
180  perror("CSharedMemory::detach() : Error: shmat could not detach shared memory");
181  return false;
182  }
183 
184  has_been_init_ = false;
185  return true;
186  }
187  return false;
188  }
189 
190  public:
192  MemType *data_;
193 
195  SignalType *data_signal_;
196 
198  SignalType data_terminate_;
199 
200  private:
201  int shmem_id_;
202  key_t key_;
203  bool has_been_init_;
204  };
205 
206 }
207 
208 #endif /* CUNIXSHAREDMEMORY_HPP_ */
SignalType data_terminate_
Definition: CSharedMemory.hpp:198
bool shmCreate()
Definition: CSharedMemory.hpp:76
bool shmRead()
Definition: CSharedMemory.hpp:110
bool shmCheckDetach()
Definition: CSharedMemory.hpp:152
MemType * data_
Definition: CSharedMemory.hpp:192
bool shmAlive()
Definition: CSharedMemory.hpp:144
bool shmDetach()
Definition: CSharedMemory.hpp:172
Definition: CSharedMemory.hpp:66
SignalType * data_signal_
Definition: CSharedMemory.hpp:195