平台崩溃之operator new异常(四)-2010-5-15

2010-5-15

今天早上接到老总电话,平台又卡住了。远程上去,是user breakpoint from at对话框,确定后,程序的调用栈大致为
new失败
ado的GetField...
binder.ObjectFromDB(prs)
QUERY_MDB_COMMAND((CMD_QUERY_SERVER,svr_id),CServerBinder,*server,result);
server_helper_.Get(serverid,&server);
server = dap_->GetServer(org->GetSvrID());
int CRTOPlugin::HandleSend(CMsg *msg,CWrappedMsg<> **wm)

查找附近代码,发现一处线程安全问题。

CTableInfo* HTX_DB_Helper::OpenTable(CDbAccessor *pdbor,const char *tbl_name) {
// string s = tbl_name;
// StringToUpper(s);
 string s = StringToUpper(tbl_name);
 CTableInfo *pti = this->FindTable(s.c_str());
 if (pti)
  return pti;
 pti = new CTableInfo();
 pti->SetDbAccessor(pdbor);
 if (pti->Init(tbl_name)) {
  delete pti;
  return 0;
 }
 use_tables_.bind(s.c_str(),pti);///<use_tables_容器是非线性安全的。

 return pti;
}

 use_tables_容器是非线性安全的,其定义如下
 typedef ACE_Hash_Map_Manager<ACE_CString,CTableInfo*,ACE_Null_Mutex> MAP_DB_TABLE;
 MAP_DB_TABLE use_tables_;
 
 所以,当多线程下同时访问OpenTable时,会存在不可预期。
 修改如下:
 typedef ACE_Hash_Map_Manager<ACE_CString,CTableInfo*,ACE_Recursive_Thread_Mutex> MAP_DB_TABLE;
 
 当绑定失败后,会存在内存泄漏(不过量很小),临时修改如下:
 
CTableInfo* HTX_DB_Helper::OpenTable(CDbAccessor *pdbor,const char *tbl_name) {
 CTableInfo *pti = 0;
 use_tables_.mutex().acquire();
 if( -1 == use_tables_.find(tbl_name) ){
  pti = new CTableInfo();
  pti->SetDbAccessor(pdbor);
  if (pti->Init(tbl_name)) {///<保证init没有异常抛出,否则会有死锁
   use_tables_.mutex().release();
   delete pti;
   return 0;
  }
  use_tables_.bind(tbl_name,pti); 
 }
 use_tables_.mutex().release();
 return pti;
}

ITableHandler* HTX_DB_Helper::NewTableHandler(CDbAccessor *pdbor,const char *tbl_name) {
 CTableInfo *tbl;
 string s = StringToUpper(tbl_name);
 tbl = this->FindTable(s.c_str());
 if (tbl==NULL)
  tbl = this->OpenTable(pdbor,s.c_str());///<当查找失败后,才OpenTable。Opentable是线程互斥的
 CTableHandler *th = 0;
 if (tbl) {
  th = new CTableHandler;
  th->Attach(tbl);
  th->SetDbAccessor(pdbor);
 }
 return th;
}
 
 替换程序,顺便把客户通、商机中心、计费系统的后台线程停掉,于16:40,在非debug模式下重启平台。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值