前面写了几篇文章了,最后的目的之一就是为了缓存ACE_Message_Block,代码简单,应该比先前的(《
ACE中ACE_Message_Block的缓存处理》)实现要好,先前在使用不当的情况下会有问题的,如clone
// MessageBlockManager.h
/**//**
* @date 2007.10.28
* @author PeakGao <peakgao163@163.com>
*/
#ifndef OM_MESSAGEBLOCKMANAGER_H
#define OM_MESSAGEBLOCKMANAGER_H
#include <ace/thread_mutex.h>
#include <ace/synch_traits.h>
#include <ace/message_block.h>
#include <ace/Lock_Adapter_T.h>
#include "MemPoolT.h"
#include "MemPoolAllocator.h"
namespace om{
class MessageBlockManager
{
typedef ACE_Lock_Adapter<ACE_SYNCH_MUTEX> MyLock;
My_Allocator mDataPool; /**//// 为数据缓冲分配
My_Allocator mDBPool; /**//// 为ACE_Data_Block对象本身分配
My_Allocator mMBPool; /**//// 为ACE_Message_Block对象本身分配
MyLock mLock; /**//// 同步锁
public:
static MessageBlockManager* instance();
MessageBlockManager();
~MessageBlockManager();
/**//// 初始化参数
void create(size_t bufSize, size_t growObjCount);
/**//// 清除缓冲池
void clear();
/**//// 分配一个消息块
ACE_Message_Block* alloc();
/**//// 释放指定的消息块
void free(ACE_Message_Block* mb);
};
} // namespace om
#endif // OM_MESSAGEBLOCKMANAGER_H
// MessageBlockManager.cpp
/**//**
* @date 2007.10.28
* @author PeakGao <peakgao163@163.com>
*/
#include "MessageBlockManager.h"
namespace om{
MessageBlockManager* MessageBlockManager::instance()
{
static MessageBlockManager* mbm = 0;
if (mbm == 0)
mbm = new MessageBlockManager();
return mbm;
}
MessageBlockManager::MessageBlockManager()
{
}
MessageBlockManager::~MessageBlockManager()
{
clear();
}
void MessageBlockManager::clear()
{
ACE_GUARD(MyLock, ace_mon, mLock);
mDataPool.clear();
mDBPool.clear();
mMBPool.clear();
}
void MessageBlockManager::create(size_t bufSize, size_t growObjCount)
{
mDataPool.create(bufSize, growObjCount);
mDBPool.create(sizeof(ACE_Data_Block), growObjCount);
mMBPool.create(sizeof(ACE_Message_Block), growObjCount);
}
ACE_Message_Block* MessageBlockManager::alloc()
{
ACE_GUARD_RETURN(MyLock, ace_mon, mLock, NULL);
void* mb_buf = mMBPool.alloc();
size_t data_size = mDataPool.getBlockSize();
// 直接调用构造
ACE_Message_Block* mb = ::new (mb_buf) ACE_Message_Block(
data_size, // size
ACE_Message_Block::MB_DATA, // type
0, // cont
0, // data
&mDataPool, // allocator_strategy
0, // locking_strategy 我们的mLock不要传入,因为前面有mMBPool.alloc()方法需要加锁
ACE_DEFAULT_MESSAGE_BLOCK_PRIORITY, // priority
ACE_Time_Value::zero, // execution_time
ACE_Time_Value::max_time, // deadline_time
&mDBPool, // data_block_allocator
&mMBPool // message_block_allocator
);
return mb;
}
void MessageBlockManager::free(ACE_Message_Block* mb)
{
ACE_GUARD(MyLock, ace_mon, mLock);
mb->release();
}
} // namespace om
演示代码:
void test()
{
using namespace om;
MessageBlockManager::instance()->create(1024, 256);
ACE_Message_Block* mb = MessageBlockManager::instance()->alloc();
mb->copy("1234567890", 11);
assert(strcmp(mb->base(), "1234567890") == 0);
ACE_Message_Block* mb_clone = mb->clone();
MessageBlockManager::instance()->free(mb);
MessageBlockManager::instance()->free(mb_clone);
MessageBlockManager::instance()->clear();
}
如果直接为ACE_Message_Block实现对象的new/delete操作,可能用起来更方便,大家可以试试,这里我不改了。