综合

img xiaoly_caep

VC下的ADO连接池

发表于2004/12/31 23:44:00  4129人阅读

由于工作需要,查找了很多关于数据库连接池的实现代码.但是发现很多都是JAVA  版本的.我试着改了一下,
代码如下:


/******************************************************************
*
*  ADO 对象的简单封装
*
*******************************************************************/

#ifndef _DATA_BASE_H_
#define _DATA_BASE_H_
#define CATCHERROR(ptr,a) catch(_com_error &e)/
       {/
        ErrorHandler(e,m_ErrStr);/
        ptr=NULL;/
        return a;/
       }

#define CATCHERRGET   catch(_com_error &e)/
       {/
         ErrorHandler(e,m_ErrStr);/
        sprintf(m_ErrStr,"%s/n**For Field Name:%s",m_ErrStr,FieldName);/
        return 0;/
       }

#import "c:/Program Files/Common Files/System/ADO/msado25.tlb" /
              rename("EOF", "EndOfFile")

typedef _RecordsetPtr RecPtr;
typedef _ConnectionPtr CnnPtr;

class Database;
class Table;


class Database
{
public:
 BOOL RollBack();
 BOOL CommitTrans();
 BOOL BeginTrans();
 void Close();
 CnnPtr m_Cnn;
 char m_ErrStr[500];
 Database();
 bool Open(char* UserName, char* Pwd,char* CnnStr);
 bool OpenTbl(int Mode, char* CmdStr, Table& Tbl);
 bool Execute(char* CmdStr, long * lRecordAffected, long Option);
 bool Execute(char* CmdStr, Table& Tbl);
 void GetErrorErrStr(char* ErrStr);
};

class Table{
public:
 int GetBinaryLen(char * FieldName);
 bool GetBinary(char * FieldName, BYTE * pValue);

 BOOL SetPageSize(int size);
 bool Move(int index);
 int GetRecordCount();
 bool Get(char * FieldNam, DWORD & value);
 bool Get(char * FieldName, BYTE * pValue);
 bool Get(char * FieldName, short & value);
 bool Get(char * FieldName, BYTE &value);
 RecPtr m_Rec;
 char m_ErrStr[500];
 int   m_pageSize;

 

 Table();
 void GetErrorErrStr(char* ErrStr);
 int ISEOF();
 HRESULT MoveNext();
 HRESULT MovePrevious();
 bool MoveFirst();
 HRESULT MoveLast();
 /*
 int AddNew();
 int Update();
 int Add(char* FieldName, char* FieldValue);
 int Add(char* FieldName,int FieldValue);
 int Add(char* FieldName,float FieldValue);
 int Add(char* FieldName,double FieldValue);
 int Add(char* FieldName,long FieldValue);
 */
 
 bool Get(char* FieldName, char* FieldValue);
 bool Get(char* FieldName,int& FieldValue);
 bool Get(char* FieldName,float& FieldValue);
 bool Get(char* FieldName,double& FieldValue);
 bool Get(char* FieldName,double& FieldValue,int Scale);
 bool Get(char* FieldName,long& FieldValue);
};

#endif _DATA_BASE_H_

//database.cpp
#include <stdio.h>
#include <iostream.h>
#include <comdef.h>
#include <conio.h>
#include <atlbase.h>
#include "stdafx.h"
#include "Database.h"
#include "htrdserver.h"

_variant_t  vtMissing1(DISP_E_PARAMNOTFOUND, VT_ERROR);

static void ErrorHandler(_com_error &e, char* ErrStr)
{
 
 sprintf(ErrStr,"Error:/n");
 sprintf(ErrStr,"%sCode = %08lx/n",ErrStr ,e.Error());
 sprintf(ErrStr,"%sCode meaning = %s/n", ErrStr, (char*) e.ErrorMessage());
 sprintf(ErrStr,"%sSource = %s/n", ErrStr, (char*) e.Source());
 sprintf(ErrStr,"%sDescription = %s",ErrStr, (char*) e.Description());
}

Database::Database()
{
 m_Cnn=NULL;
 sprintf(m_ErrStr,"NULL POINTER");
}

void Database::GetErrorErrStr(char* ErrStr)
{
 sprintf(ErrStr,"%s",m_ErrStr);
}

void Table::GetErrorErrStr(char* ErrStr)
{
 sprintf(ErrStr,"%s",m_ErrStr);
}

