/*
* MemPool.cpp
*
* Created on: 2012-8-20
* Author: Administrator
*/
#include "MemPool.h"
#include <iostream>
#include <memory.h>
MemPool::MemPool(size_t _poolSize, size_t _poolCnts)
: m_poolSz(_poolSize)
, m_poolCnts(_poolCnts)
, m_memory(NULL)
, m_orgPoolArray(NULL)
, m_idlePoolLocker(PTHREAD_MUTEX_INITIALIZER)
, m_fullPoolLocker(PTHREAD_MUTEX_INITIALIZER)
, m_bPoolIsVaild(false)
, m_pWritingPool(NULL)
, m_pReadingPool(NULL)
, m_condMutex(PTHREAD_MUTEX_INITIALIZER)
, m_cond(PTHREAD_COND_INITIALIZER)
{
m_memory = new uchar_t[_poolSize];
size_t tSubPlSize = m_poolSz / m_poolCnts;
m_orgPoolArray = new PoolAttr[m_poolCnts];
uchar_t *tMem = m_memory;
for (size_t i = 0; i < m_poolCnts; i++)
{
PoolAttr &pool = m_orgPoolArray[i];
pool.org_ptr = tMem;
pool.wr_ptr = tMem;
pool.poolno = i;
pool.poolsz = tSubPlSize;
tMem += tSubPlSize;
this->m_idlePoolQueue.push(&pool);
}
m_bPoolIsVaild = true;
}
MemPool::~MemPool()
{
m_bPoolIsVaild = false;
pthread_mutex_destroy(&m_idlePoolLocker);
pthread_mutex_destroy(&m_fullPoolLocker);
pthread_mutex_destroy(&m_condMutex);
pthread_cond_destroy(&m_cond);
SAFE_DELETE_ARRAY(m_orgPoolArray);
SAFE_DELETE_ARRAY(m_memory);
}
int MemPool::set_data(const uchar_t *_data, const size_t _len)
{
//std::cout << "set data" << std::endl;
if(!m_bPoolIsVaild)
{
return MEM_POOL_IS_INVAILD;
}
if(NULL == m_pWritingPool)
{
m_pWritingPool = this->getIdlePool();
if(NULL == m_pWritingPool)
{
return MEM_POOL_IS_FULLED;
}
}
if((m_pWritingPool->datalen + _len) < m_pWritingPool->poolsz)
{
std::cout << "111111111111" << std::endl;
memcpy(m_pWritingPool->wr_ptr, _data, _len);
std::cout << "111111111111" << std::endl;
m_pWritingPool->wr_ptr += _len;
m_pWritingPool->datalen +=_len;
}
else
{
pthread_mutex_lock(&m_fullPoolLocker);
this->m_fullPoolQueue.push(m_pWritingPool);
m_pWritingPool = NULL;
pthread_mutex_unlock(&m_fullPoolLocker);
pthread_cond_signal(&m_cond);
return this->set_data(_data, _len);
}
return SUCCESS;
}
int MemPool::get_data(uchar_t *&_data, size_t &_len)
{
if(!m_bPoolIsVaild)
{
return MEM_POOL_IS_INVAILD;
}
pthread_mutex_lock(&m_fullPoolLocker);
if(this->m_fullPoolQueue.empty())
{
if(COND_WAIT_TIME_OUT == condTimedWait(3))
{
return MEM_POOL_IS_EMPTY;
}
}
m_pReadingPool = m_fullPoolQueue.front();
m_fullPoolQueue.pop();
pthread_mutex_unlock(&m_fullPoolLocker);
_data = m_pReadingPool->org_ptr;
_len = m_pReadingPool->datalen;
return SUCCESS;
}
void MemPool::release_pool()
{
pthread_mutex_lock(&m_idlePoolLocker);
m_pReadingPool->wr_ptr = m_pReadingPool->org_ptr;
m_pReadingPool->datalen = 0;
m_idlePoolQueue.push(m_pReadingPool);
m_pReadingPool = NULL;
pthread_mutex_unlock(&m_idlePoolLocker);
pthread_cond_signal(&m_cond);
}
PoolAttr* MemPool::getIdlePool()
{
PoolAttr* tmpPool = NULL;
pthread_mutex_lock(&m_idlePoolLocker);
if(m_idlePoolQueue.empty())
{
return NULL;
}
tmpPool = m_idlePoolQueue.front();
m_idlePoolQueue.pop();
pthread_mutex_unlock(&m_idlePoolLocker);
return tmpPool;
}
int MemPool::condTimedWait(size_t timeout)
{
pthread_mutex_lock(&m_condMutex);
time_t now = time(0);
now += timeout;
timespec timedwait;
timedwait.tv_sec = now;
if(ETIMEDOUT == pthread_cond_timedwait(&m_cond, &m_condMutex, &timedwait))
{
return COND_WAIT_TIME_OUT;
}
pthread_mutex_unlock(&m_condMutex);
return SUCCESS;
}