mirror of
https://github.com/mangosfour/server.git
synced 2025-12-13 13:37:05 +00:00
Imported MaNGOS revision 6767 from http://mangos.svn.sourceforge.net/svnroot/mangos/trunk/
This commit is contained in:
parent
d767495d5b
commit
800ee76535
3322 changed files with 903437 additions and 0 deletions
385
dep/ACE_wrappers/ace/Pagefile_Memory_Pool.cpp
Normal file
385
dep/ACE_wrappers/ace/Pagefile_Memory_Pool.cpp
Normal file
|
|
@ -0,0 +1,385 @@
|
|||
// $Id: Pagefile_Memory_Pool.cpp 82559 2008-08-07 20:23:07Z parsons $
|
||||
|
||||
// Pagefile_Memory_Pool.cpp
|
||||
#include "ace/Pagefile_Memory_Pool.h"
|
||||
|
||||
#if !defined (__ACE_INLINE__)
|
||||
#include "ace/Pagefile_Memory_Pool.inl"
|
||||
#endif /* __ACE_INLINE__ */
|
||||
|
||||
#include "ace/Log_Msg.h"
|
||||
#include "ace/Auto_Ptr.h"
|
||||
#include "ace/RW_Thread_Mutex.h"
|
||||
#include "ace/OS_NS_sys_mman.h"
|
||||
#include "ace/OS_NS_string.h"
|
||||
#include "ace/OS_NS_sys_stat.h"
|
||||
#include "ace/OS_NS_unistd.h"
|
||||
#include "ace/Truncate.h"
|
||||
|
||||
#if (ACE_HAS_POSITION_INDEPENDENT_POINTERS == 1)
|
||||
#include "ace/Based_Pointer_T.h"
|
||||
#include "ace/Based_Pointer_Repository.h"
|
||||
#endif /* ACE_HAS_POSITION_INDEPENDENT_POINTERS == 1 */
|
||||
|
||||
ACE_RCSID(ace, Pagefile_Memory_Pool, "$Id: Pagefile_Memory_Pool.cpp 82559 2008-08-07 20:23:07Z parsons $")
|
||||
|
||||
#if defined (ACE_WIN32) && !defined (ACE_HAS_PHARLAP)
|
||||
#if !defined (ACE_HAS_WINCE)
|
||||
#define ACE_MAP_FILE(_hnd, _access, _offHigh, _offLow, _nBytes, _baseAdd)\
|
||||
MapViewOfFileEx (_hnd, _access, _offHigh, _offLow, _nBytes, _baseAdd)
|
||||
#else //if !defined (ACE_HAS_WINCE)
|
||||
#define ACE_MAP_FILE(_hnd, _access, _offHigh, _offLow, _nBytes, _baseAdd)\
|
||||
MapViewOfFile (_hnd, _access, _offHigh, _offLow, _nBytes)
|
||||
#endif /* !ACE_HAS_WINCE */
|
||||
|
||||
ACE_BEGIN_VERSIONED_NAMESPACE_DECL
|
||||
|
||||
ACE_Pagefile_Memory_Pool_Options::ACE_Pagefile_Memory_Pool_Options (
|
||||
void *base_addr,
|
||||
size_t max_size)
|
||||
: base_addr_ (base_addr),
|
||||
max_size_ (max_size)
|
||||
{
|
||||
}
|
||||
|
||||
int
|
||||
ACE_Pagefile_Memory_Pool::release (int)
|
||||
{
|
||||
return this->unmap ();
|
||||
}
|
||||
|
||||
ACE_Pagefile_Memory_Pool::ACE_Pagefile_Memory_Pool (const ACE_TCHAR *backing_store_name,
|
||||
const OPTIONS *options)
|
||||
: shared_cb_ (0),
|
||||
object_handle_ (0),
|
||||
page_size_ (ACE_Pagefile_Memory_Pool::round_to_page_size (1))
|
||||
{
|
||||
// Initialize local copy of pool statistics.
|
||||
if (options != 0)
|
||||
{
|
||||
this->local_cb_.req_base_ = options->base_addr_;
|
||||
this->local_cb_.mapped_base_ = 0;
|
||||
this->local_cb_.sh_.max_size_ =
|
||||
options->max_size_;
|
||||
this->local_cb_.sh_.mapped_size_ = 0;
|
||||
this->local_cb_.sh_.free_offset_ =
|
||||
this->local_cb_.sh_.mapped_size_;
|
||||
this->local_cb_.sh_.free_size_ = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
this->local_cb_.req_base_ = 0;
|
||||
this->local_cb_.mapped_base_ = 0;
|
||||
this->local_cb_.sh_.max_size_ =
|
||||
this->round_to_chunk_size (page_size_) ;
|
||||
this->local_cb_.sh_.mapped_size_ = 0;
|
||||
this->local_cb_.sh_.free_offset_ =
|
||||
this->local_cb_.sh_.mapped_size_;
|
||||
this->local_cb_.sh_.free_size_ = 0;
|
||||
}
|
||||
|
||||
int update_backing_store_name = backing_store_name == 0 ? 0 : 1;
|
||||
|
||||
if (backing_store_name == 0)
|
||||
// Only create a new unique filename for the backing store file if
|
||||
// the user didn't supply one...
|
||||
backing_store_name = ACE_DEFAULT_PAGEFILE_POOL_NAME;
|
||||
|
||||
ACE_OS::strsncpy (this->backing_store_name_,
|
||||
backing_store_name,
|
||||
(sizeof this->backing_store_name_ / sizeof (ACE_TCHAR)));
|
||||
|
||||
if (update_backing_store_name
|
||||
&& ACE_OS::strlen (this->backing_store_name_) < sizeof this->backing_store_name_)
|
||||
ACE_OS::strcat (this->backing_store_name_,
|
||||
ACE_TEXT ("_"));
|
||||
}
|
||||
|
||||
void *
|
||||
ACE_Pagefile_Memory_Pool::acquire (size_t nbytes,
|
||||
size_t &rounded_bytes)
|
||||
{
|
||||
rounded_bytes = round_to_page_size (nbytes);
|
||||
void *result = 0;
|
||||
int first_time = 0;
|
||||
|
||||
// Check local_cb_ for consistency. Remap, if extra space is too
|
||||
// small and/or we didn't map the whole shared memory section
|
||||
if (this->shared_cb_->sh_.mapped_size_
|
||||
> this->local_cb_.sh_.mapped_size_
|
||||
|| this->shared_cb_->sh_.free_size_ < rounded_bytes)
|
||||
{
|
||||
size_t append = 0;
|
||||
if (rounded_bytes > this->shared_cb_->sh_.free_size_)
|
||||
append = rounded_bytes - this->shared_cb_->sh_.free_size_;
|
||||
|
||||
if (this->map (first_time, append) < 0)
|
||||
return result;
|
||||
}
|
||||
|
||||
// Get the block from extra space and update shared and local
|
||||
// control block
|
||||
if (this->shared_cb_->sh_.free_size_ < rounded_bytes)
|
||||
return result;
|
||||
|
||||
result = (void *)((char *) this->local_cb_.mapped_base_
|
||||
+ this->shared_cb_->sh_.free_offset_);
|
||||
this->shared_cb_->sh_.free_offset_ += rounded_bytes;
|
||||
this->shared_cb_->sh_.free_size_ -= rounded_bytes;
|
||||
this->local_cb_.sh_ = this->shared_cb_->sh_;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void *
|
||||
ACE_Pagefile_Memory_Pool::init_acquire (size_t nbytes,
|
||||
size_t &rounded_bytes,
|
||||
int &first_time)
|
||||
{
|
||||
// Map the shared memory and get information, if we created the
|
||||
// shared memory.
|
||||
if (this->map (first_time) < 0)
|
||||
return 0;
|
||||
|
||||
if (first_time != 0)
|
||||
// We created the shared memory. So we have to allocate the
|
||||
// requested memory.
|
||||
return this->acquire (nbytes, rounded_bytes);
|
||||
else
|
||||
// We just mapped the memory and return the base address
|
||||
return (void *)((char *) this->local_cb_.mapped_base_
|
||||
+ ACE_Pagefile_Memory_Pool::round_to_page_size
|
||||
((int) sizeof (Control_Block)));
|
||||
}
|
||||
|
||||
int
|
||||
ACE_Pagefile_Memory_Pool::seh_selector (void *ep)
|
||||
{
|
||||
DWORD ecode = ((EXCEPTION_POINTERS *) ep)->ExceptionRecord->ExceptionCode;
|
||||
|
||||
if (ecode == EXCEPTION_ACCESS_VIOLATION)
|
||||
{
|
||||
void * fault_addr = (void *)
|
||||
((EXCEPTION_POINTERS *) ep)->ExceptionRecord->ExceptionInformation[1];
|
||||
|
||||
if (this->remap (fault_addr) == 0)
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
ACE_Pagefile_Memory_Pool::remap (void *addr)
|
||||
{
|
||||
// If the shared memory is not mapped or the address, that caused
|
||||
// the memory fault is outside of the commited range of chunks, we
|
||||
// return.
|
||||
if (this->shared_cb_ == 0
|
||||
|| addr < this->local_cb_.mapped_base_
|
||||
|| addr >= (void *)((char *) this->local_cb_.mapped_base_
|
||||
+ this->shared_cb_->sh_.mapped_size_))
|
||||
return -1;
|
||||
|
||||
// We can solve the problem by committing additional chunks.
|
||||
int first_time = 0;
|
||||
return this->map (first_time);
|
||||
}
|
||||
|
||||
int
|
||||
ACE_Pagefile_Memory_Pool::unmap (void)
|
||||
{
|
||||
#if (ACE_HAS_POSITION_INDEPENDENT_POINTERS == 1)
|
||||
ACE_BASED_POINTER_REPOSITORY::instance ()->unbind
|
||||
(this->local_cb_.mapped_base_);
|
||||
#endif /* ACE_HAS_POSITION_INDEPENDENT_POINTERS == 1 */
|
||||
|
||||
// Cleanup cached pool pointer.
|
||||
this->shared_cb_ = 0;
|
||||
|
||||
if (this->local_cb_.sh_.mapped_size_ > 0)
|
||||
::UnmapViewOfFile (this->local_cb_.mapped_base_);
|
||||
|
||||
// Reset local pool statistics.
|
||||
this->local_cb_.req_base_ =
|
||||
ACE_DEFAULT_PAGEFILE_POOL_BASE;
|
||||
this->local_cb_.mapped_base_ = 0;
|
||||
this->local_cb_.sh_.max_size_ =
|
||||
ACE_DEFAULT_PAGEFILE_POOL_SIZE;
|
||||
this->local_cb_.sh_.mapped_size_ = 0;
|
||||
this->local_cb_.sh_.free_offset_ =
|
||||
this->local_cb_.sh_.mapped_size_;
|
||||
this->local_cb_.sh_.free_size_ = 0;
|
||||
|
||||
// Release the pool
|
||||
if (this->object_handle_ != 0)
|
||||
{
|
||||
::CloseHandle (this->object_handle_);
|
||||
this->object_handle_ = 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
ACE_Pagefile_Memory_Pool::map (int &first_time,
|
||||
size_t append_bytes)
|
||||
{
|
||||
size_t map_size;
|
||||
void *map_addr;
|
||||
|
||||
// Create file mapping, if not yet done
|
||||
if (object_handle_ == 0)
|
||||
{
|
||||
#if !defined (ACE_LACKS_WIN32_SECURITY_DESCRIPTORS)
|
||||
// Allow access by all users.
|
||||
SECURITY_ATTRIBUTES sa;
|
||||
SECURITY_DESCRIPTOR sd;
|
||||
::InitializeSecurityDescriptor (&sd,
|
||||
SECURITY_DESCRIPTOR_REVISION);
|
||||
::SetSecurityDescriptorDacl (&sd,
|
||||
TRUE,
|
||||
0,
|
||||
FALSE);
|
||||
sa.nLength = sizeof (SECURITY_ATTRIBUTES);
|
||||
sa.lpSecurityDescriptor = &sd;
|
||||
sa.bInheritHandle = FALSE;
|
||||
#endif /* ACE_LACKS_WIN32_SECURITY_DESCRIPTORS */
|
||||
|
||||
// Get an object handle to the named reserved memory object.
|
||||
DWORD size_high;
|
||||
DWORD size_low;
|
||||
#if defined (ACE_WIN64)
|
||||
size_high = static_cast<DWORD> (this->local_cb_.sh_.max_size_ >> 32);
|
||||
size_low = static_cast<DWORD> (this->local_cb_.sh_.max_size_ & 0xFFFFFFFF);
|
||||
#else
|
||||
size_high = 0;
|
||||
size_low = ACE_Utils::truncate_cast<DWORD> (this->local_cb_.sh_.max_size_);
|
||||
#endif
|
||||
|
||||
object_handle_ =
|
||||
ACE_TEXT_CreateFileMapping (INVALID_HANDLE_VALUE,
|
||||
#if !defined (ACE_LACKS_WIN32_SECURITY_DESCRIPTORS)
|
||||
&sa,
|
||||
#else
|
||||
0,
|
||||
#endif /* !ACE_LACKS_WIN32_SECURITY_DESCRIPTORS */
|
||||
PAGE_READWRITE | SEC_RESERVE,
|
||||
size_high,
|
||||
size_low,
|
||||
this->backing_store_name_);
|
||||
if (object_handle_ == 0)
|
||||
return -1;
|
||||
first_time =
|
||||
::GetLastError () == ERROR_ALREADY_EXISTS
|
||||
? 0
|
||||
: 1;
|
||||
}
|
||||
|
||||
// Do the initial mapping.
|
||||
if (this->shared_cb_ == 0)
|
||||
{
|
||||
// Map a view to the shared memory. Note: <MapViewOfFile[Ex]>
|
||||
// does *not* commit the pages!
|
||||
this->shared_cb_ = (ACE_Pagefile_Memory_Pool::Control_Block *)
|
||||
ACE_MAP_FILE (this->object_handle_,
|
||||
FILE_MAP_WRITE,
|
||||
0,
|
||||
0,
|
||||
this->local_cb_.sh_.max_size_,
|
||||
this->local_cb_.req_base_);
|
||||
if (this->shared_cb_ == 0)
|
||||
return -1;
|
||||
|
||||
// There was no previous mapping, so we map the first chunk and
|
||||
// initialize the shared pool statistics.
|
||||
if (first_time)
|
||||
{
|
||||
// 1st block is used to keep shared memory statistics.
|
||||
map_size =
|
||||
ACE_Pagefile_Memory_Pool::round_to_chunk_size
|
||||
(ACE_Pagefile_Memory_Pool::round_to_page_size
|
||||
((int) sizeof(Control_Block))
|
||||
+ append_bytes);
|
||||
|
||||
if (::VirtualAlloc ((void *) this->shared_cb_,
|
||||
map_size,
|
||||
MEM_COMMIT,
|
||||
PAGE_READWRITE) == 0)
|
||||
return -1;
|
||||
|
||||
this->shared_cb_->req_base_ = 0;
|
||||
this->shared_cb_->mapped_base_ = 0;
|
||||
this->local_cb_.mapped_base_ = this->shared_cb_;
|
||||
this->local_cb_.sh_.mapped_size_ = map_size;
|
||||
this->local_cb_.sh_.free_offset_ =
|
||||
round_to_page_size ((int) sizeof (Control_Block));
|
||||
this->local_cb_.sh_.free_size_ =
|
||||
this->local_cb_.sh_.mapped_size_ -
|
||||
this->local_cb_.sh_.free_offset_;
|
||||
this->shared_cb_->sh_ = this->local_cb_.sh_;
|
||||
}
|
||||
|
||||
// The shared memory exists, so we map the first chunk to the
|
||||
// base address of the pool to get the shared pool statistics.
|
||||
else
|
||||
{
|
||||
// 1st block is used to keep shared memory statistics.
|
||||
map_size =
|
||||
ACE_Pagefile_Memory_Pool::round_to_chunk_size
|
||||
((int) sizeof (Control_Block));
|
||||
|
||||
if (::VirtualAlloc ((void *) this->shared_cb_,
|
||||
map_size,
|
||||
MEM_COMMIT,
|
||||
PAGE_READWRITE) == 0)
|
||||
return -1;
|
||||
this->local_cb_.mapped_base_ = this->shared_cb_;
|
||||
this->local_cb_.sh_.mapped_size_ = map_size;
|
||||
}
|
||||
}
|
||||
|
||||
// If the shared memory is larger than the part we've already
|
||||
// committed, we have to remap it.
|
||||
if (this->shared_cb_->sh_.mapped_size_ >
|
||||
this->local_cb_.sh_.mapped_size_
|
||||
|| append_bytes > 0)
|
||||
{
|
||||
map_size =
|
||||
(this->shared_cb_->sh_.mapped_size_ -
|
||||
this->local_cb_.sh_.mapped_size_)
|
||||
+ ACE_Pagefile_Memory_Pool::round_to_chunk_size
|
||||
(append_bytes);
|
||||
|
||||
map_addr = (void *)((char *) this->shared_cb_ +
|
||||
this->local_cb_.sh_.mapped_size_);
|
||||
|
||||
if (::VirtualAlloc (map_addr,
|
||||
map_size,
|
||||
MEM_COMMIT,
|
||||
PAGE_READWRITE) == 0)
|
||||
return -1;
|
||||
else if (append_bytes > 0)
|
||||
{
|
||||
this->shared_cb_->sh_.mapped_size_ +=
|
||||
round_to_chunk_size (append_bytes);
|
||||
this->shared_cb_->sh_.free_size_ =
|
||||
this->shared_cb_->sh_.mapped_size_ -
|
||||
this->shared_cb_->sh_.free_offset_;
|
||||
}
|
||||
}
|
||||
|
||||
// Update local copy of the shared memory statistics.
|
||||
this->local_cb_.sh_ =
|
||||
this->shared_cb_->sh_;
|
||||
#if (ACE_HAS_POSITION_INDEPENDENT_POINTERS == 1)
|
||||
ACE_BASED_POINTER_REPOSITORY::instance ()->bind
|
||||
(this->local_cb_.mapped_base_,
|
||||
this->local_cb_.sh_.mapped_size_);
|
||||
#endif /* ACE_HAS_POSITION_INDEPENDENT_POINTERS == 1 */
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
ACE_END_VERSIONED_NAMESPACE_DECL
|
||||
|
||||
#endif /* ACE_WIN32 && !ACE_HAS_PHARLAP */
|
||||
Loading…
Add table
Add a link
Reference in a new issue