bool Database::Open(char* UserName, char* Pwd,char* CnnStr)
{
 //cnn->Open(strCnn,"sa","sa",NULL);
 try
 {
  HRESULT hr;
  hr    = m_Cnn.CreateInstance( __uuidof( Connection ) );
  m_Cnn->Open(CnnStr, UserName, Pwd, NULL);
 }
 
 CATCHERROR(m_Cnn,0)

 sprintf(m_ErrStr,"Success");
 return 1;
}

bool Database::OpenTbl(int Mode, char* CmdStr, Table &Tbl)
{
 if(m_Cnn==NULL)
 {
  Tbl.m_Rec=NULL;
  sprintf(m_ErrStr,"Invalid Connection");
  return 0;
 }
 RecPtr t_Rec=NULL;
 try
 {
  //t_Rec->putref_ActiveConnection(m_Cnn);
  //vtMissing<<-->>_variant_t((IDispatch *) m_Cnn, true)
  t_Rec.CreateInstance( __uuidof( Recordset ) );
  t_Rec->Open(CmdStr,_variant_t((IDispatch *) m_Cnn, true),adOpenStatic,adLockOptimistic,Mode);
 }
 
 CATCHERROR(Tbl.m_Rec,0)

 Tbl.m_Rec=t_Rec;
 sprintf(m_ErrStr,"Success");
 return 1;
}

bool Database::Execute(char* CmdStr, long * lRecordAffected, long Option)
{
 VARIANT var;
 var.vt = VT_I4;
 try
 {
  m_Cnn->Execute(CmdStr,&var,Option);
  *lRecordAffected = var.lVal;
 }
 catch(_com_error &e)
 {
  ErrorHandler(e,m_ErrStr);

  CString str;
  str.Format("数据库执行错误,消息:%s/r/n", m_ErrStr);
  OUTPUT_MSG(str);
  return 0;
 }
 sprintf(m_ErrStr,"Success");
 return 1;
}

bool Database::Execute(char* CmdStr, Table& Tbl)
{
// TRACE(CmdStr);
 int t = strlen(CmdStr);
 RecPtr t_Rec=NULL;
 try
 {
  t_Rec=m_Cnn->Execute(CmdStr,NULL,1);
 }

 catch(_com_error &e)
 {
  ErrorHandler(e,m_ErrStr);

  CString str;
  str.Format("数据库执行错误,消息:%s/r/n", m_ErrStr);
  OUTPUT_MSG(str);
  return 0;
 }

 sprintf(m_ErrStr,"Success");
 Tbl.m_Rec=t_Rec;
 sprintf(m_ErrStr,"Success");

 return 1;
}

Table::Table()
{
 m_Rec=NULL;
 m_pageSize = -1;


}

int Table::ISEOF()
{
 int rs;
 if(m_Rec==NULL)
 {
  sprintf(m_ErrStr,"Invalid Record");
  return -1;
 }
 try{
  rs=m_Rec->adoEOF;
 }
 
 CATCHERROR(m_Rec,-2)

 sprintf(m_ErrStr,"Success");
 return rs;
}

bool Table::Get(char* FieldName, char* FieldValue)
{
 try
 {
  _variant_t  vtValue;
  vtValue = m_Rec->Fields->GetItem(FieldName)->GetValue();
  if (vtValue.vt == VT_NULL)
  {
   sprintf((char *)FieldValue , "");
   return true;
  }
  VariantChangeType(&vtValue,&vtValue,0, VT_BYREF|VT_BSTR);
  sprintf(FieldValue,"%s",(LPCSTR)((_bstr_t)vtValue.bstrVal));
 }

 CATCHERRGET

 sprintf(m_ErrStr,"Success");
 return 1;
}

bool Table::Get(char* FieldName,int& FieldValue)
{
 try
 {
  _variant_t  vtValue;
  vtValue = m_Rec->Fields->GetItem(FieldName)->GetValue();
  
 
  VariantChangeType(&vtValue,&vtValue,0, VT_I4);
  
  FieldValue=vtValue.intVal;
 }

 CATCHERRGET

 sprintf(m_ErrStr,"Success");
 return 1;
}

bool Table::Get(char* FieldName,float& FieldValue)
{
 try
 {
  _variant_t  vtValue;
  vtValue = m_Rec->Fields->GetItem(FieldName)->GetValue();
  if (vtValue.vt == VT_NULL)
  {
   FieldValue = 0;
   return true;
  }
  VariantChangeType(&vtValue,&vtValue,0, VT_R4);
  
  FieldValue=vtValue.fltVal;
 }

 CATCHERRGET

 sprintf(m_ErrStr,"Success");
 return 1;
}

