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