laocai 发表于 2011-3-4 21:03:39

在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

laocai 发表于 2011-3-4 21:05:05

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]
查看完整版本: 在ACE_Message_Block中使用Allocator内存池