00001 #include "ace_pch.h"
00002
00003
00004
00005 #include "ace/Memory_Pool.h"
00006 #include "ace/Log_Msg.h"
00007
00008 #if !defined (__ACE_INLINE__)
00009 #include "ace/Memory_Pool.i"
00010 #endif
00011
00012 #include "ace/Auto_Ptr.h"
00013
00014 #if (ACE_HAS_POSITION_INDEPENDENT_POINTERS == 1)
00015 #include "ace/Based_Pointer_T.h"
00016 #include "ace/Based_Pointer_Repository.h"
00017 #endif
00018
00019 ACE_RCSID(ace, Memory_Pool, "Memory_Pool.cpp,v 4.79 2001/09/02 22:33:16 schmidt Exp")
00020
00021 ACE_ALLOC_HOOK_DEFINE(ACE_Local_Memory_Pool)
00022
00023 void
00024 ACE_Local_Memory_Pool::dump (void) const
00025 {
00026 ACE_TRACE ("ACE_Local_Memory_Pool::dump");
00027 }
00028
00029 ACE_Local_Memory_Pool::ACE_Local_Memory_Pool (const ACE_TCHAR *,
00030 const OPTIONS *)
00031 {
00032 ACE_TRACE ("ACE_Local_Memory_Pool::ACE_Local_Memory_Pool");
00033 }
00034
00035 void *
00036 ACE_Local_Memory_Pool::acquire (size_t nbytes,
00037 size_t &rounded_bytes)
00038 {
00039 ACE_TRACE ("ACE_Local_Memory_Pool::acquire");
00040 rounded_bytes = this->round_up (nbytes);
00041
00042 char *temp = 0;
00043 ACE_NEW_RETURN (temp,
00044 char[rounded_bytes],
00045 0);
00046
00047 ACE_Auto_Basic_Array_Ptr<char> cp (temp);
00048
00049 if (this->allocated_chunks_.insert (cp.get ()) != 0)
00050 ACE_ERROR_RETURN ((LM_ERROR,
00051 ACE_LIB_TEXT ("(%P|%t) insertion into set failed\n")),
00052 0);
00053
00054 return cp.release ();
00055 }
00056
00057 int
00058 ACE_Local_Memory_Pool::release (int)
00059 {
00060 ACE_TRACE ("ACE_Local_Memory_Pool::release");
00061
00062
00063 for (ACE_Unbounded_Set<char *>::iterator i = this->allocated_chunks_.begin ();
00064 i != this->allocated_chunks_.end ();
00065 ++i)
00066 delete [] *i;
00067 this->allocated_chunks_.reset ();
00068 return 0;
00069 }
00070
00071 #if defined (ACE_WIN32)
00072 int
00073 ACE_Local_Memory_Pool::seh_selector (void *)
00074 {
00075 return 0;
00076
00077 }
00078 #endif
00079
00080 int
00081 ACE_Local_Memory_Pool::remap (void *)
00082 {
00083 return 0;
00084
00085 }
00086
00087 ACE_ALLOC_HOOK_DEFINE(ACE_MMAP_Memory_Pool)
00088
00089 void
00090 ACE_MMAP_Memory_Pool::dump (void) const
00091 {
00092 ACE_TRACE ("ACE_MMAP_Memory_Pool::dump");
00093 }
00094
00095 int
00096 ACE_MMAP_Memory_Pool::release (int destroy)
00097 {
00098 ACE_TRACE ("ACE_MMAP_Memory_Pool::release");
00099
00100 #if (ACE_HAS_POSITION_INDEPENDENT_POINTERS == 1)
00101 ACE_BASED_POINTER_REPOSITORY::instance ()->unbind (this->mmap_.addr ());
00102 #endif
00103
00104 if (destroy)
00105 this->mmap_.remove ();
00106 else
00107 this->mmap_.close ();
00108 return 0;
00109 }
00110
00111 int
00112 ACE_MMAP_Memory_Pool::sync (ssize_t len, int flags)
00113 {
00114 ACE_TRACE ("ACE_MMAP_Memory_Pool::sync");
00115
00116 if (len < 0)
00117 len = ACE_OS::lseek (this->mmap_.handle (), 0, SEEK_END);
00118
00119 return this->mmap_.sync (len, flags);
00120 }
00121
00122
00123
00124
00125 int
00126 ACE_MMAP_Memory_Pool::sync (void *addr, size_t len, int flags)
00127 {
00128 ACE_TRACE ("ACE_MMAP_Memory_Pool::sync");
00129 return ACE_OS::msync (addr, len, flags);
00130 }
00131
00132
00133
00134
00135
00136 int
00137 ACE_MMAP_Memory_Pool::protect (ssize_t len, int prot)
00138 {
00139 ACE_TRACE ("ACE_MMAP_Memory_Pool::protect");
00140
00141 if (len < 0)
00142 len = ACE_OS::lseek (this->mmap_.handle (), 0, SEEK_END);
00143
00144 return this->mmap_.protect (len, prot);
00145 }
00146
00147
00148
00149
00150 int
00151 ACE_MMAP_Memory_Pool::protect (void *addr, size_t len, int prot)
00152 {
00153 ACE_TRACE ("ACE_MMAP_Memory_Pool::protect");
00154 return ACE_OS::mprotect (addr, len, prot);
00155 }
00156
00157 ACE_MMAP_Memory_Pool::ACE_MMAP_Memory_Pool (const ACE_TCHAR *backing_store_name,
00158 const OPTIONS *options)
00159 : base_addr_ (0),
00160 use_fixed_addr_(0),
00161 flags_ (MAP_SHARED),
00162 write_each_page_ (0),
00163 minimum_bytes_ (0),
00164 sa_ (0),
00165 file_mode_ (ACE_DEFAULT_FILE_PERMS)
00166 {
00167 ACE_TRACE ("ACE_MMAP_Memory_Pool::ACE_MMAP_Memory_Pool");
00168
00169 #if (defined (ACE_HAS_SIGINFO_T) && !defined (ACE_LACKS_SI_ADDR)) || defined (ACE_WIN32)
00170
00171 guess_on_fault_ = 0;
00172 #else
00173
00174
00175 if (options)
00176 guess_on_fault_ = options->guess_on_fault_;
00177 else
00178
00179 guess_on_fault_ = 1;
00180 #endif
00181
00182
00183 if (options)
00184 {
00185 if (options->flags_ != 0)
00186 this->flags_ = options->flags_;
00187 use_fixed_addr_ = options->use_fixed_addr_;
00188
00189 if (use_fixed_addr_ == ACE_MMAP_Memory_Pool_Options::ALWAYS_FIXED)
00190 {
00191 this->base_addr_ = ACE_const_cast (void *, options->base_addr_);
00192 ACE_SET_BITS (flags_, MAP_FIXED);
00193 }
00194 this->write_each_page_ = options->write_each_page_;
00195 this->minimum_bytes_ = options->minimum_bytes_;
00196 if (options->sa_ != 0)
00197 this->sa_ = options->sa_;
00198 this->file_mode_ = options->file_mode_;
00199 }
00200
00201 if (backing_store_name == 0)
00202 {
00203
00204
00205 #if defined (ACE_DEFAULT_BACKING_STORE)
00206
00207 ACE_OS::strcpy (this->backing_store_name_,
00208 ACE_DEFAULT_BACKING_STORE);
00209 #else
00210 if (ACE_Lib_Find::get_temp_dir (this->backing_store_name_,
00211 MAXPATHLEN - 17) == -1)
00212
00213 {
00214 ACE_ERROR ((LM_ERROR,
00215 ACE_LIB_TEXT ("Temporary path too long, ")
00216 ACE_LIB_TEXT ("defaulting to current directory\n")));
00217 this->backing_store_name_[0] = 0;
00218 }
00219
00220
00221 ACE_OS::strcat (this->backing_store_name_,
00222 ACE_LIB_TEXT ("ace-malloc-XXXXXX"));
00223
00224 #endif
00225 }
00226 else
00227 ACE_OS::strsncpy (this->backing_store_name_,
00228 backing_store_name,
00229 (sizeof this->backing_store_name_ / sizeof (ACE_TCHAR)));
00230
00231 #if !defined (ACE_WIN32) && !defined (CHORUS)
00232 if (this->signal_handler_.register_handler (SIGSEGV, this) == -1)
00233 ACE_ERROR ((LM_ERROR,
00234 "%p\n", this->backing_store_name_));
00235 #endif
00236 }
00237
00238
00239
00240 int
00241 ACE_MMAP_Memory_Pool::commit_backing_store_name (size_t rounded_bytes,
00242 off_t &map_size)
00243 {
00244 ACE_TRACE ("ACE_MMAP_Memory_Pool::commit_backing_store_name");
00245
00246 #if defined (CHORUS)
00247 map_size = rounded_bytes;
00248 #else
00249 size_t seek_len;
00250
00251 if (this->write_each_page_)
00252
00253
00254 seek_len = this->round_up (1);
00255 else
00256
00257 seek_len = rounded_bytes;
00258
00259
00260
00261
00262
00263 for (size_t cur_block = 0;
00264 cur_block < rounded_bytes;
00265 cur_block += seek_len)
00266 {
00267 map_size = ACE_OS::lseek (this->mmap_.handle (),
00268 ACE_static_cast (off_t, seek_len - 1),
00269 SEEK_END);
00270
00271 if (map_size == -1
00272 || ACE_OS::write (this->mmap_.handle (),
00273 "",
00274 1) == -1)
00275 ACE_ERROR_RETURN ((LM_ERROR,
00276 ACE_LIB_TEXT ("(%P|%t) %p\n"),
00277 this->backing_store_name_),
00278 -1);
00279 }
00280
00281
00282 map_size++;
00283 #endif
00284 return 0;
00285 }
00286
00287
00288
00289 int
00290 ACE_MMAP_Memory_Pool::map_file (off_t map_size)
00291 {
00292 ACE_TRACE ("ACE_MMAP_Memory_Pool::map_file");
00293
00294
00295 this->mmap_.unmap ();
00296
00297 #if (ACE_HAS_POSITION_INDEPENDENT_POINTERS == 1)
00298 if(use_fixed_addr_ == ACE_MMAP_Memory_Pool_Options::NEVER_FIXED)
00299 this->base_addr_ = 0;
00300 #endif
00301
00302
00303 if (this->mmap_.map (map_size,
00304 PROT_RDWR,
00305 this->flags_,
00306 this->base_addr_,
00307 0,
00308 this->sa_) == -1
00309 || this->base_addr_ != 0
00310 #ifdef ACE_HAS_WINCE
00311 && this->mmap_.addr () == 0)
00312 #else
00313 && this->mmap_.addr () != this->base_addr_)
00314 #endif // ACE_HAS_WINCE
00315 {
00316 #if 0
00317 ACE_ERROR ((LM_ERROR,
00318 ACE_LIB_TEXT ("(%P|%t) addr = %u, base_addr = %u, map_size = %u, %p\n"),
00319 this->mmap_.addr (),
00320 this->base_addr_,
00321 map_size,
00322 this->backing_store_name_));
00323 #endif
00324 return -1;
00325 }
00326 else
00327 {
00328 #if (ACE_HAS_POSITION_INDEPENDENT_POINTERS == 1)
00329 this->base_addr_ = this->mmap_.addr ();
00330 ACE_BASED_POINTER_REPOSITORY::instance ()->bind (this->base_addr_,
00331 map_size);
00332 #endif
00333 return 0;
00334 }
00335 }
00336
00337
00338
00339
00340
00341 void *
00342 ACE_MMAP_Memory_Pool::acquire (size_t nbytes,
00343 size_t &rounded_bytes)
00344 {
00345 ACE_TRACE ("ACE_MMAP_Memory_Pool::acquire");
00346 rounded_bytes = this->round_up (nbytes);
00347
00348
00349
00350
00351 off_t map_size;
00352
00353 if (this->commit_backing_store_name (rounded_bytes,
00354 map_size) == -1)
00355 return 0;
00356 else if (this->map_file (map_size) == -1)
00357 return 0;
00358
00359
00360
00361
00362
00363 return (void *) ((char *) this->mmap_.addr () + (this->mmap_.size () - rounded_bytes));
00364 }
00365
00366
00367
00368 void *
00369 ACE_MMAP_Memory_Pool::init_acquire (size_t nbytes,
00370 size_t &rounded_bytes,
00371 int &first_time)
00372 {
00373 ACE_TRACE ("ACE_MMAP_Memory_Pool::init_acquire");
00374
00375 first_time = 0;
00376
00377 if (nbytes < (size_t) this->minimum_bytes_)
00378 nbytes = this->minimum_bytes_;
00379
00380 if (this->mmap_.open (this->backing_store_name_,
00381 O_RDWR | O_CREAT | O_TRUNC | O_EXCL,
00382 this->file_mode_, this->sa_) != -1)
00383 {
00384
00385 first_time = 1;
00386 return this->acquire (nbytes, rounded_bytes);
00387 }
00388 else if (errno == EEXIST)
00389 {
00390 errno = 0;
00391
00392 if (this->mmap_.map (this->backing_store_name_,
00393 #if defined (CHORUS)
00394 nbytes,
00395 #else
00396 -1,
00397 #endif
00398 O_RDWR,
00399 this->file_mode_,
00400 PROT_RDWR,
00401 this->flags_,
00402 this->base_addr_,
00403 0,
00404 this->sa_) == -1)
00405 ACE_ERROR_RETURN ((LM_ERROR,
00406 ACE_LIB_TEXT ("%p\n"),
00407 ACE_LIB_TEXT ("open")),
00408 0);
00409
00410 return this->mmap_.addr ();
00411 }
00412 else
00413 ACE_ERROR_RETURN ((LM_ERROR,
00414 ACE_LIB_TEXT ("%p\n"),
00415 ACE_LIB_TEXT ("open")),
00416 0);
00417 }
00418
00419 #if defined (ACE_WIN32)
00420 int
00421 ACE_MMAP_Memory_Pool::seh_selector (void *ep)
00422 {
00423 DWORD ecode = ((EXCEPTION_POINTERS *) ep)->ExceptionRecord->ExceptionCode;
00424
00425 if (ecode == EXCEPTION_ACCESS_VIOLATION)
00426 {
00427 void * fault_addr = (void *)
00428 ((EXCEPTION_POINTERS *) ep)->ExceptionRecord->ExceptionInformation[1];
00429
00430 if (this->remap (fault_addr) == 0)
00431 return 1;
00432 }
00433
00434 return 0;
00435 }
00436 #endif
00437
00438 int
00439 ACE_MMAP_Memory_Pool::remap (void *addr)
00440 {
00441 ACE_TRACE ("ACE_MMAP_Memory_Pool::remap");
00442
00443 off_t current_map_size = ACE_OS::filesize (this->mmap_.handle ());
00444
00445
00446 if (!(addr < (void *) ((char *) this->mmap_.addr () + current_map_size)
00447 && addr >= this->mmap_.addr ()))
00448 return -1;
00449
00450
00451 return this->map_file (current_map_size);
00452 }
00453
00454 ACE_MMAP_Memory_Pool_Options::ACE_MMAP_Memory_Pool_Options (const void *base_addr,
00455 int use_fixed_addr,
00456 int write_each_page,
00457 off_t minimum_bytes,
00458 u_int flags,
00459 int guess_on_fault,
00460 LPSECURITY_ATTRIBUTES sa,
00461 mode_t file_mode)
00462 : base_addr_ (base_addr),
00463 use_fixed_addr_ (use_fixed_addr),
00464 write_each_page_ (write_each_page),
00465 minimum_bytes_ (minimum_bytes),
00466 flags_ (flags),
00467 guess_on_fault_ (guess_on_fault),
00468 sa_ (sa),
00469 file_mode_ (file_mode)
00470 {
00471 ACE_TRACE ("ACE_MMAP_Memory_Pool_Options::ACE_MMAP_Memory_Pool_Options");
00472
00473 if (base_addr_ == 0 && use_fixed_addr_ == ALWAYS_FIXED)
00474 use_fixed_addr_ = FIRSTCALL_FIXED;
00475
00476
00477 #if defined (__hpux) && defined (__LP64__)
00478 long temp = ACE_DEFAULT_BASE_ADDRL;
00479 base_addr_ = (void *) temp;
00480 #endif
00481 }
00482
00483
00484
00485
00486
00487
00488
00489
00490
00491
00492
00493 int
00494 ACE_MMAP_Memory_Pool::handle_signal (int signum, siginfo_t *siginfo, ucontext_t *)
00495 {
00496 if (signum != SIGSEGV)
00497 return -1;
00498 else
00499 ;
00500
00501
00502
00503 #if defined (ACE_HAS_SIGINFO_T) && !defined (ACE_LACKS_SI_ADDR)
00504
00505
00506
00507 if (siginfo != 0)
00508 {
00509
00510 if (this->remap ((void *) siginfo->si_addr) == -1)
00511 return -1;
00512
00513
00514 return 0;
00515 }
00516 #else
00517 ACE_UNUSED_ARG(siginfo);
00518 #endif
00519
00520
00521
00522
00523
00524
00525 if (guess_on_fault_)
00526 {
00527
00528 off_t current_map_size = ACE_OS::filesize (this->mmap_.handle ());
00529
00530 if (ACE_static_cast (size_t, current_map_size) == this->mmap_.size ())
00531 {
00532
00533
00534
00535
00536 this->signal_handler_.remove_handler (SIGSEGV);
00537 return 0;
00538 }
00539
00540
00541 return this->map_file (current_map_size);
00542 }
00543 else
00544 return -1;
00545 }
00546
00547 ACE_ALLOC_HOOK_DEFINE(ACE_Lite_MMAP_Memory_Pool)
00548
00549 ACE_Lite_MMAP_Memory_Pool::ACE_Lite_MMAP_Memory_Pool (const ACE_TCHAR *backing_store_name,
00550 const OPTIONS *options)
00551 : ACE_MMAP_Memory_Pool (backing_store_name, options)
00552 {
00553 ACE_TRACE ("ACE_Lite_MMAP_Memory_Pool::ACE_Lite_MMAP_Memory_Pool");
00554 }
00555
00556 int
00557 ACE_Lite_MMAP_Memory_Pool::sync (ssize_t, int)
00558 {
00559 ACE_TRACE ("ACE_Lite_MMAP_Memory_Pool::sync");
00560 return 0;
00561 }
00562
00563 int
00564 ACE_Lite_MMAP_Memory_Pool::sync (void *, size_t, int)
00565 {
00566 ACE_TRACE ("ACE_Lite_MMAP_Memory_Pool::sync");
00567 return 0;
00568 }
00569
00570 #if !defined (ACE_LACKS_SBRK)
00571 ACE_ALLOC_HOOK_DEFINE(ACE_Sbrk_Memory_Pool)
00572
00573
00574
00575 void *
00576 ACE_Sbrk_Memory_Pool::acquire (size_t nbytes,
00577 size_t &rounded_bytes)
00578 {
00579 ACE_TRACE ("ACE_Sbrk_Memory_Pool::acquire");
00580 rounded_bytes = this->round_up (nbytes);
00581
00582 void *cp = ACE_OS::sbrk (rounded_bytes);
00583
00584 if (cp == MAP_FAILED)
00585 ACE_ERROR_RETURN ((LM_ERROR,
00586 "(%P|%t) cp = %u\n",
00587 cp),
00588 0);
00589 else
00590
00591 return cp;
00592 }
00593
00594 void
00595 ACE_Sbrk_Memory_Pool::dump (void) const
00596 {
00597 ACE_TRACE ("ACE_Sbrk_Memory_Pool::dump");
00598 }
00599
00600 ACE_Sbrk_Memory_Pool::ACE_Sbrk_Memory_Pool (const ACE_TCHAR *,
00601 const OPTIONS *)
00602 {
00603 ACE_TRACE ("ACE_Sbrk_Memory_Pool::ACE_Sbrk_Memory_Pool");
00604 }
00605 #endif
00606
00607 #if !defined (ACE_LACKS_SYSV_SHMEM)
00608 ACE_ALLOC_HOOK_DEFINE(ACE_Shared_Memory_Pool)
00609
00610 ACE_Shared_Memory_Pool_Options::ACE_Shared_Memory_Pool_Options (const char *base_addr,
00611 size_t max_segments,
00612 size_t file_perms,
00613 off_t minimum_bytes,
00614 size_t segment_size)
00615 : base_addr_ (base_addr),
00616 max_segments_ (max_segments),
00617 minimum_bytes_ (minimum_bytes),
00618 file_perms_ (file_perms),
00619 segment_size_ (segment_size)
00620 {
00621 ACE_TRACE ("ACE_Shared_Memory_Pool_Options::ACE_Shared_Memory_Pool_Options");
00622
00623 #if defined (__hpux) && defined (__LP64__)
00624 long temp = ACE_DEFAULT_BASE_ADDRL;
00625 base_addr_ = (char *) temp;
00626 #endif
00627 }
00628
00629 void
00630 ACE_Shared_Memory_Pool::dump (void) const
00631 {
00632 ACE_TRACE ("ACE_Shared_Memory_Pool::dump");
00633 }
00634
00635 int
00636 ACE_Shared_Memory_Pool::in_use (off_t &offset,
00637 size_t &counter)
00638 {
00639 offset = 0;
00640 SHM_TABLE *st = ACE_reinterpret_cast (SHM_TABLE *,
00641 this->base_addr_);
00642 shmid_ds buf;
00643
00644 for (counter = 0;
00645 counter < this->max_segments_ && st[counter].used_ == 1;
00646 counter++)
00647 {
00648 if (ACE_OS::shmctl (st[counter].shmid_, IPC_STAT, &buf) == -1)
00649 ACE_ERROR_RETURN ((LM_ERROR,
00650 ACE_LIB_TEXT ("(%P|%t) %p\n"),
00651 ACE_LIB_TEXT ("shmctl")),
00652 -1);
00653 offset += buf.shm_segsz;
00654
00655 }
00656
00657 return 0;
00658 }
00659
00660 int
00661 ACE_Shared_Memory_Pool::find_seg (const void* const searchPtr,
00662 off_t &offset,
00663 size_t &counter)
00664 {
00665 offset = 0;
00666 SHM_TABLE *st = ACE_reinterpret_cast (SHM_TABLE *,
00667 this->base_addr_);
00668 shmid_ds buf;
00669
00670 for (counter = 0;
00671 counter < this->max_segments_
00672 && st[counter].used_ == 1;
00673 counter++)
00674 {
00675 if (ACE_OS::shmctl (st[counter].shmid_, IPC_STAT, &buf) == -1)
00676 ACE_ERROR_RETURN ((LM_ERROR,
00677 ACE_LIB_TEXT ("(%P|%t) %p\n"),
00678 ACE_LIB_TEXT ("shmctl")),
00679 -1);
00680 offset += buf.shm_segsz;
00681
00682
00683
00684
00685 if (((ptrdiff_t) offset + (ptrdiff_t) (this->base_addr_)) > (ptrdiff_t) searchPtr)
00686 {
00687 --counter;
00688 offset -= buf.shm_segsz;
00689 return 0;
00690 }
00691
00692 }
00693
00694 return 0;
00695 }
00696
00697 int
00698 ACE_Shared_Memory_Pool::commit_backing_store_name (size_t rounded_bytes,
00699 off_t &offset)
00700 {
00701 ACE_TRACE ("ACE_Shared_Memory_Pool::commit_backing_store_name");
00702
00703 size_t counter;
00704 SHM_TABLE *st = ACE_reinterpret_cast (SHM_TABLE *,
00705 this->base_addr_);
00706
00707 if (this->in_use (offset, counter) == -1)
00708 return -1;
00709
00710 if (counter == this->max_segments_)
00711 ACE_ERROR_RETURN ((LM_ERROR,
00712 "exceeded max number of segments = %d, base = %u, offset = %u\n",
00713 counter,
00714 this->base_addr_,
00715 offset),
00716 -1);
00717 else
00718 {
00719 int shmid = ACE_OS::shmget (st[counter].key_,
00720 rounded_bytes,
00721 this->file_perms_ | IPC_CREAT | IPC_EXCL);
00722 if (shmid == -1)
00723 ACE_ERROR_RETURN ((LM_ERROR,
00724 ACE_LIB_TEXT ("(%P|%t) %p\n"),
00725 ACE_LIB_TEXT ("shmget")),
00726 0);
00727 st[counter].shmid_ = shmid;
00728 st[counter].used_ = 1;
00729
00730 void *address = (void *) (((char *) this->base_addr_) + offset);
00731 void *shmem = ACE_OS::shmat (st[counter].shmid_,
00732 (char *) address,
00733 0);
00734
00735 if (shmem != address)
00736 ACE_ERROR_RETURN ((LM_ERROR,
00737 "(%P|%t) %p, shmem = %u, address = %u\n",
00738 "shmat",
00739 shmem,
00740 address),
00741 0);
00742 }
00743 return 0;
00744 }
00745
00746
00747
00748 int
00749 ACE_Shared_Memory_Pool::handle_signal (int , siginfo_t *siginfo, ucontext_t *)
00750 {
00751 ACE_TRACE ("ACE_Shared_Memory_Pool::handle_signal");
00752
00753
00754 #if defined (ACE_HAS_SIGINFO_T) && !defined (ACE_LACKS_SI_ADDR)
00755 off_t offset;
00756
00757
00758
00759 if (siginfo != 0)
00760 {
00761
00762 size_t counter;
00763 if (this->in_use (offset, counter) == -1)
00764 ACE_ERROR ((LM_ERROR,
00765 ACE_LIB_TEXT ("(%P|%t) %p\n"),
00766 ACE_LIB_TEXT ("in_use")));
00767 #if !defined(_UNICOS)
00768 else if (!(siginfo->si_code == SEGV_MAPERR
00769 && siginfo->si_addr < (((char *) this->base_addr_) + offset)
00770 && siginfo->si_addr >= ((char *) this->base_addr_)))
00771 ACE_ERROR_RETURN ((LM_ERROR,
00772 "(%P|%t) address %u out of range\n",
00773 siginfo->si_addr),
00774 -1);
00775 #else
00776 else if (!(siginfo->si_code == SEGV_MEMERR
00777 && siginfo->si_addr < (((unsigned long) this->base_addr_) + offset)
00778 && siginfo->si_addr >= ((unsigned long) this->base_addr_)))
00779 ACE_ERROR_RETURN ((LM_ERROR,
00780 "(%P|%t) address %u out of range\n",
00781 siginfo->si_addr),
00782 -1);
00783 #endif
00784 }
00785
00786
00787
00788
00789
00790
00791 size_t counter;
00792
00793 #if !defined(_UNICOS)
00794 if (this->find_seg (siginfo->si_addr, offset, counter) == -1)
00795 #else
00796 if (this->find_seg ((const void *)siginfo->si_addr, offset, counter) == -1)
00797 #endif
00798 ACE_ERROR_RETURN ((LM_ERROR,
00799 ACE_LIB_TEXT ("(%P|%t) %p\n"),
00800 ACE_LIB_TEXT ("in_use")),
00801 -1);
00802
00803 void *address = (void *) (((char *) this->base_addr_) + offset);
00804 SHM_TABLE *st = ACE_reinterpret_cast (SHM_TABLE *,
00805 this->base_addr_);
00806
00807 void *shmem = ACE_OS::shmat (st[counter].shmid_, (char *) address, 0);
00808
00809 if (shmem != address)
00810 ACE_ERROR_RETURN ((LM_ERROR,
00811 "(%P|%t) %p, shmem = %u, address = %u\n",
00812 "shmat",
00813 shmem,
00814 address),
00815 0);
00816
00817
00818 #else
00819 ACE_UNUSED_ARG (siginfo);
00820 #endif
00821
00822 return 0;
00823 }
00824
00825 ACE_Shared_Memory_Pool::ACE_Shared_Memory_Pool (const ACE_TCHAR *backing_store_name,
00826 const OPTIONS *options)
00827 : base_addr_ (0),
00828 file_perms_ (ACE_DEFAULT_FILE_PERMS),
00829 max_segments_ (ACE_DEFAULT_MAX_SEGMENTS),
00830 minimum_bytes_ (0),
00831 segment_size_ (ACE_DEFAULT_SEGMENT_SIZE)
00832 {
00833 ACE_TRACE ("ACE_Shared_Memory_Pool::ACE_Shared_Memory_Pool");
00834
00835
00836 if (options)
00837 {
00838 this->base_addr_ =
00839 ACE_reinterpret_cast (void *,
00840 ACE_const_cast (char *,
00841 options->base_addr_));
00842 this->max_segments_ = options->max_segments_;
00843 this->file_perms_ = options->file_perms_;
00844 this->minimum_bytes_ = options->minimum_bytes_;
00845 this->segment_size_ = options->segment_size_;
00846 }
00847
00848 if (backing_store_name)
00849 {
00850
00851
00852
00853 int segment_key;
00854 int result = ::sscanf (backing_store_name,
00855 "%d",
00856 &segment_key);
00857
00858 if (result == 0 || result == EOF)
00859
00860
00861 this->base_shm_key_ = (key_t) ACE::crc32 (backing_store_name);
00862 else
00863 this->base_shm_key_ = segment_key;
00864
00865 if (this->base_shm_key_ == IPC_PRIVATE)
00866
00867
00868 this->base_shm_key_ = ACE_DEFAULT_SHM_KEY;
00869 }
00870 else
00871 this->base_shm_key_ = ACE_DEFAULT_SHM_KEY;
00872
00873 if (this->signal_handler_.register_handler (SIGSEGV, this) == -1)
00874 ACE_ERROR ((LM_ERROR,
00875 ACE_LIB_TEXT ("%p\n"),
00876 ACE_LIB_TEXT ("ACE_Sig_Handler::register_handler")));
00877 }
00878
00879
00880
00881 void *
00882 ACE_Shared_Memory_Pool::acquire (size_t nbytes,
00883 size_t &rounded_bytes)
00884 {
00885 ACE_TRACE ("ACE_Shared_Memory_Pool::acquire");
00886
00887 rounded_bytes = this->round_up (nbytes);
00888
00889
00890
00891 off_t offset;
00892
00893 if (this->commit_backing_store_name (rounded_bytes, offset) == -1)
00894 return 0;
00895
00896
00897 return ((char *) this->base_addr_) + offset;
00898 }
00899
00900
00901
00902 void *
00903 ACE_Shared_Memory_Pool::init_acquire (size_t nbytes,
00904 size_t &rounded_bytes,
00905 int &first_time)
00906 {
00907 ACE_TRACE ("ACE_Shared_Memory_Pool::init_acquire");
00908
00909 off_t shm_table_offset = ACE::round_to_pagesize (sizeof (SHM_TABLE));
00910 rounded_bytes = this->round_up (nbytes > (size_t) this->minimum_bytes_
00911 ? nbytes
00912 : (size_t) this->minimum_bytes_);
00913
00914
00915
00916
00917 int shmid = ACE_OS::shmget (this->base_shm_key_,
00918 rounded_bytes + shm_table_offset,
00919 this->file_perms_ | IPC_CREAT | IPC_EXCL);
00920 if (shmid == -1)
00921 {
00922 if (errno != EEXIST)
00923 ACE_ERROR_RETURN ((LM_ERROR,
00924 ACE_LIB_TEXT ("(%P|%t) %p\n"),
00925 ACE_LIB_TEXT ("shmget")),
00926 0);
00927 first_time = 0;
00928
00929 shmid = ACE_OS::shmget (this->base_shm_key_, 0, 0);
00930
00931 if (shmid == -1)
00932 ACE_ERROR_RETURN ((LM_ERROR,
00933 ACE_LIB_TEXT ("(%P|%t) %p\n"),
00934 ACE_LIB_TEXT ("shmget")),
00935 0);
00936
00937
00938
00939 this->base_addr_ =
00940 ACE_OS::shmat (shmid,
00941 ACE_reinterpret_cast (char *,
00942 this->base_addr_),
00943 0);
00944 if (this->base_addr_ == ACE_reinterpret_cast (void *, -1))
00945 ACE_ERROR_RETURN ((LM_ERROR,
00946 "(%P|%t) %p, base_addr = %u\n",
00947 "shmat",
00948 this->base_addr_),
00949 0);
00950 }
00951 else
00952 {
00953 first_time = 1;
00954
00955
00956
00957 this->base_addr_ =
00958 ACE_OS::shmat (shmid,
00959 ACE_reinterpret_cast (char *,
00960 this->base_addr_),
00961 0);
00962 if (this->base_addr_ == ACE_reinterpret_cast (char *, -1))
00963 ACE_ERROR_RETURN ((LM_ERROR,
00964 "(%P|%t) %p, base_addr = %u\n",
00965 "shmat",
00966 this->base_addr_), 0);
00967
00968 SHM_TABLE *st = ACE_reinterpret_cast (SHM_TABLE *,
00969 this->base_addr_);
00970 st[0].key_ = this->base_shm_key_;
00971 st[0].shmid_ = shmid;
00972
00973 st[0].used_ = 1;
00974
00975 for (size_t counter = 1;
00976 counter < this->max_segments_;
00977 counter++)
00978 {
00979 st[counter].key_ = this->base_shm_key_ + counter;
00980 st[counter].shmid_ = 0;
00981 st[counter].used_ = 0;
00982 }
00983 }
00984
00985 return (void *) (((char *) this->base_addr_) + shm_table_offset);
00986 }
00987
00988
00989
00990 int
00991 ACE_Shared_Memory_Pool::release (int)
00992 {
00993 ACE_TRACE ("ACE_Shared_Memory_Pool::release");
00994
00995 int result = 0;
00996 SHM_TABLE *st = ACE_reinterpret_cast (SHM_TABLE *,
00997 this->base_addr_);
00998
00999 for (size_t counter = 0;
01000 counter < this->max_segments_ && st[counter].used_ == 1;
01001 counter++)
01002 if (ACE_OS::shmctl (st[counter].shmid_, IPC_RMID, 0) == -1)
01003 result = -1;
01004
01005 return result;
01006 }
01007 #endif
01008
01009 #if defined (ACE_WIN32)
01010 #if !defined (ACE_HAS_WINCE)
01011 #define ACE_MAP_FILE(_hnd, _access, _offHigh, _offLow, _nBytes, _baseAdd)\
01012 MapViewOfFileEx (_hnd, _access, _offHigh, _offLow, _nBytes, _baseAdd)
01013 #else //if !defined (ACE_HAS_WINCE)
01014 #define ACE_MAP_FILE(_hnd, _access, _offHigh, _offLow, _nBytes, _baseAdd)\
01015 MapViewOfFile (_hnd, _access, _offHigh, _offLow, _nBytes)
01016 #endif
01017
01018 ACE_Pagefile_Memory_Pool_Options::ACE_Pagefile_Memory_Pool_Options (void *base_addr,
01019 size_t max_size)
01020 : base_addr_ (base_addr),
01021 max_size_ (max_size)
01022 {
01023 }
01024
01025 int
01026 ACE_Pagefile_Memory_Pool::release (int)
01027 {
01028 return this->unmap ();
01029 }
01030
01031 ACE_Pagefile_Memory_Pool::ACE_Pagefile_Memory_Pool (const ACE_TCHAR *backing_store_name,
01032 const OPTIONS *options)
01033 : shared_cb_ (0),
01034 object_handle_ (0),
01035 page_size_ (ACE_Pagefile_Memory_Pool::round_to_page_size (1))
01036 {
01037
01038 if (options != 0)
01039 {
01040 this->local_cb_.req_base_ = options->base_addr_;
01041 this->local_cb_.mapped_base_ = 0;
01042 this->local_cb_.sh_.max_size_ =
01043 options->max_size_;
01044 this->local_cb_.sh_.mapped_size_ = 0;
01045 this->local_cb_.sh_.free_offset_ =
01046 this->local_cb_.sh_.mapped_size_;
01047 this->local_cb_.sh_.free_size_ = 0;
01048 }
01049
01050 if (backing_store_name == 0)
01051
01052
01053 backing_store_name = ACE_DEFAULT_PAGEFILE_POOL_NAME;
01054
01055 ACE_OS::strsncpy (this->backing_store_name_,
01056 backing_store_name,
01057 (sizeof this->backing_store_name_ / sizeof (ACE_TCHAR)));
01058 }
01059
01060 void *
01061 ACE_Pagefile_Memory_Pool::acquire (size_t nbytes,
01062 size_t &rounded_bytes)
01063 {
01064 rounded_bytes = round_to_page_size (nbytes);
01065 void *result = 0;
01066 int first_time = 0;
01067
01068
01069
01070 if (this->shared_cb_->sh_.mapped_size_
01071 > this->local_cb_.sh_.mapped_size_
01072 || this->shared_cb_->sh_.free_size_ < rounded_bytes)
01073 {
01074 size_t append = 0;
01075 if (rounded_bytes > this->shared_cb_->sh_.free_size_)
01076 append = rounded_bytes - this->shared_cb_->sh_.free_size_;
01077
01078 if (this->map (first_time, append) < 0)
01079 return result;
01080 }
01081
01082
01083
01084 if (this->shared_cb_->sh_.free_size_ < rounded_bytes)
01085 return result;
01086
01087 result = (void *)((char *) this->local_cb_.mapped_base_
01088 + this->shared_cb_->sh_.free_offset_);
01089 this->shared_cb_->sh_.free_offset_ += rounded_bytes;
01090 this->shared_cb_->sh_.free_size_ -= rounded_bytes;
01091 this->local_cb_.sh_ = this->shared_cb_->sh_;
01092
01093 return result;
01094 }
01095
01096 void *
01097 ACE_Pagefile_Memory_Pool::init_acquire (size_t nbytes,
01098 size_t &rounded_bytes,
01099 int &first_time)
01100 {
01101
01102
01103 if (this->map (first_time) < 0)
01104 return 0;
01105
01106 if (first_time != 0)
01107
01108
01109 return this->acquire (nbytes, rounded_bytes);
01110 else
01111
01112 return (void *)((char *) this->local_cb_.mapped_base_
01113 + ACE_Pagefile_Memory_Pool::round_to_page_size
01114 ((int) sizeof (Control_Block)));
01115 }
01116
01117 int
01118 ACE_Pagefile_Memory_Pool::seh_selector (void *ep)
01119 {
01120 DWORD ecode = ((EXCEPTION_POINTERS *) ep)->ExceptionRecord->ExceptionCode;
01121
01122 if (ecode == EXCEPTION_ACCESS_VIOLATION)
01123 {
01124 void * fault_addr = (void *)
01125 ((EXCEPTION_POINTERS *) ep)->ExceptionRecord->ExceptionInformation[1];
01126
01127 if (this->remap (fault_addr) == 0)
01128 return 1;
01129 }
01130
01131 return 0;
01132 }
01133
01134 int
01135 ACE_Pagefile_Memory_Pool::remap (void *addr)
01136 {
01137
01138
01139
01140 if (this->shared_cb_ == 0
01141 || addr < this->local_cb_.mapped_base_
01142 || addr >= (void *)((char *) this->local_cb_.mapped_base_
01143 + this->shared_cb_->sh_.mapped_size_))
01144 return -1;
01145
01146
01147 int first_time = 0;
01148 return this->map (first_time);
01149 }
01150
01151 int
01152 ACE_Pagefile_Memory_Pool::unmap (void)
01153 {
01154 #if (ACE_HAS_POSITION_INDEPENDENT_POINTERS == 1)
01155 ACE_BASED_POINTER_REPOSITORY::instance ()->unbind
01156 (this->local_cb_.mapped_base_);
01157 #endif
01158
01159
01160 this->shared_cb_ = 0;
01161
01162 if (this->local_cb_.sh_.mapped_size_ > 0)
01163 ::UnmapViewOfFile (this->local_cb_.mapped_base_);
01164
01165
01166 this->local_cb_.req_base_ =
01167 ACE_DEFAULT_PAGEFILE_POOL_BASE;
01168 this->local_cb_.mapped_base_ = 0;
01169 this->local_cb_.sh_.max_size_ =
01170 ACE_DEFAULT_PAGEFILE_POOL_SIZE;
01171 this->local_cb_.sh_.mapped_size_ = 0;
01172 this->local_cb_.sh_.free_offset_ =
01173 this->local_cb_.sh_.mapped_size_;
01174 this->local_cb_.sh_.free_size_ = 0;
01175
01176
01177 if (this->object_handle_ != 0)
01178 {
01179 ::CloseHandle (this->object_handle_);
01180 this->object_handle_ = 0;
01181 }
01182 return 0;
01183 }
01184
01185 int
01186 ACE_Pagefile_Memory_Pool::map (int &first_time,
01187 size_t append_bytes)
01188 {
01189 size_t map_size;
01190 void *map_addr;
01191
01192
01193 if (object_handle_ == 0)
01194 {
01195 #if (defined (ACE_HAS_WINNT4) && (ACE_HAS_WINNT4 != 0))
01196
01197 SECURITY_ATTRIBUTES sa;
01198 SECURITY_DESCRIPTOR sd;
01199 ::InitializeSecurityDescriptor (&sd,
01200 SECURITY_DESCRIPTOR_REVISION);
01201 ::SetSecurityDescriptorDacl (&sd,
01202 TRUE,
01203 0,
01204 FALSE);
01205 sa.nLength = sizeof (SECURITY_ATTRIBUTES);
01206 sa.lpSecurityDescriptor = &sd;
01207 sa.bInheritHandle = FALSE;
01208 #endif
01209
01210
01211 DWORD size_high;
01212 DWORD size_low;
01213 #if defined (ACE_WIN64)
01214 size_high = ACE_static_cast (DWORD,
01215 this->local_cb_.sh_.max_size_ >> 32);
01216 size_low = ACE_static_cast (DWORD,
01217 this->local_cb_.sh_.max_size_ & 0xFFFFFFFF);
01218 #else
01219 size_high = 0;
01220 size_low = this->local_cb_.sh_.max_size_;
01221 #endif
01222
01223 object_handle_ =
01224 ACE_TEXT_CreateFileMapping (INVALID_HANDLE_VALUE,
01225 #if (defined (ACE_HAS_WINNT4) && (ACE_HAS_WINNT4 != 0))
01226 &sa,
01227 #else
01228 0,
01229 #endif
01230 PAGE_READWRITE | SEC_RESERVE,
01231 size_high,
01232 size_low,
01233 this->backing_store_name_);
01234 if (object_handle_ == 0)
01235 return -1;
01236 first_time =
01237 ::GetLastError () == ERROR_ALREADY_EXISTS
01238 ? 0
01239 : 1;
01240 }
01241
01242
01243 if (this->shared_cb_ == 0)
01244 {
01245
01246
01247 this->shared_cb_ = (ACE_Pagefile_Memory_Pool::Control_Block *)
01248 ACE_MAP_FILE (this->object_handle_,
01249 FILE_MAP_WRITE,
01250 0,
01251 0,
01252 this->local_cb_.sh_.max_size_,
01253 this->local_cb_.req_base_);
01254 if (this->shared_cb_ == 0)
01255 return -1;
01256
01257
01258
01259 if (first_time)
01260 {
01261
01262 map_size =
01263 ACE_Pagefile_Memory_Pool::round_to_chunk_size
01264 (ACE_Pagefile_Memory_Pool::round_to_page_size
01265 ((int) sizeof(Control_Block))
01266 + append_bytes);
01267
01268 if (::VirtualAlloc ((void *) this->shared_cb_,
01269 map_size,
01270 MEM_COMMIT,
01271 PAGE_READWRITE) == 0)
01272 return -1;
01273
01274 this->shared_cb_->req_base_ = 0;
01275 this->shared_cb_->mapped_base_ = 0;
01276 this->local_cb_.mapped_base_ = this->shared_cb_;
01277 this->local_cb_.sh_.mapped_size_ = map_size;
01278 this->local_cb_.sh_.free_offset_ =
01279 round_to_page_size ((int) sizeof (Control_Block));
01280 this->local_cb_.sh_.free_size_ =
01281 this->local_cb_.sh_.mapped_size_ -
01282 this->local_cb_.sh_.free_offset_;
01283 this->shared_cb_->sh_ = this->local_cb_.sh_;
01284 }
01285
01286
01287
01288 else
01289 {
01290
01291 map_size =
01292 ACE_Pagefile_Memory_Pool::round_to_chunk_size
01293 ((int) sizeof (Control_Block));
01294
01295 if (::VirtualAlloc ((void *) this->shared_cb_,
01296 map_size,
01297 MEM_COMMIT,
01298 PAGE_READWRITE) == 0)
01299 return -1;
01300 this->local_cb_.mapped_base_ = this->shared_cb_;
01301 this->local_cb_.sh_.mapped_size_ = map_size;
01302 }
01303 }
01304
01305
01306
01307 if (this->shared_cb_->sh_.mapped_size_ >
01308 this->local_cb_.sh_.mapped_size_
01309 || append_bytes > 0)
01310 {
01311 map_size =
01312 (this->shared_cb_->sh_.mapped_size_ -
01313 this->local_cb_.sh_.mapped_size_)
01314 + ACE_Pagefile_Memory_Pool::round_to_chunk_size
01315 (append_bytes);
01316
01317 map_addr = (void *)((char *) this->shared_cb_ +
01318 this->local_cb_.sh_.mapped_size_);
01319
01320 if (::VirtualAlloc (map_addr,
01321 map_size,
01322 MEM_COMMIT,
01323 PAGE_READWRITE) == 0)
01324 return -1;
01325 else if (append_bytes > 0)
01326 {
01327 this->shared_cb_->sh_.mapped_size_ +=
01328 round_to_chunk_size (append_bytes);
01329 this->shared_cb_->sh_.free_size_ =
01330 this->shared_cb_->sh_.mapped_size_ -
01331 this->shared_cb_->sh_.free_offset_;
01332 }
01333 }
01334
01335
01336 this->local_cb_.sh_ =
01337 this->shared_cb_->sh_;
01338 #if (ACE_HAS_POSITION_INDEPENDENT_POINTERS == 1)
01339 ACE_BASED_POINTER_REPOSITORY::instance ()->bind
01340 (this->local_cb_.mapped_base_,
01341 this->local_cb_.sh_.mapped_size_);
01342 #endif
01343
01344 return 0;
01345 }
01346
01347 #endif
01348
01349 #if defined (ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION)
01350 template class ACE_Auto_Basic_Array_Ptr<char>;
01351 template class ACE_Unbounded_Set<char *>;
01352 template class ACE_Unbounded_Set_Iterator<char *>;
01353 #elif defined (ACE_HAS_TEMPLATE_INSTANTIATION_PRAGMA)
01354 #pragma instantiate ACE_Auto_Basic_Array_Ptr<char>
01355 #pragma instantiate ACE_Unbounded_Set<char *>
01356 #pragma instantiate ACE_Unbounded_Set_Iterator<char *>
01357 #endif