#include <Shared_Memory_Pool.h>
Inheritance diagram for ACE_Shared_Memory_Pool:
Public Types | |
typedef ACE_Shared_Memory_Pool_Options | OPTIONS |
Public Member Functions | |
ACE_Shared_Memory_Pool (const ACE_TCHAR *backing_store_name=0, const OPTIONS *options=0) | |
Initialize the pool. | |
virtual | ~ACE_Shared_Memory_Pool (void) |
virtual void * | init_acquire (size_t nbytes, size_t &rounded_bytes, int &first_time) |
Ask system for initial chunk of local memory. | |
virtual void * | acquire (size_t nbytes, size_t &rounded_bytes) |
virtual int | release (int destroy=1) |
Instruct the memory pool to release all of its resources. | |
virtual int | sync (ssize_t len=-1, int flags=MS_SYNC) |
virtual int | sync (void *addr, size_t len, int flags=MS_SYNC) |
Sync the memory region to the backing store starting at addr. | |
virtual int | protect (ssize_t len=-1, int prot=PROT_RDWR) |
virtual int | protect (void *addr, size_t len, int prot=PROT_RDWR) |
virtual void * | base_addr (void) const |
virtual void | dump (void) const |
Dump the state of an object. | |
Public Attributes | |
ACE_ALLOC_HOOK_DECLARE | |
Declare the dynamic allocation hooks. | |
Protected Member Functions | |
virtual size_t | round_up (size_t nbytes) |
virtual int | commit_backing_store_name (size_t rounded_bytes, ACE_OFF_T &offset) |
virtual int | find_seg (const void *const searchPtr, ACE_OFF_T &offset, size_t &counter) |
Find the segment that contains the searchPtr. | |
virtual int | in_use (ACE_OFF_T &offset, size_t &counter) |
Determine how much memory is currently in use. | |
virtual int | handle_signal (int signum, siginfo_t *, ucontext_t *) |
Protected Attributes | |
void * | base_addr_ |
size_t | file_perms_ |
File permissions to use when creating/opening a segment. | |
size_t | max_segments_ |
Number of shared memory segments in the table. | |
ACE_OFF_T | minimum_bytes_ |
What the minimim bytes of the initial segment should be. | |
size_t | segment_size_ |
Shared memory segment size. | |
key_t | base_shm_key_ |
Base shared memory key for the segment. | |
ACE_Sig_Handler | signal_handler_ |
Handles SIGSEGV. |
Definition at line 82 of file Shared_Memory_Pool.h.
|
Definition at line 85 of file Shared_Memory_Pool.h. |
|
Initialize the pool.
Definition at line 228 of file Shared_Memory_Pool.cpp. References ACE_DEFAULT_FILE_PERMS, ACE_DEFAULT_MAX_SEGMENTS, ACE_DEFAULT_SEGMENT_SIZE, ACE_DEFAULT_SHM_KEY, ACE_ERROR, ACE_TCHAR, ACE_TEXT, ACE_TEXT_ALWAYS_CHAR, ACE_TRACE, base_shm_key_, ACE::crc32(), IPC_PRIVATE, LM_ERROR, ACE_Sig_Handler::register_handler(), and SIGSEGV.
00231 : base_addr_ (0), 00232 file_perms_ (ACE_DEFAULT_FILE_PERMS), 00233 max_segments_ (ACE_DEFAULT_MAX_SEGMENTS), 00234 minimum_bytes_ (0), 00235 segment_size_ (ACE_DEFAULT_SEGMENT_SIZE) 00236 { 00237 ACE_TRACE ("ACE_Shared_Memory_Pool::ACE_Shared_Memory_Pool"); 00238 00239 // Only change the defaults if <options> != 0. 00240 if (options) 00241 { 00242 this->base_addr_ = 00243 reinterpret_cast<void *> (const_cast<char *> (options->base_addr_)); 00244 this->max_segments_ = options->max_segments_; 00245 this->file_perms_ = options->file_perms_; 00246 this->minimum_bytes_ = options->minimum_bytes_; 00247 this->segment_size_ = options->segment_size_; 00248 } 00249 00250 if (backing_store_name) 00251 { 00252 // Convert the string into a number that is used as the segment 00253 // key. 00254 00255 int segment_key; 00256 int result = ::sscanf (ACE_TEXT_ALWAYS_CHAR (backing_store_name), 00257 "%d", 00258 &segment_key); 00259 00260 if (result == 0 || result == EOF) 00261 // The conversion to a number failed so hash with crc32 00262 // ACE::crc32 is also used in <SV_Semaphore_Simple>. 00263 this->base_shm_key_ = 00264 (key_t) ACE::crc32 (ACE_TEXT_ALWAYS_CHAR (backing_store_name)); 00265 else 00266 this->base_shm_key_ = segment_key; 00267 00268 if (this->base_shm_key_ == IPC_PRIVATE) 00269 // Make sure that the segment can be shared between unrelated 00270 // processes. 00271 this->base_shm_key_ = ACE_DEFAULT_SHM_KEY; 00272 } 00273 else 00274 this->base_shm_key_ = ACE_DEFAULT_SHM_KEY; 00275 00276 if (this->signal_handler_.register_handler (SIGSEGV, this) == -1) 00277 ACE_ERROR ((LM_ERROR, 00278 ACE_TEXT ("%p\n"), 00279 ACE_TEXT ("ACE_Sig_Handler::register_handler"))); 00280 } |
|
Definition at line 282 of file Shared_Memory_Pool.cpp.
00283 { 00284 } |
|
Acquire at least nbytes from the memory pool. rounded_byes is the actual number of bytes allocated. Also acquires an internal semaphore that ensures proper serialization of Memory_Pool initialization across processes. Definition at line 289 of file Shared_Memory_Pool.cpp. References ACE_OFF_T, ACE_TRACE, commit_backing_store_name(), and round_up().
00291 { 00292 ACE_TRACE ("ACE_Shared_Memory_Pool::acquire"); 00293 00294 rounded_bytes = this->round_up (nbytes); 00295 00296 // ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("(%P|%t) acquiring more chunks, nbytes = %d, rounded_bytes = %d\n"), nbytes, rounded_bytes)); 00297 00298 ACE_OFF_T offset; 00299 00300 if (this->commit_backing_store_name (rounded_bytes, offset) == -1) 00301 return 0; 00302 00303 // ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("(%P|%t) acquired more chunks, nbytes = %d, rounded_bytes = %d\n"), nbytes, rounded_bytes)); 00304 return ((char *) this->base_addr_) + offset; 00305 } |
|
Return the base address of this memory pool, 0 if base_addr never changes. Definition at line 440 of file Shared_Memory_Pool.cpp. References ACE_TRACE.
00441 { 00442 ACE_TRACE ("ACE_Shared_Memory_Pool::base_addr"); 00443 return this->base_addr_; 00444 } |
|
Commits a new shared memory segment if necessary after an or a signal. is set to the new offset into the backing store. Definition at line 100 of file Shared_Memory_Pool.cpp. References ACE_ERROR_RETURN, ACE_OFF_T, ACE_TEXT, ACE_TRACE, in_use(), IPC_CREAT, IPC_EXCL, LM_ERROR, ACE_OS::shmat(), ACE_OS::shmget(), ACE_Shared_Memory_Pool::SHM_TABLE::shmid_, and ACE_Shared_Memory_Pool::SHM_TABLE::used_. Referenced by acquire().
00102 { 00103 ACE_TRACE ("ACE_Shared_Memory_Pool::commit_backing_store_name"); 00104 00105 size_t counter; 00106 SHM_TABLE *st = reinterpret_cast<SHM_TABLE *> (this->base_addr_); 00107 00108 if (this->in_use (offset, counter) == -1) 00109 return -1; 00110 00111 if (counter == this->max_segments_) 00112 ACE_ERROR_RETURN ((LM_ERROR, 00113 "exceeded max number of segments = %d, base = %u, offset = %u\n", 00114 counter, 00115 this->base_addr_, 00116 offset), 00117 -1); 00118 else 00119 { 00120 int shmid = ACE_OS::shmget (st[counter].key_, 00121 rounded_bytes, 00122 this->file_perms_ | IPC_CREAT | IPC_EXCL); 00123 if (shmid == -1) 00124 ACE_ERROR_RETURN ((LM_ERROR, 00125 ACE_TEXT ("(%P|%t) %p\n"), 00126 ACE_TEXT ("shmget")), 00127 -1); 00128 st[counter].shmid_ = shmid; 00129 st[counter].used_ = 1; 00130 00131 void *address = (void *) (((char *) this->base_addr_) + offset); 00132 void *shmem = ACE_OS::shmat (st[counter].shmid_, 00133 (char *) address, 00134 0); 00135 00136 if (shmem != address) 00137 ACE_ERROR_RETURN ((LM_ERROR, 00138 "(%P|%t) %p, shmem = %u, address = %u\n", 00139 "shmat", 00140 shmem, 00141 address), 00142 -1); 00143 } 00144 return 0; 00145 } |
|
Dump the state of an object.
Definition at line 32 of file Shared_Memory_Pool.cpp. References ACE_TRACE.
00033 { 00034 #if defined (ACE_HAS_DUMP) 00035 ACE_TRACE ("ACE_Shared_Memory_Pool::dump"); 00036 #endif /* ACE_HAS_DUMP */ 00037 } |
|
Find the segment that contains the searchPtr.
Definition at line 64 of file Shared_Memory_Pool.cpp. References ACE_ERROR_RETURN, ACE_OFF_T, ACE_TEXT, IPC_STAT, LM_ERROR, ACE_OS::shmctl(), and ACE_Shared_Memory_Pool::SHM_TABLE::used_. Referenced by handle_signal().
00067 { 00068 offset = 0; 00069 SHM_TABLE *st = reinterpret_cast<SHM_TABLE *> (this->base_addr_); 00070 shmid_ds buf; 00071 00072 for (counter = 0; 00073 counter < this->max_segments_ 00074 && st[counter].used_ == 1; 00075 counter++) 00076 { 00077 if (ACE_OS::shmctl (st[counter].shmid_, IPC_STAT, &buf) == -1) 00078 ACE_ERROR_RETURN ((LM_ERROR, 00079 ACE_TEXT ("(%P|%t) %p\n"), 00080 ACE_TEXT ("shmctl")), 00081 -1); 00082 offset += buf.shm_segsz; 00083 00084 // If segment 'counter' starts at a location greater than the 00085 // place we are searching for. We then decrement the offset to 00086 // the start of counter-1. (flabar@vais.net) 00087 if (((ptrdiff_t) offset + (ptrdiff_t) (this->base_addr_)) > (ptrdiff_t) searchPtr) 00088 { 00089 --counter; 00090 offset -= buf.shm_segsz; 00091 return 0; 00092 } 00093 // ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("(%P|%t) segment size = %d, offset = %d\n"), buf.shm_segsz, offset)); 00094 } 00095 00096 return 0; 00097 } |
|
Handle SIGSEGV and SIGBUS signals to remap shared memory properly. Reimplemented from ACE_Event_Handler. Definition at line 150 of file Shared_Memory_Pool.cpp. References ACE_ERROR, ACE_ERROR_RETURN, ACE_OFF_T, ACE_TEXT, ACE_TRACE, find_seg(), in_use(), LM_ERROR, ACE_OS::shmat(), and ucontext_t.
00151 { 00152 ACE_TRACE ("ACE_Shared_Memory_Pool::handle_signal"); 00153 // ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("signal %S occurred\n"), signum)); 00154 00155 // While FreeBSD 5.X has a siginfo_t struct with a si_addr field, 00156 // it does not define SEGV_MAPERR. 00157 #if defined (ACE_HAS_SIGINFO_T) && !defined (ACE_LACKS_SI_ADDR) && \ 00158 (defined (SEGV_MAPERR) || defined (SEGV_MEMERR)) 00159 ACE_OFF_T offset; 00160 // Make sure that the pointer causing the problem is within the 00161 // range of the backing store. 00162 00163 if (siginfo != 0) 00164 { 00165 // ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("(%P|%t) si_signo = %d, si_code = %d, addr = %u\n"), siginfo->si_signo, siginfo->si_code, siginfo->si_addr)); 00166 size_t counter; 00167 if (this->in_use (offset, counter) == -1) 00168 ACE_ERROR ((LM_ERROR, 00169 ACE_TEXT ("(%P|%t) %p\n"), 00170 ACE_TEXT ("in_use"))); 00171 #if !defined(_UNICOS) 00172 else if (!(siginfo->si_code == SEGV_MAPERR 00173 && siginfo->si_addr < (((char *) this->base_addr_) + offset) 00174 && siginfo->si_addr >= ((char *) this->base_addr_))) 00175 ACE_ERROR_RETURN ((LM_ERROR, 00176 "(%P|%t) address %u out of range\n", 00177 siginfo->si_addr), 00178 -1); 00179 #else /* ! _UNICOS */ 00180 else if (!(siginfo->si_code == SEGV_MEMERR 00181 && siginfo->si_addr < (((unsigned long) this->base_addr_) + offset) 00182 && siginfo->si_addr >= ((unsigned long) this->base_addr_))) 00183 ACE_ERROR_RETURN ((LM_ERROR, 00184 "(%P|%t) address %u out of range\n", 00185 siginfo->si_addr), 00186 -1); 00187 #endif /* ! _UNICOS */ 00188 } 00189 00190 // The above if case will check to see that the address is in the 00191 // proper range. Therefore there is a segment out there that the 00192 // pointer wants to point into. Find the segment that someone else 00193 // has used and attach to it (flabar@vais.net) 00194 00195 size_t counter; // ret value to get shmid from the st table. 00196 00197 #if !defined(_UNICOS) 00198 if (this->find_seg (siginfo->si_addr, offset, counter) == -1) 00199 #else /* ! _UNICOS */ 00200 if (this->find_seg ((const void *)siginfo->si_addr, offset, counter) == -1) 00201 #endif /* ! _UNICOS */ 00202 ACE_ERROR_RETURN ((LM_ERROR, 00203 ACE_TEXT ("(%P|%t) %p\n"), 00204 ACE_TEXT ("in_use")), 00205 -1); 00206 00207 void *address = (void *) (((char *) this->base_addr_) + offset); 00208 SHM_TABLE *st = reinterpret_cast<SHM_TABLE *> (this->base_addr_); 00209 00210 void *shmem = ACE_OS::shmat (st[counter].shmid_, (char *) address, 0); 00211 00212 if (shmem != address) 00213 ACE_ERROR_RETURN ((LM_ERROR, 00214 "(%P|%t) %p, shmem = %u, address = %u\n", 00215 "shmat", 00216 shmem, 00217 address), 00218 -1); 00219 00220 // NOTE: this won't work if we dont have SIGINFO_T or SI_ADDR 00221 #else 00222 ACE_UNUSED_ARG (siginfo); 00223 #endif /* ACE_HAS_SIGINFO_T && !defined (ACE_LACKS_SI_ADDR) */ 00224 00225 return 0; 00226 } |
|
Determine how much memory is currently in use.
Definition at line 40 of file Shared_Memory_Pool.cpp. References ACE_ERROR_RETURN, ACE_OFF_T, ACE_TEXT, IPC_STAT, LM_ERROR, ACE_OS::shmctl(), and ACE_Shared_Memory_Pool::SHM_TABLE::used_. Referenced by commit_backing_store_name(), and handle_signal().
00042 { 00043 offset = 0; 00044 SHM_TABLE *st = reinterpret_cast<SHM_TABLE *> (this->base_addr_); 00045 shmid_ds buf; 00046 00047 for (counter = 0; 00048 counter < this->max_segments_ && st[counter].used_ == 1; 00049 counter++) 00050 { 00051 if (ACE_OS::shmctl (st[counter].shmid_, IPC_STAT, &buf) == -1) 00052 ACE_ERROR_RETURN ((LM_ERROR, 00053 ACE_TEXT ("(%P|%t) %p\n"), 00054 ACE_TEXT ("shmctl")), 00055 -1); 00056 offset += buf.shm_segsz; 00057 // ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("(%P|%t) segment size = %d, offset = %d\n"), buf.shm_segsz, offset)); 00058 } 00059 00060 return 0; 00061 } |
|
Ask system for initial chunk of local memory.
Definition at line 310 of file Shared_Memory_Pool.cpp. References ACE_ERROR_RETURN, ACE_OFF_T, ACE_TEXT, ACE_TRACE, base_shm_key_, IPC_CREAT, IPC_EXCL, ACE_Shared_Memory_Pool::SHM_TABLE::key_, LM_ERROR, ACE::round_to_pagesize(), round_up(), ACE_OS::shmat(), ACE_OS::shmget(), ACE_Shared_Memory_Pool::SHM_TABLE::shmid_, and ACE_Shared_Memory_Pool::SHM_TABLE::used_.
00313 { 00314 ACE_TRACE ("ACE_Shared_Memory_Pool::init_acquire"); 00315 00316 ACE_OFF_T shm_table_offset = ACE::round_to_pagesize (sizeof (SHM_TABLE)); 00317 rounded_bytes = this->round_up (nbytes > (size_t) this->minimum_bytes_ 00318 ? nbytes 00319 : (size_t) this->minimum_bytes_); 00320 00321 // Acquire the semaphore to serialize initialization and prevent 00322 // race conditions. 00323 00324 int shmid = ACE_OS::shmget (this->base_shm_key_, 00325 rounded_bytes + shm_table_offset, 00326 this->file_perms_ | IPC_CREAT | IPC_EXCL); 00327 if (shmid == -1) 00328 { 00329 if (errno != EEXIST) 00330 ACE_ERROR_RETURN ((LM_ERROR, 00331 ACE_TEXT ("(%P|%t) %p\n"), 00332 ACE_TEXT ("shmget")), 00333 0); 00334 first_time = 0; 00335 00336 shmid = ACE_OS::shmget (this->base_shm_key_, 0, 0); 00337 00338 if (shmid == -1) 00339 ACE_ERROR_RETURN ((LM_ERROR, 00340 ACE_TEXT ("(%P|%t) %p\n"), 00341 ACE_TEXT ("shmget")), 00342 0); 00343 00344 // This implementation doesn't care if we don't get the key we 00345 // want... 00346 this->base_addr_ = 00347 ACE_OS::shmat (shmid, 00348 reinterpret_cast<char *> (this->base_addr_), 00349 0); 00350 if (this->base_addr_ == reinterpret_cast<void *> (-1)) 00351 ACE_ERROR_RETURN ((LM_ERROR, 00352 "(%P|%t) %p, base_addr = %u\n", 00353 "shmat", 00354 this->base_addr_), 00355 0); 00356 } 00357 else 00358 { 00359 first_time = 1; 00360 00361 // This implementation doesn't care if we don't get the key we 00362 // want... 00363 this->base_addr_ = 00364 ACE_OS::shmat (shmid, 00365 reinterpret_cast<char *> (this->base_addr_), 00366 0); 00367 if (this->base_addr_ == reinterpret_cast<char *> (-1)) 00368 ACE_ERROR_RETURN ((LM_ERROR, 00369 "(%P|%t) %p, base_addr = %u\n", 00370 "shmat", 00371 this->base_addr_), 0); 00372 00373 SHM_TABLE *st = reinterpret_cast<SHM_TABLE *> (this->base_addr_); 00374 st[0].key_ = this->base_shm_key_; 00375 st[0].shmid_ = shmid; 00376 00377 st[0].used_ = 1; 00378 00379 for (size_t counter = 1; // Skip over the first entry... 00380 counter < this->max_segments_; 00381 counter++) 00382 { 00383 st[counter].key_ = this->base_shm_key_ + counter; 00384 st[counter].shmid_ = 0; 00385 st[counter].used_ = 0; 00386 } 00387 } 00388 00389 return (void *) (((char *) this->base_addr_) + shm_table_offset); 00390 } |
|
Change the protection of the pages of the mapped region to prot starting at addr up to len bytes. Definition at line 433 of file Shared_Memory_Pool.cpp. References ACE_TRACE.
00434 { 00435 ACE_TRACE ("ACE_Shared_Memory_Pool::protect"); 00436 return 0; 00437 } |
|
Change the protection of the pages of the mapped region to prot starting at Definition at line 426 of file Shared_Memory_Pool.cpp. References ACE_TRACE, and ssize_t.
00427 { 00428 ACE_TRACE ("ACE_Shared_Memory_Pool::protect"); 00429 return 0; 00430 } |
|
Instruct the memory pool to release all of its resources.
Definition at line 395 of file Shared_Memory_Pool.cpp. References ACE_TRACE, IPC_RMID, ACE_OS::shmctl(), and ACE_Shared_Memory_Pool::SHM_TABLE::used_.
00396 { 00397 ACE_TRACE ("ACE_Shared_Memory_Pool::release"); 00398 00399 int result = 0; 00400 SHM_TABLE *st = reinterpret_cast<SHM_TABLE *> (this->base_addr_); 00401 00402 for (size_t counter = 0; 00403 counter < this->max_segments_ && st[counter].used_ == 1; 00404 counter++) 00405 if (ACE_OS::shmctl (st[counter].shmid_, IPC_RMID, 0) == -1) 00406 result = -1; 00407 00408 return result; 00409 } |
|
Implement the algorithm for rounding up the request to an appropriate chunksize. Definition at line 450 of file Shared_Memory_Pool.cpp. References ACE_TRACE, and ACE::round_to_pagesize(). Referenced by acquire(), and init_acquire().
00451 { 00452 ACE_TRACE ("ACE_Shared_Memory_Pool::round_up"); 00453 if (nbytes < this->segment_size_) 00454 nbytes = this->segment_size_; 00455 00456 return ACE::round_to_pagesize (nbytes); 00457 } |
|
Sync the memory region to the backing store starting at addr.
Definition at line 419 of file Shared_Memory_Pool.cpp. References ACE_TRACE.
00420 { 00421 ACE_TRACE ("ACE_Shared_Memory_Pool::sync"); 00422 return 0; 00423 } |
|
Sync the memory region to the backing store starting at Definition at line 412 of file Shared_Memory_Pool.cpp. References ACE_TRACE, and ssize_t.
00413 { 00414 ACE_TRACE ("ACE_Shared_Memory_Pool::sync"); 00415 return 0; 00416 } |
|
Declare the dynamic allocation hooks.
Definition at line 136 of file Shared_Memory_Pool.h. |
|
Base address of the shared memory segment. If this has the value of 0 then the OS is free to select any address, otherwise this value is what the OS must try to use to map the shared memory segment. Definition at line 170 of file Shared_Memory_Pool.h. |
|
Base shared memory key for the segment.
Definition at line 185 of file Shared_Memory_Pool.h. Referenced by ACE_Shared_Memory_Pool(), and init_acquire(). |
|
File permissions to use when creating/opening a segment.
Definition at line 173 of file Shared_Memory_Pool.h. |
|
Number of shared memory segments in the table.
Definition at line 176 of file Shared_Memory_Pool.h. |
|
What the minimim bytes of the initial segment should be.
Definition at line 179 of file Shared_Memory_Pool.h. |
|
Shared memory segment size.
Definition at line 182 of file Shared_Memory_Pool.h. |
|
Handles SIGSEGV.
Definition at line 197 of file Shared_Memory_Pool.h. |