在ACE_Message_Block中使用Allocator内存池
本帖最后由 laocai 于 2011-3-4 21:08 编辑在ACE_Message_Block的构造函数中可以传入相应的Allocator作为其里面数据的分配器,其中allocator_strategy专用于分配内部ACE_Data_Block里面的buffer,data_block_allocator用于分配内部的ACE_Data_Block,message_block_allocator用于内部构造新的ACE_Message_Block时使用。不过具体使用还得注意一些细节,如果这些细节没有注意很可能会用错,因此本人对在ACE_Message_Block中使用Allocator做了很浅的封装,使用起来就不容易出错了。附件代码中的Allocator是我用ACE写的Slab内存池,用起来效率还很不错。当然把模板参数实例化一下,也可以用其它的符合ACE的Allocator。
因上传附件的大小受限制,在这里贴代码,有兴趣的朋友可以跟我联系取工程文件和相关测试代码:
Message_Block_Oilfield.h:#ifndef __MESSAGE_BLOCK_OILFIELD_H__
#define __MESSAGE_BLOCK_OILFIELD_H__
# if !defined (ACE_LACKS_PRAGMA_ONCE)
#pragma once
# endif
#include "Slab_Malloc.h"
#include <ace/Message_Block.h>
#include <ace/String_Base.h>
#include <ace/ace_wchar.h>
#include <string>
// to_str_ptr is idea of c_str_ptr that is from stlsoft
inline const char *to_str_ptr(const char *data, bool &result_want_del)
{
result_want_del = false;
return data;
}
inline const char *to_str_ptr(const wchar_t *data, bool &result_want_del)
{
result_want_del = true;
return (ACE_Wide_To_Ascii::convert(data));
}
template <typename T>
inline const char *to_str_ptr(std::basic_string<T> const &s, bool &result_want_del)
{
return (to_str_ptr(s.c_str(), result_want_del));
}
template <typename T>
inline const char *to_str_ptr(ACE_String_Base<T> const &s, bool &result_want_del)
{
return (to_str_ptr(s.c_str(), result_want_del));
}
/**
* 在这里打个比喻,ACE_Message_Block就像石油,而
* Message_Block_Oilfield就像是油田。我们只管从
* “油田”中获取“石油”使用,不用考虑怎么把
* “石油”归还(释放)给“油田”。ACE_Message_Block
* 使用完毕后还是要释放的,但它可以像正常new出来
* 的那样进行释放。
*/
template <typename POOL_ALLOCATOR = Slab_Malloc_Allocator, typename POOL_ALLOCATOR_SINGLETON = Slab_Malloc_Allocator_Singleton>
class Message_Block_Oilfield
{
public:
ACE_Message_Block *get_message_block(void);
ACE_Message_Block *get_message_block(size_t len);
ACE_Message_Block *get_message_block(const char *data, int len);
ACE_Message_Block *get_message_block(const ACE_UINT8 *data, int len);
// 这个模板多了两个无用的参数,是因为模板函数不能偏特化,不得已而为之。
template <typename String_Type>
ACE_Message_Block *get_message_block(String_Type data, int not_use1, long not_use2);
public:
ACE_Data_Block *get_data_block(void);
ACE_Data_Block *get_data_block(size_t size,
ACE_Message_Block::ACE_Message_Type msg_type,
const char *msg_data,
ACE_Allocator *allocator_strategy = 0,
ACE_Lock *locking_strategy = 0);
private:
ACE_Message_Block *get_message_block(ACE_Data_Block *data_block,
ACE_Message_Block::Message_Flags flags,
ACE_Allocator *message_block_allocator);
private:
static POOL_ALLOCATOR *allocator_;
};
template<typename POOL_ALLOCATOR, typename POOL_ALLOCATOR_SINGLETON> inline ACE_Data_Block *
Message_Block_Oilfield<POOL_ALLOCATOR, POOL_ALLOCATOR_SINGLETON>::get_data_block(void)
{
ACE_Data_Block *db;
ACE_NEW_MALLOC_RETURN(db,
static_cast<ACE_Data_Block *>(allocator_->malloc(sizeof(ACE_Data_Block))),
ACE_Data_Block(0,
ACE_Message_Block::MB_DATA,
0,
allocator_,
0,
0,
allocator_),
0);
return db;
}
template<typename POOL_ALLOCATOR, typename POOL_ALLOCATOR_SINGLETON> inline ACE_Message_Block *
Message_Block_Oilfield<POOL_ALLOCATOR, POOL_ALLOCATOR_SINGLETON>::get_message_block(size_t len)
{
ACE_Message_Block *mb;
mb = this->get_message_block();
mb->size(len);
return mb;
}
template<typename POOL_ALLOCATOR, typename POOL_ALLOCATOR_SINGLETON> inline ACE_Message_Block *
Message_Block_Oilfield<POOL_ALLOCATOR, POOL_ALLOCATOR_SINGLETON>::get_message_block(const ACE_UINT8 *data, int len)
{
return (get_message_block(reinterpret_cast<const char *>(data), len));
}
template<typename POOL_ALLOCATOR, typename POOL_ALLOCATOR_SINGLETON> inline ACE_Message_Block *
Message_Block_Oilfield<POOL_ALLOCATOR, POOL_ALLOCATOR_SINGLETON>::get_message_block(ACE_Data_Block *data_block,
ACE_Message_Block::Message_Flags flags,
ACE_Allocator *message_block_allocator)
{
ACE_Message_Block *mb;
ACE_NEW_MALLOC_RETURN(mb,
static_cast<ACE_Message_Block *>(allocator_->malloc(sizeof(ACE_Message_Block))),
ACE_Message_Block(data_block, flags, message_block_allocator),
0);
return mb;
}
typedef ACE_Singleton<Message_Block_Oilfield<>, ACE_SYNCH_MUTEX> Message_Block_Oilfield_Singleton;
#define MESSAGE_BLOCK_OILFIELD Message_Block_Oilfield_Singleton::instance()
enum Parameter_Not_Use_Type
{
PARAMETER_NOT_USE_VAL = 0
};
#if defined (ACE_TEMPLATES_REQUIRE_SOURCE)
# include "Message_Block_Oilfield.cpp"
#endif
#if defined (ACE_TEMPLATES_REQUIRE_PRAGMA)
# pragma implementation ("Message_Block_Oilfield.cpp")
#endif
#endif Message_Block_Oilfield.cpp:#ifndef __MESSAGE_BLOCK_OILFIELD_CPP__
#define __MESSAGE_BLOCK_OILFIELD_CPP__
#include "Message_Block_Oilfield.h"
#if !defined (ACE_LACKS_PRAGMA_ONCE)
# pragma once
#endif /* ACE_LACKS_PRAGMA_ONCE */
template<typename POOL_ALLOCATOR, typename POOL_ALLOCATOR_SINGLETON>
POOL_ALLOCATOR *Message_Block_Oilfield<POOL_ALLOCATOR, POOL_ALLOCATOR_SINGLETON>::allocator_ = POOL_ALLOCATOR_SINGLETON::instance();
template<typename POOL_ALLOCATOR, typename POOL_ALLOCATOR_SINGLETON> ACE_Message_Block *
Message_Block_Oilfield<POOL_ALLOCATOR, POOL_ALLOCATOR_SINGLETON>::get_message_block(void)
{
ACE_Message_Block *mb;
ACE_Data_Block *db;
db = this->get_data_block();
mb = this->get_message_block(db, 0, allocator_);
return mb;
}
template<typename POOL_ALLOCATOR, typename POOL_ALLOCATOR_SINGLETON> ACE_Message_Block *
Message_Block_Oilfield<POOL_ALLOCATOR, POOL_ALLOCATOR_SINGLETON>::get_message_block(const char *data, int len)
{
ACE_Message_Block *mb;
ACE_Data_Block *db;
db = this->get_data_block(len, ACE_Message_Block::MB_DATA, data);
mb = this->get_message_block(db, 0, allocator_);
mb->wr_ptr(len);
return mb;
}
template<typename POOL_ALLOCATOR, typename POOL_ALLOCATOR_SINGLETON>
template<typename String_Type>
ACE_Message_Block *
Message_Block_Oilfield<POOL_ALLOCATOR, POOL_ALLOCATOR_SINGLETON>::get_message_block(String_Type data, int not_use1, long not_use2)
{
ACE_Message_Block *mb;
bool result_want_del = false;
const char *result_data = to_str_ptr(data, result_want_del);
mb = get_message_block(result_data, ACE_OS::strlen(result_data));
if (result_want_del)
delete []result_data;
return mb;
}
template<typename POOL_ALLOCATOR, typename POOL_ALLOCATOR_SINGLETON> ACE_Data_Block *
Message_Block_Oilfield<POOL_ALLOCATOR, POOL_ALLOCATOR_SINGLETON>::get_data_block(size_t size,
ACE_Message_Block::ACE_Message_Type msg_type,
const char *msg_data,
ACE_Allocator *allocator_strategy,
ACE_Lock *locking_strategy)
{
ACE_Data_Block *db;
ACE_NEW_MALLOC_RETURN(db,
static_cast<ACE_Data_Block *>(allocator_->malloc(sizeof(ACE_Data_Block))),
ACE_Data_Block(size,
msg_type,
0,
(allocator_strategy != 0) ? allocator_strategy : allocator_,
locking_strategy,
0,
allocator_),
0);
ACE_OS::memcpy(db->base(), msg_data, db->size());
return db;
}
#endif
页:
[1]