bool Table::Get(char* FieldName,double& FieldValue)
{
 try
 {
  _variant_t  vtValue;
  vtValue = m_Rec->Fields->GetItem(FieldName)->GetValue();
  if (vtValue.vt == VT_NULL)
  {
   FieldValue = 0;
   return true;
  }
  
  
  VariantChangeType(&vtValue,&vtValue,0, VT_R8);

  FieldValue = vtValue.dblVal;
  //GetDec(vtValue,FieldValue,3);
 }

 CATCHERRGET
  
  sprintf(m_ErrStr,"Success");
 return 1;
}

HRESULT Table::MoveNext()
{
 HRESULT hr;
 try
 {
  hr=m_Rec->MoveNext();
 }
 catch(_com_error &e)
 {
  ErrorHandler(e,m_ErrStr);
  //m_Rec=NULL;
  return -2;
 }
 sprintf(m_ErrStr,"Success");
 return hr;
}

HRESULT Table::MovePrevious()
{
 HRESULT hr;
 try
 {
  hr=m_Rec->MovePrevious();
 }
 catch(_com_error &e)
 {
  ErrorHandler(e,m_ErrStr);
  //m_Rec=NULL;
  return -2;
 }
 sprintf(m_ErrStr,"Success");
 return hr;
}

bool Table::MoveFirst()
{
 HRESULT hr;
 try
 {
  hr=m_Rec->MoveFirst();
 }
 catch(_com_error &e)
 {
  ErrorHandler(e,m_ErrStr);
  //m_Rec=NULL;
  return false;
 }
 sprintf(m_ErrStr,"Success");
 return true;
}

HRESULT Table::MoveLast()
{
 HRESULT hr;
 try
 {
  hr=m_Rec->MoveLast();
 }
 catch(_com_error &e)
 {
  ErrorHandler(e,m_ErrStr);
  //m_Rec=NULL;
  return -2;
 }
 sprintf(m_ErrStr,"Success");
 return hr;
}

void Database::Close()
{
 try
 {
  m_Cnn = NULL;
 }
 catch (_com_error e)
 {
  LPCTSTR lpsz = e.ErrorMessage();
 }
 
 
}

bool Table::Get(char *FieldName, BYTE &value)
{
 try
 {
  _variant_t  vtValue;
  vtValue = m_Rec->Fields->GetItem(FieldName)->GetValue();
  if (vtValue.vt == VT_NULL)
  {
   value = 0;
   return true;
  }
 
  VariantChangeType(&vtValue,&vtValue,0, VT_UI1);
  value=vtValue.bVal;
 }
 
 CATCHERRGET
  
  sprintf(m_ErrStr,"Success");
 return 1;

}

bool Table::Get(char *FieldName, short &value)
{
 
 try
 {
  _variant_t  vtValue;
  vtValue = m_Rec->Fields->GetItem(FieldName)->GetValue();

  if (vtValue.vt == VT_NULL)
  {
   value = 0;
   return true;
  }
 
  VariantChangeType(&vtValue,&vtValue,0, VT_I2);
  value=vtValue.iVal;
 }
 
 CATCHERRGET
  
  sprintf(m_ErrStr,"Success");
 return 1;

}

bool Table::Get(char *FieldName, BYTE *pValue)
{
 try
 {
  _variant_t  vtValue;
  vtValue = m_Rec->Fields->GetItem(FieldName)->GetValue();
  if (vtValue.vt == VT_NULL)
  {
   sprintf((char *)pValue , "");
   return true;
  }
  VariantChangeType(&vtValue,&vtValue,0, VT_BSTR);
  
  sprintf((char *)pValue,"%s",(LPCSTR)((_bstr_t)vtValue.bstrVal));
 }
 
 CATCHERRGET
  
  sprintf(m_ErrStr,"Success");
 return 1;
}

bool Table::Get(char *FieldName, DWORD &value)
{
 try
 {
  _variant_t  vtValue;
  vtValue = m_Rec->Fields->GetItem(FieldName)->GetValue();
  if (vtValue.vt == VT_NULL)
  {
   value = 0;
   return true;
  }


  VariantChangeType(&vtValue,&vtValue,0, VT_I4);
  
  value = vtValue.lVal;
 }
 
 CATCHERRGET
  
  sprintf(m_ErrStr,"Success");
 return 1;
 

}

