|  | 
 
| 本帖最后由 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 stlsoftinline 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
 | 
 |