int Table::GetRecordCount()
{
 if (m_Rec == NULL)
  return 0;
 
 int ret = 0;
 if (!ISEOF())
  MoveFirst();
 
 while(!ISEOF())
 {
  ret++;
  MoveNext();
 }
 
 return ret;
}

bool Table::Move(int index)
{
 if (index == 0)
  return true;
 
 try
 {
  m_Rec->Move(index);
 }
 catch (_com_error e)
 {
  LPCTSTR lpsz = e.ErrorMessage();
 }
 
  sprintf(m_ErrStr,"Success");
 return 1;
}


BOOL Database::BeginTrans()
{
 
 if (m_Cnn == NULL)
  return FALSE;

 try
 {
  m_Cnn->BeginTrans();
 }
 catch(_com_error e)
 {
  LPCTSTR lpsz = e.ErrorMessage();
  return FALSE;
 }
 return TRUE;
}

BOOL Database::CommitTrans()
{
 if (m_Cnn == NULL)
  return FALSE;
 try
 {
  m_Cnn->CommitTrans();
 }
 catch(_com_error e)
 {
  LPCTSTR lpsz = e.ErrorMessage();
  return FALSE;
 }
 return TRUE;
}

BOOL Table::SetPageSize(int size)
{
 if (m_Rec == NULL)
  return FALSE;
 if (GetRecordCount() < size)
  return FALSE;
 
 m_pageSize = size;
 
 return TRUE;
}

 

BOOL Database::RollBack()
{
 if (m_Cnn == NULL)
  return FALSE;
 try
 {
  m_Cnn->RollbackTrans();
 }
 catch(_com_error e)
 {
  LPCTSTR lpsz = e.ErrorMessage();
  return FALSE;
 }
 return TRUE;
}

/*
 *   purpose:  get the binary filed value from data base
 *    the memory of pValue must be allocated by the user.
 *    the length of pValue is known as before.
 */
bool Table::GetBinary(char *FieldName, BYTE *pValue)
{
 HRESULT hr = -1;
 try
 {
  _StreamPtr   m_pStream;
 
  hr = m_pStream.CreateInstance(__uuidof(Stream));
  m_pStream->PutType(adTypeBinary);
  
  _variant_t vtEmpty (DISP_E_PARAMNOTFOUND, VT_ERROR);
  _bstr_t bstrEmpty(L"");
  
  hr = m_pStream->Open(vtEmpty,adModeUnknown,adOpenStreamUnspecified,
   bstrEmpty, bstrEmpty);

  hr = m_pStream->Write(m_Rec->Fields->GetItem(FieldName)->Value);
  m_pStream->Position = 0;

  _variant_t var(m_pStream->Read(adReadAll));
  LONG lDataLength = m_pStream->GetSize();

  BYTE * pBuff= (BYTE *)GlobalAlloc(GMEM_FIXED, lDataLength);
  
  if(var.vt == (VT_ARRAY | VT_UI1))
  {
   HRESULT hr = -1;
   hr = SafeArrayAccessData(var.parray, (void **)&pBuff);

   memcpy(pValue, pBuff, lDataLength);

   GlobalFree((HGLOBAL)pBuff);
  }
  else
  {
   GlobalFree((HGLOBAL)pBuff);
   return false;
  }

  m_pStream->Close();

 }
 catch ( _com_error e)
 {
  LPCTSTR lpsz = e.ErrorMessage();
  if (hr == 0)
   return true;
  else
   return false;

 }

 return true;
 
}

int Table::GetBinaryLen(char *FieldName)
{
 int nRet = 0;
 try
 {
  nRet = m_Rec->Fields->GetItem(FieldName)->ActualSize;
 }
 catch(_com_error e)
 {
  nRet = 0;
 }

 return nRet;
}

// ConnObject.h: interface for the CConnObject class.
//
//////////////////////////////////////////////////////////////////////

#if !defined(AFX_CONNOBJECT_H__2818382C_8737_44D0_B319_1032C614EFEE__INCLUDED_)
#define AFX_CONNOBJECT_H__2818382C_8737_44D0_B319_1032C614EFEE__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

#include "Database.h"

class CConnPool;

class CConnObject
{
public:
 CConnObject(CConnPool *  pool)
 {
  ASSERT(pool);
  pPool = pool;
 // conn = NULL;
  m_bInUse = FALSE;
  m_nLastEnd = 0;
  m_nLastBegin = 0;
  m_nUseCount   = 0;
  m_nTotalUseTime = 0;
 }
 ~CConnObject();
 // 用完本身不能关闭,交给连接池处理
 


public:
 //释放连接对象给连接池
 void Close();

 Database          conn;
 BOOL     m_bInUse;
 int      m_nLastEnd;   //最后一次使用结束时间
 int      m_nLastBegin;    //最后一次开始时间
 int      m_nUseCount;     //使用次数
 CConnPool *       pPool;
 int      m_nTotalUseTime;

public:

 //得到总得使用时间
 int  GetTotalUseTime()
 {
  return m_nTotalUseTime;
 }
};
CConnObject::~CConnObject()
{

}

void CConnObject::Close()
{
 m_nTotalUseTime += GetTickCount() - m_nLastBegin;
 pPool->Close(this);
}

#endif //
// ConnPool.h: interface for the CConnPool class.
//
//////////////////////////////////////////////////////////////////////

#if !defined(AFX_CONNPOOL_H__FD09CC72_3241_4A82_912F_06F92BE1CD54__INCLUDED_)
#define AFX_CONNPOOL_H__FD09CC72_3241_4A82_912F_06F92BE1CD54__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
 
#include <atlbase.h>

#include "ConnObject.h"
 
/***************************************
数据库连接池.
一个连接池对应于一个库
****************************************/

/*

*/
class CConnPool 
{
public:
 void OnTimer();
 static void __stdcall TimerProc(HWND hWnd, UINT msg, UINT id, DWORD dwTime);

 //得到一个连接
 CConnObject * GetConnect();
 //释放一个连接回连接池
 void Close(CConnObject * pConn);
 //销毁连接池
 void Destroy();
 //创建连接池  strConn: 连接串
 BOOL Init(CString strConn);

 CConnPool();
 virtual ~CConnPool();


public:

 UINT        m_nTimer;     //定时器
 
 CSimpleArray<CConnObject *>      m_listConn;   //连接链表

 UINT        m_nTimeOut;   //连接最大空闲时间
 UINT        m_ConnMax;    //连接数量上限
 UINT        m_ConnMin;    //连接数量下限
 UINT        m_nMaxCount;  //连接最大使用次数
 UINT        m_nMaxUseTime; //最大使用时间
 CString        m_strConn;    //连接串

 HANDLE                 m_cs;   //保证改变连接池状态时代码不终端

protected:

 //创建一个新的连接
 CConnObject * CreateNewConn();
};

#endif // !defined(AFX_CONNPOOL_H__FD09CC72_3241_4A82_912F_06F92BE1CD54__INCLUDED_)
// ConnPool.cpp: implementation of the CConnPool class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "HTRDServer.h"
#include "ConnPool.h"
#include "const_def.h"
#include "MyEvent.h"

#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////


CConnPool::CConnPool()
{

 m_ConnMin = CONN_MIN;
 m_nTimeOut = CONN_TIMEOUT;
 m_nMaxUseTime = CONN_MAX_USETIME;
 m_nMaxCount  =  500;

 m_cs = CreateEvent(NULL, TRUE, TRUE, "da8b4c9d-e4ef-4c9a-a6d2-941ee98400d2");

}

CConnPool::~CConnPool()
{
 Destroy();
 
}

BOOL CConnPool::Init(CString strConn)
{
 m_ConnMax = theApp.m_sysSetting.m_nConnCount;

 m_strConn = strConn;
 for (UINT i = 0;i < m_ConnMax; i++)
 {
  CConnObject * pObj = CreateNewConn();
  if (!pObj)
   return FALSE;
  m_listConn.Add(pObj);
 }
 
 return TRUE;

 //启动连接池维护计时器
// m_nTimer = SetTimer(0, 0, CONNPOOL_TIMER, (TIMERPROC)TimerProc);

}

void CConnPool::Destroy()
{
 for (int i = 0;i < m_listConn.GetSize(); i++)
 {
  m_listConn[i]->m_bInUse = FALSE;

   m_listConn[i]->conn.Close();
 // m_listConn[i]->conn->Release();

  delete   m_listConn[i];
 }

 m_listConn.RemoveAll();

 KillTimer(NULL, m_nTimer);
}
/*
 * 释放连接时需要保护数据一致性,所以使用 临界对象
 */
void CConnPool::Close(CConnObject *pConn)
{
 
 //回收!

 CMyEvent cs(m_cs);

 for (int i = 0;i < m_listConn.GetSize(); i++)
 {
  if (m_listConn[i] == pConn)
  {
   m_listConn[i]->m_bInUse = FALSE;
   m_listConn[i]->m_nUseCount++;
   m_listConn[i]->m_nLastEnd = ::GetTickCount();

   //判断使用次数是否过多,使用时间是否过多
   //如果过度使用该连接,则重新创建
   if (m_listConn[i]->m_nUseCount > (int)m_nMaxCount ||
    m_listConn[i]->GetTotalUseTime() > CONN_MAX_USETIME)
   {
    OUTPUT_MSG("有数据库连接对象使用过多,需要重新连接/r/n");
    
    m_listConn[i]->conn.Close();
    if (!m_listConn[i]->conn.Open("", "", m_strConn.GetBuffer(0)))
    {
     AfxMessageBox("重新数据库连接对象出错!, 系统退出!");
     ExitProcess(0);
    }
    m_listConn[i]->m_nLastBegin = 0;
    m_listConn[i]->m_nLastEnd = 0;
    m_listConn[i]->m_nTotalUseTime = 0;
    m_listConn[i]->m_nUseCount = 0;

   }
   
   return;
  }
   
 }


#ifdef _DEBUG
 AfxMessageBox("The connect object is no mine!");
#endif

}
/*
 * 得到连接时需要保护数据一致性,所以使用 临界对象
 */
CConnObject * CConnPool::GetConnect()
{
 CMyEvent cs(m_cs);

 CConnObject * pObj = NULL;
 for (int i = 0;i < m_listConn.GetSize(); i++)
 {
  if (!m_listConn[i]->m_bInUse)
  {
   m_listConn[i]->m_bInUse = TRUE;
   pObj = m_listConn[i];
   pObj->m_nLastBegin = ::GetTickCount();
   
   return pObj;
  }
   
 }

 if ((pObj == NULL) &&
  (m_listConn.GetSize() < (int)m_ConnMax)) //connect object is no enough!
 {
  pObj = CreateNewConn();
  pObj->m_bInUse = TRUE;
  m_listConn.Add(pObj);
  return pObj;
 }


 //连接池已经满载!
 return NULL;
}

CConnObject * CConnPool::CreateNewConn()
{
 CConnObject * pConn = new CConnObject(this);
 
 
 if (!pConn->conn.Open("","",_bstr_t(m_strConn)))
  return NULL;
 
 
 return pConn;
}

void CConnPool::TimerProc(HWND hWnd, UINT msg, UINT id, DWORD dwTime)
{
// CHTRDServerApp * pApp = (CHTRDServerApp *)AfxGetApp();
// ASSERT(pPool);

// pPool->OnTimer();
 
}

/*
 * 调度连接池
 */
void CConnPool::OnTimer()

 
 DWORD dwTime = ::GetTickCount();
 for (int i = 0; i < m_listConn.GetSize(); i++)
 {
  if (m_listConn[i]->conn.m_Cnn->State == adStateClosed)
  {
   //delete from pool
   delete m_listConn[i];
   m_listConn.RemoveAt(i);
   TRACE("One conn closed!, delete from pool!/n");
  }
  else if (!m_listConn[i]->m_bInUse)
  {
   if (dwTime - m_listConn[i]->m_nLastEnd >= m_nTimeOut)
   {
    m_listConn[i]->conn.Close();
    delete m_listConn[i];
    m_listConn.RemoveAt(i);
    TRACE("One conn time out!/n");
   }
   else if (m_listConn[i]->m_nUseCount >= (int)m_nMaxCount)
   {
    m_listConn[i]->conn.Close();
    delete m_listConn[i];
    m_listConn.RemoveAt(i);
    TRACE("One conn use to much!/n");

   }
  }
  else if (m_listConn[i]->GetTotalUseTime() >= (int)m_nMaxUseTime)
  {
   m_listConn[i]->conn.Close();
   delete m_listConn[i];
   m_listConn.RemoveAt(i);

   TRACE("One conn use too long/n");
  }
 }

 //检查连接数,小于下限则添加到下限
 for (i = m_listConn.GetSize(); i < (int)m_ConnMin;i++)
 {
  CConnObject * pObj = CreateNewConn();
  ASSERT(pObj);
  m_listConn.Add(pObj);
 }
 
}




阅读全文
0 0

相关文章推荐

img
取 消
img