关闭

使用Pro C++实现数据库连接池采用多线程方式访问oracle数据库

2224人阅读 评论(0) 收藏 举报
分类:
 

使用Pro C++实现数据库连接池采用多线程方式访问oracle数据库

分类: Proc C/C++ 348人阅读 评论(0) 收藏 举报
数据库连接作为一种资源,我们的应用必须对之进行行之有效的管理。我们在访问数据库的时候,一般传统上采用先建立连接,然后使用该连接访问数据库,在使用完毕后,关闭该连接。这是我们经常采用的方法。该方法的好处是使用简单,不用对连接进行任何管理。但随之带来的缺点也就出现了,在应用需要频繁访问数据库的时候,这种方法就会使程序的效率十分低下,甚至有时候是不能满足应用的需要的。随着数据库连接池技术出现了,我们的应用根据访问数据库的频率动态决定创建连接的数量,以及决定在适当的时刻可以关闭一些数据库连接,用以节省这种资源。笔者最近在参考了网上大量代码的同时,实现了如何利用Pro C++使用数据库连接池完成了多线程对oracle数据库的访问。本着来源于网络,共享与网络的精神,和大家共同探讨,其中笔者的大部分代码来源是黄剑锋先生的共享代码,在此深表感谢。实现的基本功能如下:
1:可以设定最小的数据库连接数。
2:可以设定最大的数据库连接数。
3:当数据库某个连接空闲时间多长时间后,该连接池会自动断开连接以节省数据库连接资源。
4:提供了每个连接被使用的次数接口,方便统计和分析各个连接的情况。
5:提供了每个连接从上次访问完毕,懂查看的时候为止,已经空闲的时长,以秒为单位。
6:可以动态访问数据库存储过程,即存储过程的名字可以动态变化的。
 
CConnection:
  1. #pragma once  
  2.   
  3. #include <string>  
  4. #include <ace/OS.h>  
  5. #include <ace/Task.h>  
  6.   
  7. #define RT_OK   0  
  8. #define RT_NG  -1  
  9.   
  10. #define DB_CORE   0  
  11. #define DB_CORE_1 DB_CORE  
  12.   
  13. using namespace std;  
  14.   
  15. /*数据库错误原因*/  
  16. #define     RT_CONNECT_FAILED       -2  
  17. #define     RT_SOURCE_BUSY          -3  
  18. #define     RT_NO_DATA_FOUND        -4      /*when fetch cursor over or cursor is empty*/  
  19. #define     RT_DOUBLE_KEY           -5      /*unique constraint violated*/  
  20. #define     RT_OTHER_ERROR          -99  
  21.   
  22.   
  23. /****************************************数据库单连接******************************************/  
  24.   
  25. class CConnection  
  26. {  
  27. public:  
  28.     CConnection();  
  29.     CConnection(std::string db_string, std::string db_name);  
  30.     virtual ~CConnection();  
  31.     void settimerid(int timerid);  
  32.     int gettimerid();  
  33.     void addinvoke();  
  34.     void set(std::string db_string, std::string db_name);  
  35.     void set_db_string(std::string db_string);  
  36.     void set_db_name(std::string db_name);  
  37.     string get_db_string();  
  38.     string get_db_name();  
  39.     void output();  
  40.     void setidletimepoint();  
  41.     void* getctctx();  
  42.     static int multi_thread();  
  43.     int start();  
  44.     int stop();  
  45.     int connect();  
  46.     int disconnect();  
  47.     int reconnect();  
  48.     bool is_connected();  
  49.     /*示例*/  
  50.     int DML_DEMO_1();  
  51.     int DML_DEMO_2(int i);  
  52.     int DML_DEMO_3(int i);  
  53.     int DML_DEMO_4(char* inputparam, char* outputparam);  
  54.     int DML_DEMO_5(char* spname, char* inputparam, char* outputparam);  
  55. private:  
  56.     bool db_connected_;  
  57.     int  invoke_;  
  58.     time_t  idletimepoint_;  
  59.     int timerid_;  
  60.     /*数据库连接上下文*/  
  61.     void * ctx_;  
  62.     std::string db_string_; /*数据库连接串 user/pwd@sid*/  
  63.     std::string db_name_;   /*数据库连接别名*/  
  64.     int SqlError(void *_sqlca, const char *_FunName);  
  65. };  
  66.   
  67.   
  68. /*================================================================================================== 
  69.  * 项目名称: Proc++程序模板 
  70.  *     功能: 实现Proc预编译程序设计模式 
  71.  *     作者: huangjf 
  72.  *     联系: huangjf@ffcs.cn 
  73.  * 最近修改: 2010-7-15 
  74.  *     版本: v2.0.1 
  75.  ==================================================================================================*/  
  76.   
  77. #include <list>  
  78. #include <vector>  
  79. #include <algorithm>  
  80. #include <ace/OS.h>  
  81. #include <ace/FILE_Addr.h>  
  82. #include <ace/FILE_Connector.h>  
  83. #include <ace/FILE_IO.h>  
  84. #include "Logger.h"  
  85. #include "Connection.h"  
  86.   
  87. CConnection::CConnection()  
  88. {   
  89.     CLogger::createinstance()->logdebugmsg("(+)connection address=%08x\n"this);  
  90.     db_connected_ = false;  
  91.     ctx_ = NULL;  
  92.     db_string_ = "NULL";  
  93.     db_name_ = "NULL";  
  94.     invoke_ = 0;  
  95.     idletimepoint_ = time(NULL);  
  96.     timerid_ = -1;  
  97. }  
  98.   
  99. CConnection::CConnection(std::string db_string, std::string db_name)  
  100. {  
  101.     CLogger::createinstance()->logdebugmsg("(+)connection address=%08x\n"this);  
  102.     db_connected_ = false;  
  103.     ctx_ = NULL;  
  104.     db_string_ = db_string;  
  105.     db_name_ = db_name;  
  106.     invoke_ = 0;  
  107.     idletimepoint_ = time(NULL);  
  108.     timerid_ = -1;  
  109. }  
  110.   
  111. CConnection::~CConnection()  
  112. {  
  113.     CLogger::createinstance()->logdebugmsg("(-)connection address=%08x\n"this);  
  114.     db_connected_ = false;  
  115. }  
  116.   
  117.   
  118. void CConnection::settimerid(int timerid)  
  119. {  
  120.     timerid_ = timerid;  
  121. }  
  122.   
  123. int CConnection::gettimerid()  
  124. {  
  125.     return timerid_;  
  126. }  
  127.   
  128. void CConnection::addinvoke()  
  129. {  
  130.     invoke_++;  
  131. }  
  132.   
  133. void CConnection::set(std::string db_string, std::string db_name)  
  134. {  
  135.     db_string_ = db_string;  
  136.     db_name_   = db_name;  
  137. }  
  138.   
  139. void CConnection::set_db_string(std::string db_string)  
  140. {  
  141.     db_string_ = db_string;  
  142. }  
  143.   
  144. void CConnection::set_db_name(std::string db_name)  
  145. {  
  146.     db_name_ = db_name;  
  147. }  
  148.   
  149. string CConnection::get_db_string()  
  150. {  
  151.     return db_string_;  
  152. }  
  153.   
  154. void CConnection::setidletimepoint()  
  155. {  
  156.     time(&idletimepoint_);  
  157. }  
  158.   
  159. void CConnection::output()  
  160. {  
  161.     CLogger::createinstance()->logdebugmsg("connection=%08x invoke=%d idletime=%d\n"this, invoke_, time(NULL) - idletimepoint_);  
  162. }  
  163.   
  164. void*  CConnection::getctctx()  
  165. {  
  166.     return ctx_;  
  167. }  
  168.   
  169. string CConnection::get_db_name()  
  170. {  
  171.     return db_name_;  
  172. }  
  173.   
  174. int CConnection::multi_thread()  
  175. {  
  176.     #undef SQLCA  
  177.     EXEC SQL INCLUDE SQLCA;  
  178.   
  179.     EXEC SQL WHENEVER SQLERROR GOTO sqlerr;  
  180.   
  181.     EXEC SQL ENABLE THREADS;  
  182.       
  183.     CLogger::createinstance()->logdebugmsg("start database muti thread mode:success\n");  
  184.     return RT_OK;  
  185.       
  186. sqlerr:  
  187.     CLogger::createinstance()->logdebugmsg("start database muti thread mode:failure\n");  
  188.     return RT_NG;  
  189. }  
  190.   
  191. int CConnection::start()  
  192. {  
  193.     #undef SQLCA  
  194.     EXEC SQL INCLUDE SQLCA;  
  195.   
  196.     EXEC SQL WHENEVER SQLERROR GOTO sqlerr;  
  197.   
  198.     EXEC SQL BEGIN DECLARE SECTION;  
  199.         sql_context ctx = NULL;  
  200.     EXEC SQL END DECLARE SECTION;  
  201.   
  202.     EXEC SQL CONTEXT ALLOCATE :ctx;  
  203.   
  204.     this->ctx_ = ctx;  
  205.   
  206.     if (this->ctx_ != NULL)  
  207.     {  
  208.         CLogger::createinstance()->logdebugmsg("create database context:success\n");  
  209.         return RT_OK;  
  210.     }  
  211.     else  
  212.     {  
  213.         CLogger::createinstance()->logdebugmsg("create database context:failure\n");  
  214.         return RT_NG;  
  215.     }  
  216.   
  217. sqlerr:  
  218.     return (SqlError(&sqlca, "start()"));  
  219. }  
  220.   
  221. int CConnection::stop()  
  222. {  
  223.     #undef SQLCA  
  224.     EXEC SQL INCLUDE SQLCA;  
  225.   
  226.     EXEC SQL WHENEVER SQLERROR GOTO sqlerr;  
  227.   
  228.     EXEC SQL BEGIN DECLARE SECTION;  
  229.         sql_context ctx = NULL;  
  230.     EXEC SQL END DECLARE SECTION;  
  231.   
  232.     ctx = this->ctx_;  
  233.       
  234.     EXEC SQL CONTEXT FREE :ctx;  
  235.   
  236.     CLogger::createinstance()->logdebugmsg("destroy database context:success\n");  
  237.     return RT_OK;  
  238.       
  239. sqlerr:  
  240.     CLogger::createinstance()->logdebugmsg("destroy database context:failure\n");  
  241.     return (SqlError(&sqlca, "stop()"));  
  242. }  
  243.   
  244. int CConnection::connect()  
  245. {  
  246.     #undef SQLCA  
  247.     EXEC SQL INCLUDE SQLCA;  
  248.   
  249.     EXEC SQL WHENEVER SQLERROR GOTO sqlerr;  
  250.   
  251.     if (this->ctx_ == NULL) return RT_NG;  
  252.     if (this->db_connected_ == truereturn RT_OK;  
  253.   
  254.     EXEC SQL BEGIN DECLARE SECTION;  
  255.         VARCHAR vcConnStr[512]; /*数据库连接串 user/pwd@sid*/  
  256.         VARCHAR vcLinkName[64]; /*数据库连接别名*/  
  257.           
  258.         sql_context ctx = NULL; /*数据库连接上下文*/  
  259.     EXEC SQL END DECLARE SECTION;  
  260.   
  261.     ACE_OS::memset(&vcConnStr, 0x00, sizeof(vcConnStr));  
  262.     ACE_OS::memset(&vcLinkName, 0x00, sizeof(vcLinkName));  
  263.   
  264.     ACE_OS::strncpy((char *)vcConnStr.arr, this->db_string_.c_str(), this->db_string_.length());  
  265.     vcConnStr.len = ACE_OS::strlen((char *)vcConnStr.arr);  
  266.   
  267.     ACE_OS::strncpy((char *)vcLinkName.arr, this->db_name_.c_str(), this->db_name_.length());  
  268.     vcLinkName.len = ACE_OS::strlen((char *)vcLinkName.arr);  
  269.   
  270.     ctx = this->ctx_;  
  271.     EXEC SQL CONTEXT USE :ctx;  
  272.   
  273.     EXEC SQL CONNECT :vcConnStr AT :vcLinkName;  
  274.   
  275.     this->db_connected_ = true;  
  276.   
  277.     CLogger::createinstance()->logdebugmsg("connect to database [%s]:success\n"this->db_name_.c_str());  
  278.     return RT_OK;  
  279.   
  280. sqlerr:  
  281.     this->db_connected_ = false;  
  282.     CLogger::createinstance()->logdebugmsg("connect to database [%s]:failure\n"this->db_name_.c_str());  
  283.     return (SqlError(&sqlca, "connect()"));  
  284. }  
  285.   
  286. int CConnection::disconnect()  
  287. {  
  288.     #undef SQLCA  
  289.     EXEC SQL INCLUDE SQLCA;  
  290.   
  291.     EXEC SQL WHENEVER SQLERROR GOTO sqlerr;  
  292.   
  293.     if (this->ctx_ == NULL) return RT_NG;  
  294.     if (this->db_connected_ == falsereturn RT_OK;  
  295.   
  296.     EXEC SQL BEGIN DECLARE SECTION;  
  297.         VARCHAR vcLinkName[64]; /*数据库连接别名*/  
  298.           
  299.         sql_context ctx = NULL; /*数据库连接上下文*/  
  300.     EXEC SQL END DECLARE SECTION;  
  301.   
  302.     ACE_OS::memset(&vcLinkName, 0x00, sizeof(vcLinkName));  
  303.   
  304.     ACE_OS::strncpy((char *)vcLinkName.arr, this->db_name_.c_str(), this->db_name_.length());  
  305.     vcLinkName.len = ACE_OS::strlen((char *)vcLinkName.arr);  
  306.   
  307.     ctx = this->ctx_;  
  308.     EXEC SQL CONTEXT USE :ctx;  
  309.   
  310.     /*EXEC SQL AT :vcLinkName ROLLBACK WORK RELEASE;*/  
  311.     EXEC SQL AT :vcLinkName COMMIT WORK RELEASE;  
  312.   
  313.     this->db_connected_ = false;  
  314.   
  315.   
  316.     CLogger::createinstance()->logdebugmsg("disconnect to database [%s]:success\n"this->db_name_.c_str());  
  317.     return RT_OK;  
  318.   
  319. sqlerr:  
  320.     this->db_connected_ = false;  
  321.     CLogger::createinstance()->logdebugmsg("disconnect to database [%s]:failure\n"this->db_name_.c_str());  
  322.     return (SqlError(&sqlca, "disconnect()"));  
  323. }  
  324.   
  325. int CConnection::reconnect()  
  326. {  
  327.     this->disconnect();  
  328.       
  329.     this->connect();  
  330.       
  331.     return this->db_connected_==true ? RT_OK : RT_NG;  
  332. }  
  333.   
  334. bool CConnection::is_connected()  
  335. {  
  336.     return this->db_connected_;  
  337. }  
  338.   
  339. int CConnection::SqlError(void *_sqlca, const char *_FunName)  
  340. {  
  341.     #undef SQLCA  
  342.     EXEC SQL INCLUDE SQLCA;  
  343.   
  344.     EXEC SQL WHENEVER SQLERROR GOTO sqlerr;  
  345.   
  346.     if (this->ctx_ == NULL) return RT_NG;  
  347.     if (this->db_connected_ == falsereturn RT_NG;  
  348.   
  349.     int iRet;  
  350.   
  351.     EXEC SQL BEGIN DECLARE SECTION;  
  352.         VARCHAR vcLinkName[64]; /*数据库连接别名*/  
  353.           
  354.         sql_context ctx = NULL; /*数据库连接上下文*/  
  355.   
  356.         struct sqlca *sql_ca;  
  357.     EXEC SQL END DECLARE SECTION;  
  358.   
  359.     memset(&vcLinkName, 0x00, sizeof(vcLinkName));  
  360.   
  361.     ACE_OS::strncpy((char *)vcLinkName.arr, this->db_name_.c_str(), this->db_name_.length());  
  362.     vcLinkName.len = ACE_OS::strlen((char *)vcLinkName.arr);  
  363.   
  364.     ctx = this->ctx_;  
  365.     EXEC SQL CONTEXT USE :ctx;  
  366.   
  367.     sql_ca = (struct sqlca *)_sqlca;  
  368.   
  369.     if (sql_ca->sqlcode == 0)  
  370.     {  
  371.         return  RT_OK;  
  372.     }  
  373.     if (sql_ca->sqlcode == -1)  
  374.     {  
  375.         iRet = RT_DOUBLE_KEY;  
  376.     }  
  377.     else if (((sql_ca->sqlcode == -1012)||(sql_ca->sqlcode == -1041)||(sql_ca->sqlcode == -3114)||(sql_ca->sqlcode == -1003)||(sql_ca->sqlcode == 1455))||((sql_ca->sqlcode <= -12150)&&(sql_ca->sqlcode >= -12285))||((sql_ca->sqlcode >= -12699)&&(sql_ca->sqlcode <= -12500)))  
  378.     {  
  379.         iRet = RT_CONNECT_FAILED;  
  380.           
  381.         this->db_connected_ = false;  
  382.     }  
  383.     else if (sql_ca->sqlcode == 1403 )  /*no data found*/  
  384.     {  
  385.         iRet = RT_NO_DATA_FOUND;  
  386.     }  
  387.     else if (sql_ca->sqlcode == -54)  
  388.     {  
  389.         iRet = RT_SOURCE_BUSY;  
  390.     }  
  391.     else if (sql_ca->sqlcode == -1)  
  392.     {  
  393.         iRet = RT_DOUBLE_KEY;  /*unique constraint violated*/  
  394.     }  
  395.     else  
  396.     {  
  397.         iRet = RT_OTHER_ERROR;  
  398.     }  
  399.   
  400.     CLogger::createinstance()->logdebugmsg("database [%s] happen error:\nfunction    :[%s]\nresult    :[%d]\nerrorcode:[%d]\nerrorinfo:[%s]\n",   
  401.                     this->db_name_.c_str(),   
  402.                     _FunName,   
  403.                     iRet,   
  404.                     sql_ca->sqlcode,   
  405.                     sql_ca->sqlerrm.sqlerrmc);  
  406.       
  407.     /*ORA-01033: ORACLE initialization or shutdown in progress*/  
  408.     /*ORA-24324: service handle not initialized*/  
  409.     /*ORA-03114: not connected to ORACLE*/  
  410.     /*ORA-01089: immediate shutdown in progress - no operations are permitte */  
  411.     /*ORA-24909: call in progress. Current operation cancelled*/  
  412.     /*ORA-01012: not logged on*/  
  413.     /*ORA-01438: value larger than specified precision allows for this colum*/  
  414.     /*ORA-00001: 违反唯一约束条件*/  
  415.     /*ORA-01400: 无法将 NULL 插入*/  
  416.       
  417.     EXEC SQL AT :vcLinkName ROLLBACK WORK;  
  418.   
  419. sqlerr:  
  420.     return iRet;  
  421. }  
  422.   
  423. /********************************************************代码演示区**********************************************************/  
  424.   
  425.   
  426. /********************************************************************************************* 
  427. *功        能:SELECT示例 
  428. *输        入:NONE 
  429. * 
  430. *输        出:NONE 
  431. * 
  432. *返        回:RT_OK:成功,RT_NG:失败 
  433. *修 改  记 录:NONE 
  434. *********************************************************************************************/  
  435. int CConnection::DML_DEMO_1()  
  436. {  
  437.     #undef SQLCA  
  438.     EXEC SQL INCLUDE SQLCA;  
  439.   
  440.     EXEC SQL WHENEVER SQLERROR GOTO sqlerr;  
  441.   
  442.     if (this->ctx_ == NULL) return RT_NG;  
  443.     if (this->db_connected_ == falsereturn RT_NG;  
  444.   
  445.     EXEC SQL BEGIN DECLARE SECTION;  
  446.         VARCHAR vcLinkName[64]; /*数据库连接别名*/  
  447.   
  448.         sql_context ctx = NULL; /*数据库连接上下文*/  
  449.           
  450.         VARCHAR v_sysdate[32];  
  451.     EXEC SQL END DECLARE SECTION;  
  452.   
  453.     ACE_OS::memset(&vcLinkName, 0x00, sizeof(vcLinkName));  
  454.   
  455.     ACE_OS::strncpy((char *)vcLinkName.arr, this->db_name_.c_str(), this->db_name_.length());  
  456.     vcLinkName.len = ACE_OS::strlen((char *)vcLinkName.arr);  
  457.   
  458.     ctx = this->ctx_;  
  459.     EXEC SQL CONTEXT USE :ctx;  
  460.   
  461.     /*TODO 自有变量赋值*/  
  462.     ACE_OS::memset(&v_sysdate, 0x00, sizeof(v_sysdate));  
  463.   
  464.     EXEC SQL AT :vcLinkName   
  465.         SELECT to_char(sysdate, 'YYYY-MM-DD HH24:MI:SS') INTO :v_sysdate  
  466.         FROM DUAL;  
  467.   
  468.     CLogger::createinstance()->logdebugmsg("[%s]\n", (char *)v_sysdate.arr);   
  469.   
  470.     return RT_OK;  
  471. /* 
  472. notfound: 
  473.     CLogger::createinstance()->logdebugmsg("[%s]:DML_DEMO_1() ERROR:No record exist\n", this->db_name_.c_str()); 
  474.     return RT_NG; 
  475. */  
  476. sqlerr:  
  477.     return (SqlError(&sqlca, "DML_DEMO_1()"));  
  478. }  
  479.   
  480. /********************************************************************************************* 
  481. *功        能:INSERT INTO示例 
  482. *输        入:NONE 
  483. * 
  484. *输        出:NONE 
  485. * 
  486. *返        回:RT_OK:成功,RT_NG:失败 
  487. *修 改  记 录:NONE 
  488. *********************************************************************************************/  
  489. int CConnection::DML_DEMO_2(int i)  
  490. {  
  491.     #undef SQLCA  
  492.     EXEC SQL INCLUDE SQLCA;  
  493.   
  494.     EXEC SQL WHENEVER SQLERROR GOTO sqlerr;  
  495.     EXEC SQL WHENEVER NOT FOUND GOTO notfound;  
  496.   
  497.     if (this->ctx_ == NULL) return RT_NG;  
  498.     if (this->db_connected_ == falsereturn RT_NG;  
  499.   
  500.     EXEC SQL BEGIN DECLARE SECTION;  
  501.         VARCHAR vcLinkName[64]; /*数据库连接别名*/  
  502.           
  503.         sql_context ctx = NULL; /*数据库连接上下文*/  
  504.   
  505.         VARCHAR dyn_stmt[1024];  
  506.     EXEC SQL END DECLARE SECTION;  
  507.   
  508.     ACE_OS::memset(&vcLinkName, 0x00, sizeof(vcLinkName));  
  509.   
  510.     ACE_OS::strncpy((char *)vcLinkName.arr, this->db_name_.c_str(), this->db_name_.length());  
  511.     vcLinkName.len = ACE_OS::strlen((char *)vcLinkName.arr);  
  512.   
  513.     ctx = this->ctx_;  
  514.     EXEC SQL CONTEXT USE :ctx;  
  515.   
  516.     ACE_OS::memset(&dyn_stmt, 0x00, sizeof(dyn_stmt));  
  517.           
  518.     /*TODO 自有变量赋值*/   
  519.   
  520.     dyn_stmt.len = ACE_OS::snprintf((char *)dyn_stmt.arr, sizeof(dyn_stmt.arr), "insert into TB1(COL1, COL2) values(%d, sysdate)", i);  
  521.   
  522.     CLogger::createinstance()->logdebugmsg("SQL:[%s]\n", dyn_stmt.arr);  
  523.   
  524.     EXEC SQL AT :vcLinkName EXECUTE IMMEDIATE :dyn_stmt;  
  525.   
  526.     if (sqlca.sqlcode == 0)   
  527.     {  
  528.         CLogger::createinstance()->logdebugmsg("insert into TB1 table success\n");  
  529.     }  
  530.     else  
  531.     {  
  532.         CLogger::createinstance()->logdebugmsg("insert into TB1 table failure\n");  
  533.     }  
  534.       
  535.     EXEC SQL AT :vcLinkName COMMIT WORK;  
  536.   
  537.     return RT_OK;  
  538.   
  539. notfound:  
  540.   
  541.     CLogger::createinstance()->logdebugmsg("[%s]:DML_DEMO_2() ERROR:No record exist\n"this->db_name_.c_str());  
  542.     return RT_NG;  
  543.   
  544. sqlerr:  
  545.     return (SqlError(&sqlca, "DML_DEMO_2()"));  
  546. }  
  547.   
  548. /********************************************************************************************* 
  549. *功        能:PREPARE SELECT示例 
  550. *输        入:NONE 
  551. * 
  552. *输        出:NONE 
  553. * 
  554. *返        回:RT_OK:成功,RT_NG:失败 
  555. *修 改  记 录:NONE 
  556. *********************************************************************************************/  
  557. int CConnection::DML_DEMO_3(int i)  
  558. {  
  559.     #undef SQLCA  
  560.     EXEC SQL INCLUDE SQLCA;  
  561.   
  562.     EXEC SQL WHENEVER SQLERROR GOTO sqlerr;  
  563.     /*EXEC SQL WHENEVER NOT FOUND GOTO notfound;*/  
  564.   
  565.     if (this->ctx_ == NULL) return RT_NG;  
  566.     if (this->db_connected_ == falsereturn RT_NG;  
  567.   
  568.     EXEC SQL BEGIN DECLARE SECTION;  
  569.         VARCHAR vcLinkName[64]; /*数据库连接别名*/  
  570.   
  571.         sql_context ctx = NULL; /*数据库连接上下文*/  
  572.   
  573.         int     v_col1;  
  574.         VARCHAR v_col2[24];  
  575.           
  576.         VARCHAR dyn_stmt[1024];  
  577.     EXEC SQL END DECLARE SECTION;  
  578.   
  579.     ACE_OS::memset(&vcLinkName, 0x00, sizeof(vcLinkName));  
  580.   
  581.     ACE_OS::strncpy((char *)vcLinkName.arr, this->db_name_.c_str(), this->db_name_.length());  
  582.     vcLinkName.len = ACE_OS::strlen((char *)vcLinkName.arr);  
  583.   
  584.     ctx = this->ctx_;  
  585.     EXEC SQL CONTEXT USE :ctx;  
  586.   
  587.     /*TODO 自有变量赋值*/  
  588.     ACE_OS::memset(&dyn_stmt, 0x00, sizeof(dyn_stmt));  
  589.   
  590.     dyn_stmt.len = ACE_OS::snprintf((char *)dyn_stmt.arr, sizeof(dyn_stmt.arr), "SELECT COL1, to_char(COL2, 'YYYY-MM-DD HH24:MI:SS') FROM TB1 WHERE COL1=%d", i);  
  591.   
  592.     CLogger::createinstance()->logdebugmsg("SQL:[%s]\n", dyn_stmt.arr);  
  593.   
  594.     EXEC SQL AT :vcLinkName DECLARE S STATEMENT;  
  595.       
  596.     EXEC SQL AT :vcLinkName PREPARE S FROM :dyn_stmt;  
  597.       
  598.     EXEC SQL AT :vcLinkName DECLARE C_TB1_1 CURSOR FOR S;  
  599.       
  600.     EXEC SQL AT :vcLinkName OPEN C_TB1_1;  
  601.       
  602.         for (;;)  
  603.         {  
  604.             v_col1 = 0;  
  605.             ACE_OS::memset(&v_col2, 0x00, sizeof(v_col2));  
  606.   
  607.             EXEC SQL WHENEVER NOT FOUND DO BREAK;  
  608.             EXEC SQL FETCH C_TB1_1 INTO :v_col1, :v_col2;  
  609.             if (sqlca.sqlcode != 0) break;  
  610.   
  611.             CLogger::createinstance()->logdebugmsg("(%d):COL2=[%s]\n",  
  612.                                 v_col1,   
  613.                                 v_col2.arr);  
  614.         }  
  615.       
  616.     EXEC SQL AT :vcLinkName CLOSE C_TB1_1;  
  617.       
  618.     EXEC SQL AT :vcLinkName COMMIT WORK;  
  619.   
  620.     return RT_OK;  
  621. /* 
  622. notfound: 
  623.     CLogger::createinstance()->logdebugmsg("[%s]:DML_DEMO_3() ERROR:No record exist\n", this->db_name_.c_str()); 
  624.     return RT_NG; 
  625. */  
  626. sqlerr:  
  627.     return (SqlError(&sqlca, "DML_DEMO_3()"));  
  628. }  
  629.   
  630.   
  631.   
  632. /********************************************************************************************* 
  633. *功        能:EXECUTE PROCEDURE示例 
  634. *输        入:存储过程名, 存储过程入参 
  635. * 
  636. *输        出:存储过程返回值 
  637. * 
  638. *返        回:RT_OK:成功,RT_NG:失败 
  639. *修 改  记 录:NONE 
  640. *********************************************************************************************/  
  641.   
  642. int CConnection::DML_DEMO_4(char* inputparam, char* outputparam)  
  643. {  
  644.     #undef SQLCA  
  645.     EXEC SQL INCLUDE SQLCA;  
  646.   
  647.     EXEC SQL WHENEVER SQLERROR GOTO sqlerr;  
  648.     EXEC SQL WHENEVER NOT FOUND GOTO notfound;  
  649.       
  650.     if (this->ctx_ == NULL) return RT_NG;  
  651.     if (this->db_connected_ == falsereturn RT_NG;  
  652.   
  653.     EXEC SQL BEGIN DECLARE SECTION;  
  654.         VARCHAR vcLinkName[64]; /*数据库连接别名*/  
  655.         sql_context ctx = NULL; /*数据库连接上下文*/  
  656.         VARCHAR  v_input[512];  
  657.         VARCHAR  v_output[512];  
  658.     EXEC SQL END DECLARE SECTION;  
  659.   
  660.     ACE_OS::memset(&vcLinkName, 0x00, sizeof(vcLinkName));  
  661.     ACE_OS::strncpy((char *)vcLinkName.arr, this->db_name_.c_str(), this->db_name_.length());  
  662.     vcLinkName.len = ACE_OS::strlen((char *)vcLinkName.arr);  
  663.     ctx = this->ctx_;  
  664.     EXEC SQL CONTEXT USE :ctx;  
  665.   
  666.     /*TODO 自有变量赋值*/  
  667.     v_input.len = ACE_OS::snprintf((char *)v_input.arr, sizeof(v_input.arr),"%s",inputparam);  
  668.     ACE_OS::memset(&v_output, 0x00, sizeof(v_output));  
  669.   
  670.     /*执行PL/SQL块*/  
  671.     EXEC SQL AT :vcLinkName EXECUTE  
  672.     BEGIN  
  673.         sp_test(:v_input, :v_output);     
  674.     END;    
  675.     END-EXEC;    
  676.   
  677.     if (sqlca.sqlcode == 0)   
  678.     {  
  679.         ACE_OS::snprintf((char *)outputparam, v_output.len, "%s", v_output.arr);  
  680.         outputparam[ v_output.len + 1] = '\0';  
  681.         CLogger::createinstance()->logdebugmsg("storage procedure (sp_test) success, result=%s\n", outputparam);  
  682.     }  
  683.     else  
  684.     {  
  685.         CLogger::createinstance()->logdebugmsg("storage procedure (sp_test) failure\n");  
  686.     }  
  687.       
  688.     EXEC SQL AT :vcLinkName COMMIT WORK;  
  689.   
  690.     return RT_OK;  
  691. notfound:  
  692.     CLogger::createinstance()->logdebugmsg("[%s]:DML_DEMO_4() ERROR:No record exist\n"this->db_name_.c_str());  
  693.     return RT_NG;  
  694. sqlerr:  
  695.     return (SqlError(&sqlca, "DML_DEMO_4()"));  
  696. }  
  697.   
  698.   
  699.   
  700. /********************************************************************************************* 
  701. *功        能:PREPARE PL/SQL块示例 
  702. *输        入:NONE 
  703. * 
  704. *输        出:NONE 
  705. * 
  706. *返        回:RT_OK:成功,RT_NG:失败 
  707. *修 改  记 录:NONE 
  708. *********************************************************************************************/  
  709. int CConnection::DML_DEMO_5(char* spname, char* inputparam, char* outputparam)  
  710. {  
  711.     #undef SQLCA  
  712.     EXEC SQL INCLUDE SQLCA;  
  713.   
  714.     EXEC SQL WHENEVER SQLERROR GOTO sqlerr;  
  715.     EXEC SQL WHENEVER NOT FOUND GOTO notfound;  
  716.   
  717.     if (this->ctx_ == NULL) return RT_NG;  
  718.     if (this->db_connected_ == falsereturn RT_NG;  
  719.   
  720.     EXEC SQL BEGIN DECLARE SECTION;  
  721.         VARCHAR vcLinkName[64]; /*数据库连接别名*/  
  722.   
  723.         sql_context ctx = NULL; /*数据库连接上下文*/  
  724.   
  725.         VARCHAR v_input[512];  
  726.         VARCHAR v_output[512];  
  727.         VARCHAR dyn_stmt[1024];  
  728.   
  729.     EXEC SQL END DECLARE SECTION;  
  730.   
  731.     ACE_OS::memset(&vcLinkName, 0x00, sizeof(vcLinkName));  
  732.     ACE_OS::strncpy((char *)vcLinkName.arr, this->db_name_.c_str(), this->db_name_.length());  
  733.     vcLinkName.len = ACE_OS::strlen((char *)vcLinkName.arr);  
  734.   
  735.     ctx = this->ctx_;  
  736.     EXEC SQL CONTEXT USE :ctx;  
  737.   
  738.     /*TODO 自有变量赋值*/  
  739.     ACE_OS::memset(&dyn_stmt, 0x00, sizeof(dyn_stmt));  
  740.     dyn_stmt.len = ACE_OS::snprintf((char *)dyn_stmt.arr, sizeof(dyn_stmt.arr), "BEGIN %s(:v_input,:v_output); END;", spname);  
  741.   
  742.     v_input.len =  ACE_OS::snprintf((char *)v_input.arr, sizeof(v_input), "%s", inputparam);  
  743.     ACE_OS::memset(&v_output, 0x00, sizeof(v_output));  
  744.   
  745.   
  746.     //CLogger::createinstance()->logdebugmsg("SQL: [%s]\n", dyn_stmt.arr);  
  747.   
  748.   
  749.     EXEC SQL AT :vcLinkName DECLARE SS STATEMENT;  
  750.       
  751.     EXEC SQL AT :vcLinkName PREPARE SS FROM :dyn_stmt;  
  752.   
  753.     EXEC SQL AT :vcLinkName EXECUTE SS USING :v_input, :v_output;  
  754.   
  755.     if (sqlca.sqlcode == 0)   
  756.     {  
  757.         ACE_OS::snprintf((char *)outputparam, v_output.len, "%s", v_output.arr);  
  758.         outputparam[ v_output.len + 1] = '\0';  
  759.         CLogger::createinstance()->logdebugmsg("storage procedure (%s) success and result=%s\n", spname, outputparam);  
  760.     }  
  761.     else  
  762.     {  
  763.         CLogger::createinstance()->logdebugmsg("storage procedure (%s) failure\n", spname);  
  764.     }  
  765.       
  766.     EXEC SQL AT :vcLinkName COMMIT WORK;  
  767.   
  768.     return RT_OK;  
  769.   
  770. notfound:  
  771.     CLogger::createinstance()->logdebugmsg("[%s]:DML_DEMO_5() ERROR:No record exist\n"this->db_name_.c_str());  
  772.     return RT_NG;  
  773.   
  774. sqlerr:  
  775.     return (SqlError(&sqlca, "DML_DEMO_5()"));  
  776. }  
cconnectionpool:
  1. #pragma once  
  2. #include "Connection.h"  
  3. #include "ace/Synch.h"  
  4. #include <list>  
  5.   
  6. using namespace std;  
  7.   
  8. typedef list<CConnection*> CONNECTIONLIST;  
  9.   
  10.   
  11. class CConnectionpool : ACE_Event_Handler  
  12. {  
  13. public:  
  14.     CConnectionpool(string dbstring, string dbname);  
  15.     CConnectionpool(string dbstring, string dbname,int maxconn, int minconn, int m_keepalive);  
  16.     ~CConnectionpool(void);  
  17. private:  
  18.     CONNECTIONLIST  m_idlelist;  
  19.     CONNECTIONLIST  m_busylist;  
  20.     string m_dbstring;  
  21.     string m_dbname;  
  22.     int m_maxconn;  
  23.     int m_minconn;  
  24.     int m_keepalive;  
  25.     ACE_Thread_Mutex m_mutex;  
  26.     ACE_Condition<ACE_Thread_Mutex> *m_pcondition;  
  27.     bool active_;  
  28. private:  
  29.     CConnection* applyfor();  
  30.     bool payback(CConnection* pconn);  
  31.     bool removefromidlelist(CConnection* pconn);  
  32.     int addtimer(CConnection *pconn);  
  33.     int removetimer(CConnection *pconn);  
  34.     virtual int handle_timeout(const ACE_Time_Value &tv, const void *arg);  
  35.     int getconnectionsize();  
  36. public:  
  37.     bool start();  
  38.     bool stop();  
  39.     int  executesp(char* spname, char* inputparam, char* outparam);  
  40.     void output();  
  41.     bool getactive();  
  42. };  
  43.   
  44. #include "Connectionpool.h"  
  45. #include "ace/Reactor.h"  
  46. #include "Logger.h"  
  47.   
  48.   
  49.   
  50. CConnectionpool::CConnectionpool(string dbstring, string dbname)  
  51. {  
  52.     m_dbstring = dbstring;  
  53.     m_dbname = dbname;  
  54.     m_minconn = 2;  
  55.     m_maxconn = 4;  
  56.     m_keepalive = 10;  
  57.     m_pcondition = new ACE_Condition<ACE_Thread_Mutex>(m_mutex);  
  58. }  
  59.   
  60. CConnectionpool::CConnectionpool(string dbstring, string dbname, int minconn, int maxconn, int keepalive)  
  61. {  
  62.     m_dbstring = dbstring;  
  63.     m_dbname = dbname;    
  64.     m_minconn = minconn;  
  65.     m_maxconn = maxconn;  
  66.     m_keepalive = keepalive;  
  67.     m_pcondition = new ACE_Condition<ACE_Thread_Mutex>(m_mutex);  
  68. }  
  69.   
  70. CConnectionpool::~CConnectionpool(void)  
  71. {  
  72.     delete m_pcondition;  
  73. }  
  74.   
  75. bool CConnectionpool::start()  
  76. {  
  77.     bool result = false;  
  78.     if (CConnection::multi_thread() == RT_OK)  
  79.     {  
  80.         active_ = true;  
  81.         result = true;  
  82.     }  
  83.     return result;  
  84. }  
  85.   
  86. bool CConnectionpool::stop()  
  87. {  
  88.     active_ = false;  
  89.     while(m_busylist.size() != 0)  
  90.     {  
  91.         ACE_OS::sleep(1);  
  92.     }  
  93.     printf("all connections are idle, we can destroy them\n");  
  94.   
  95.     typedef CONNECTIONLIST::iterator ITERATOR;  
  96.     ITERATOR LI;  
  97.   
  98.     for(LI = m_idlelist.begin(); LI != m_idlelist.end();)  
  99.     {  
  100.         removetimer(*LI);  
  101.         (*LI)->disconnect();  
  102.         (*LI)->stop();     
  103.         delete (*LI);  
  104.         LI = m_idlelist.erase(LI);  
  105.     }  
  106.   
  107.     return true;  
  108. }  
  109.   
  110. CConnection* CConnectionpool::applyfor()  
  111. {  
  112.     m_mutex.acquire();  
  113.     CConnection *pconn = NULL;  
  114.     if (m_idlelist.size() > 0)  
  115.     {     
  116.         pconn = m_idlelist.front();  
  117.         m_idlelist.pop_front();  
  118.         m_busylist.push_back(pconn);  
  119.         //删除定时器  
  120.         removetimer(pconn);  
  121.     }  
  122.     else  
  123.     {  
  124.         int idle = m_idlelist.size();  
  125.         int busy = m_busylist.size();  
  126.         int all = idle + busy;  
  127.   
  128.         if (all < m_maxconn)  
  129.         {  
  130.             pconn = new CConnection(m_dbstring, m_dbname);  
  131.             pconn->start();  
  132.             pconn->reconnect();  
  133.             m_busylist.push_back(pconn);  
  134.         }  
  135.         else  
  136.         {  
  137.             while(m_idlelist.size() == 0)  
  138.             {  
  139.                 m_pcondition->signal();  
  140.                 m_pcondition->wait();  
  141.             }  
  142.             pconn = m_idlelist.front();  
  143.             m_idlelist.pop_front();  
  144.             m_busylist.push_back(pconn);  
  145.             //删除定时器  
  146.             removetimer(pconn);  
  147.         }  
  148.     }  
  149.     m_mutex.release();  
  150.     return pconn;  
  151. }  
  152.   
  153.   
  154. bool CConnectionpool::payback(CConnection* pconn)  
  155. {  
  156.     m_mutex.acquire();  
  157.     typedef CONNECTIONLIST::iterator ITERATOR;  
  158.     ITERATOR LI;  
  159.     bool find = false;  
  160.     for(LI = m_busylist.begin(); LI != m_busylist.end();)  
  161.     {  
  162.         if (*LI == pconn)  
  163.         {  
  164.             LI = m_busylist.erase(LI);  
  165.             find = true;  
  166.         }  
  167.         else  
  168.         {  
  169.             LI++;  
  170.         }  
  171.     }  
  172.     if (find)  
  173.     {  
  174.         m_idlelist.push_back(pconn);  
  175.         pconn->setidletimepoint();  
  176.         //启动定时器  
  177.         addtimer(pconn);  
  178.         m_pcondition->signal();  
  179.     }  
  180.     m_mutex.release();  
  181.     return find;  
  182. }  
  183.   
  184. int CConnectionpool::getconnectionsize()  
  185. {  
  186.     m_mutex.acquire();  
  187.     int idle = m_idlelist.size();  
  188.     int busy = m_busylist.size();  
  189.     int all = idle + busy;  
  190.     m_mutex.release();  
  191.     return all;  
  192. }  
  193.   
  194. bool CConnectionpool::removefromidlelist(CConnection* pconn)  
  195. {  
  196.     m_mutex.acquire();  
  197.     typedef CONNECTIONLIST::iterator ITERATOR;  
  198.     ITERATOR LI;  
  199.     bool find = false;  
  200.   
  201.     CConnection *ptemp = NULL;  
  202.     for(LI = m_idlelist.begin(); LI != m_idlelist.end();)  
  203.     {  
  204.         if (*LI == pconn)  
  205.         {  
  206.             pconn->disconnect();  
  207.             pconn->stop();     
  208.             delete pconn;  
  209.             m_idlelist.erase(LI);  
  210.             find = true;  
  211.             break;  
  212.         }  
  213.     }  
  214.     m_mutex.release();  
  215.     return find;  
  216. }  
  217.   
  218.   
  219. int CConnectionpool::executesp(char* spname, char* inputparam, char* outparam)  
  220. {  
  221.     int ret = -1;  
  222.     if (!active_) return ret;  
  223.     CConnection *pconn = NULL;  
  224.     pconn = applyfor();  
  225.     if (pconn != NULL)  
  226.     {  
  227.         pconn->addinvoke();  
  228.         ret = pconn->DML_DEMO_5(spname, inputparam, outparam);  
  229.     }  
  230.     payback(pconn);  
  231.     return ret;  
  232. }  
  233.   
  234. void CConnectionpool::output()  
  235. {  
  236.     m_mutex.acquire();  
  237.   
  238.     typedef CONNECTIONLIST::iterator ITERATOR;  
  239.     ITERATOR LI;  
  240.   
  241.     int idle = m_idlelist.size();  
  242.     int busy = m_busylist.size();  
  243.     int all = idle + busy;  
  244.   
  245.     printf("total=%d\n", all);  
  246.     printf("idle=%d\n", idle);  
  247.     printf("busy=%d\n", busy);  
  248.   
  249.     printf("........idle list........\n");  
  250.     for(LI = m_idlelist.begin(); LI != m_idlelist.end(); LI++)  
  251.     {  
  252.         (*LI)->output();  
  253.     }  
  254.   
  255.     printf("........busy list........\n");  
  256.     for(LI = m_busylist.begin(); LI != m_busylist.end(); LI++)  
  257.     {  
  258.         (*LI)->output();  
  259.     }     
  260.   
  261.     m_mutex.release();  
  262. }  
  263.   
  264. int CConnectionpool::addtimer(CConnection *pconn)  
  265. {  
  266.     ACE_Time_Value tv(this->m_keepalive, 0);  
  267.     int timerid = ACE_Reactor::instance()->schedule_timer(this, (void*)pconn, tv);  
  268.     pconn->settimerid(timerid);  
  269.     return timerid;  
  270. }  
  271.   
  272. int CConnectionpool::removetimer(CConnection *pconn)  
  273. {  
  274.     return ACE_Reactor::instance()->cancel_timer(pconn->gettimerid());  
  275. }  
  276.   
  277. int CConnectionpool::handle_timeout(const ACE_Time_Value &tv, const void *arg)  
  278. {  
  279.     CConnection *pconn = (CConnection*)arg;  
  280.     CLogger::createinstance()->logdebugmsg("handle_timeout current=%d connection=%08x timerid=%d ok\n", getconnectionsize(), pconn, pconn->gettimerid());  
  281.     if (getconnectionsize() > m_minconn)  
  282.     {  
  283.         removefromidlelist(pconn);  
  284.     }  
  285.     return 0;  
  286. }  
  287.   
  288. bool CConnectionpool::getactive()  
  289. {  
  290.     return active_;  
  291. }  
cclienttask
  1. #pragma once  
  2.   
  3. #include "ace/Task.h"  
  4. #include "ace/Synch.h"  
  5. #include "Connectionpool.h"  
  6.   
  7. class CClienttask : public ACE_Task<ACE_MT_SYNCH>  
  8. {  
  9. public:  
  10.     CClienttask(void);  
  11.     CClienttask(CConnectionpool* connpool, int execount);  
  12.     ~CClienttask(void);  
  13. public:  
  14.     virtual int open();  
  15.     virtual int svc();  
  16.     virtual int close();      
  17. private:  
  18.     ACE_thread_t  threads[0x04];  
  19.     CConnectionpool* m_pconnpool;  
  20.     int m_execount;  
  21. };  
  22.   
  23.   
  24.   
  25. #include "Clienttask.h"  
  26. #include "Logger.h"  
  27.   
  28.   
  29. CClienttask::CClienttask(void)  
  30. {  
  31. }  
  32.   
  33. CClienttask::CClienttask(CConnectionpool* connpool, int execount)  
  34. {  
  35.     m_pconnpool = connpool;  
  36.     m_execount = execount;  
  37. }  
  38.   
  39. CClienttask::~CClienttask(void)  
  40. {  
  41. }  
  42.   
  43. int CClienttask::open()  
  44. {  
  45.      return activate(THR_NEW_LWP, 4, 0, ACE_DEFAULT_THREAD_PRIORITY, -1, this, 0, 0, 0, threads);  
  46. }  
  47.   
  48. int CClienttask::svc()  
  49. {  
  50.     if (ACE_Thread::self() == threads[0])  
  51.     {  
  52.         CLogger::createinstance()->logdebugmsg("watch thread started, threadid=%d\n", threads[0]);  
  53.         while(true)  
  54.         {  
  55.             int command = 0;  
  56.             scanf_s("%d", &command);  
  57.             if(command == 1)  
  58.             {  
  59.                 m_pconnpool->output();  
  60.             }  
  61.             else if(command == 2)  
  62.             {  
  63.                 m_pconnpool->stop();  
  64.             }  
  65.         }  
  66.     }  
  67.     else if (ACE_Thread::self() == threads[1])  
  68.     {  
  69.         CLogger::createinstance()->logdebugmsg("client task started, threadid=%d\n", threads[1]);  
  70.         int i = 0;  
  71.         while(i < m_execount && m_pconnpool->getactive())  
  72.         {  
  73.             char input[100];  
  74.             sprintf_s(input, 100, "%05dwangxu%05d", threads[1], i);  
  75.             char output[100];  
  76.             m_pconnpool->executesp("sp_test", input, output);  
  77.               
  78.             i++;  
  79.         }  
  80.     }  
  81.     else if (ACE_Thread::self() == threads[2])  
  82.     {  
  83.         CLogger::createinstance()->logdebugmsg("client task started, threadid=%d\n", threads[2]);  
  84.         int i = 0;  
  85.         while(i < m_execount && m_pconnpool->getactive())  
  86.         {  
  87.             char input[100];  
  88.             sprintf_s(input, 100, "%05dwangxu%05d", threads[2], i);  
  89.             char output[100];  
  90.             m_pconnpool->executesp("sp_test", input, output);  
  91.               
  92.             i++;  
  93.         }  
  94.     }  
  95.     else if (ACE_Thread::self() == threads[3])  
  96.     {  
  97.         CLogger::createinstance()->logdebugmsg("client task started, threadid=%d\n", threads[3]);  
  98.         int i = 0;  
  99.         while(i < m_execount && m_pconnpool->getactive())  
  100.         {  
  101.             char input[100];  
  102.             sprintf_s(input, 100, "%05dwangxu%05d", threads[3], i);  
  103.             char output[100];  
  104.             m_pconnpool->executesp("sp_test", input, output);  
  105.               
  106.             i++;  
  107.         }  
  108.     }  
  109.     return 0;  
  110. }  
  111.   
  112. int CClienttask::close()  
  113. {  
  114.     return 0;  
  115. }  
CLogger
  1. #pragma once  
  2.   
  3. #include "ace/Activation_Queue.h"  
  4. #include "ace/Method_Request.h"  
  5. #include "ace/Task.h"  
  6. #include "ace/Future.h"  
  7. #include "ace/Auto_Ptr.h"  
  8.   
  9. #include <ctype.h>  
  10. #include <stdarg.h>  
  11. #include <stdlib.h>  
  12. #include <stdio.h>  
  13. #include <string>  
  14.   
  15. using namespace std;  
  16.   
  17. class CLogger : public ACE_Task<ACE_MT_SYNCH>  
  18. {  
  19. public:  
  20.     /*log level*/  
  21.     enum LEVEL  
  22.     {  
  23.         DEBUG = 0x00,  
  24.         INFO  = 0x01,  
  25.         WARN  = 0x02,  
  26.         FAULT = 0x03  
  27.     };  
  28.   
  29.     /*output direct*/  
  30.     enum DIRECTOR  
  31.     {  
  32.         SCREENOUT = 0x00,  
  33.         FILEOUT   = 0x01,  
  34.         BOTH      = 0x02  
  35.     };  
  36.   
  37.     /*log mode*/  
  38.     enum MODE  
  39.     {  
  40.         TEST = 0x00,  
  41.         RUN  = 0x01  
  42.     };  
  43.   
  44.     /*whether the log will be split*/  
  45.     enum SPLIT  
  46.     {  
  47.         ONE  = 0x00,  
  48.         FOUR = 0x01  
  49.     };  
  50.   
  51.     /*delete log automatic or manual*/  
  52.     enum MANAGER  
  53.     {  
  54.         AUTODEL   = 0x00,  
  55.         MANUALDEL = 0x01  
  56.     };  
  57. public:  
  58.     CLogger(void);  
  59.     CLogger(LEVEL level, DIRECTOR director, MODE mode, SPLIT split, MANAGER  manager);  
  60.     ~CLogger(void);  
  61.   
  62.     int logdebugmsg_i(const char* fmt, ...);  
  63.     int loginfomsg_i(const char* fmt, ...);  
  64.     int logwarnmsg_i(const char* fmt, ...);  
  65.     int logfaultmsg_i(const char* fmt, ...);  
  66.   
  67.     ACE_Future<int> logdebugmsg(const char* fmt, ...);  
  68.     ACE_Future<int> loginfomsg(const char* fmt, ...);  
  69.     ACE_Future<int> logwarnmsg(const char* fmt, ...);  
  70.     ACE_Future<int> logfaultmsg(const char* fmt, ...);  
  71.   
  72.     void setparam(LEVEL level, DIRECTOR director, MODE mode, SPLIT split, MANAGER  manager);  
  73.   
  74.     virtual int open();  
  75.     virtual int close();  
  76.     virtual int svc();  
  77.     static CLogger* createinstance();  
  78. private:  
  79.     static CLogger* _instance;  
  80.     ACE_thread_t  threads[0x01];  
  81.     ACE_Activation_Queue m_activation_queue;  
  82. private:  
  83.     LEVEL    m_level;  
  84.     DIRECTOR m_director;  
  85.     MODE     m_mode;  
  86.     SPLIT    m_split;  
  87.     MANAGER  m_manager;  
  88.     string   m_directory;  
  89.     void     createlogdirectory();  
  90.     string   getdatetime();  
  91.     string   getdate();  
  92.     void     closefilehandle();  
  93.     FILE*    getonefilehandle();  
  94.     FILE*    getdebugfilehandle();  
  95.     FILE*    getinfofilehandle();  
  96.     FILE*    getwarnfilehandle();  
  97.     FILE*    getfaultfilehandle();  
  98.     FILE*    m_fpfourdebug;  
  99.     string   m_filenamedebug;  
  100.     FILE*    m_fpfourinfo;  
  101.     string   m_filenameinfo;  
  102.     FILE*    m_fpfourwarn;  
  103.     string   m_filenamewarn;  
  104.     FILE*    m_fpfourfault;  
  105.     string   m_filenamefault;  
  106.     FILE*    m_fponelog;  
  107.     string   m_filenamelog;  
  108. public:  
  109.     void setlevel(LEVEL level);  
  110.     LEVEL getlevel();  
  111.     void setdirector(DIRECTOR director);  
  112.     DIRECTOR getdirector();  
  113.     void setmode(MODE mode);  
  114.     MODE getmode();  
  115.     void setsplit(SPLIT split);  
  116.     SPLIT getsplit();  
  117.     void setmanager(MANAGER manager);  
  118.     MANAGER getmanager();  
  119.   
  120. };  
  121.   
  122.   
  123. #include <direct.h>  
  124. #include "Logger.h"  
  125. #include "Logdebugmsg_MO.h"  
  126. #include "Loginfomsg_MO.h"  
  127. #include "Logwarnmsg_MO.h"  
  128. #include "Logfaultmsg_MO.h"  
  129.   
  130.   
  131. CLogger* CLogger::_instance = 0;  
  132.   
  133. CLogger* CLogger::createinstance()  
  134. {  
  135.     if (_instance == 0)  
  136.     {  
  137.         _instance = new CLogger;  
  138.     }  
  139.     return _instance;  
  140. }  
  141.   
  142.   
  143. CLogger::CLogger(void)  
  144. {  
  145.     m_level = CLogger::DEBUG;  
  146.     m_director = CLogger::BOTH;  
  147.     m_mode = CLogger::TEST;  
  148.     m_split = CLogger::FOUR;  
  149.     m_manager = CLogger::AUTODEL;  
  150.       
  151.     m_fpfourdebug = NULL;  
  152.     m_fpfourinfo = NULL;  
  153.     m_fpfourwarn = NULL;  
  154.     m_fpfourfault = NULL;  
  155.     m_fponelog = NULL;  
  156.   
  157.     m_filenamedebug = "null";  
  158.     m_filenameinfo = "null";  
  159.     m_filenamewarn = "null";  
  160.     m_filenamefault = "null";  
  161.     m_filenamelog = "null";  
  162.   
  163.     createlogdirectory();  
  164.   
  165. }  
  166.   
  167. CLogger::CLogger(LEVEL level, DIRECTOR director, MODE mode, SPLIT split, MANAGER  manager)  
  168. {  
  169.     m_level = level;  
  170.     m_director = director;  
  171.     m_mode = mode;  
  172.     m_split = split;  
  173.     m_manager = manager;  
  174.   
  175.     m_fpfourdebug = NULL;  
  176.     m_fpfourinfo = NULL;  
  177.     m_fpfourwarn = NULL;  
  178.     m_fpfourfault = NULL;  
  179.     m_fponelog = NULL;  
  180.   
  181.     m_filenamedebug = "null";  
  182.     m_filenameinfo = "null";  
  183.     m_filenamewarn = "null";  
  184.     m_filenamefault = "null";  
  185.     m_filenamelog = "null";  
  186.   
  187.     createlogdirectory();  
  188.   
  189. }  
  190.   
  191.   
  192. void CLogger::closefilehandle()  
  193. {  
  194.     if (m_fpfourdebug != NULL)  
  195.     {  
  196.         fclose(m_fpfourdebug);  
  197.         m_fpfourdebug = NULL;     
  198.         m_filenamedebug = "null";  
  199.     }  
  200.   
  201.     if (m_fpfourinfo != NULL)  
  202.     {  
  203.         fclose(m_fpfourinfo);  
  204.         m_fpfourinfo = NULL;      
  205.         m_filenameinfo = "null";  
  206.     }  
  207.   
  208.     if (m_fpfourwarn != NULL)  
  209.     {  
  210.         fclose(m_fpfourwarn);  
  211.         m_fpfourwarn = NULL;  
  212.         m_filenamewarn = "null";  
  213.     }  
  214.   
  215.     if (m_fpfourfault != NULL)  
  216.     {  
  217.         fclose(m_fpfourfault);  
  218.         m_fpfourfault = NULL;  
  219.         m_filenamefault = "null";  
  220.   
  221.     }  
  222.       
  223.     if (m_fponelog != NULL)  
  224.     {  
  225.         fclose(m_fponelog);  
  226.         m_fponelog = NULL;  
  227.         m_filenamelog = "null";  
  228.     }  
  229. }  
  230.   
  231.   
  232. CLogger::~CLogger(void)  
  233. {  
  234.     closefilehandle();  
  235. }  
  236.   
  237. void CLogger::setlevel(LEVEL level)  
  238. {  
  239.     closefilehandle();  
  240.     m_level = level;  
  241. }  
  242.   
  243. CLogger::LEVEL CLogger::getlevel()  
  244. {  
  245.     return m_level;  
  246. }  
  247.       
  248. void CLogger::setdirector(DIRECTOR director)  
  249. {  
  250.     closefilehandle();  
  251.     m_director = director;  
  252. }  
  253.   
  254. CLogger::DIRECTOR CLogger::getdirector()  
  255. {  
  256.     return m_director;  
  257. }  
  258.   
  259. void CLogger::setmode(MODE mode)  
  260. {  
  261.     closefilehandle();  
  262.     m_mode = mode;  
  263. }  
  264.   
  265. CLogger::MODE CLogger::getmode()  
  266. {  
  267.     return m_mode;  
  268. }  
  269.   
  270. void CLogger::setsplit(SPLIT split)  
  271. {  
  272.     closefilehandle();  
  273.     m_split = split;  
  274. }  
  275.   
  276. CLogger::SPLIT CLogger::getsplit()  
  277. {  
  278.     return m_split;  
  279. }  
  280.   
  281. void CLogger::setmanager(MANAGER manager)  
  282. {  
  283.     m_manager = manager;  
  284. }  
  285.   
  286.   
  287. CLogger::MANAGER CLogger::getmanager()  
  288. {  
  289.     return m_manager;  
  290. }  
  291.   
  292. string CLogger::getdatetime()  
  293. {     
  294.     time_t current;  
  295.     current = time(NULL);  
  296.     struct tm pdatetime;  
  297.     int error = localtime_s(&pdatetime, ¤t) ;  
  298.     char datetime[100];  
  299.     memset(datetime, 0x00, 100);  
  300.     sprintf_s(datetime, 100, "%04d-%02d-%02d %02d:%02d %02d",  
  301.         pdatetime.tm_year + 1900,  
  302.         pdatetime.tm_mon + 1,  
  303.         pdatetime.tm_mday,  
  304.         pdatetime.tm_hour,  
  305.         pdatetime.tm_min,  
  306.         pdatetime.tm_sec);  
  307.   
  308.     return string(datetime);  
  309. }  
  310.   
  311. string CLogger::getdate()  
  312. {  
  313.     time_t current;  
  314.     struct tm pdatetime;  
  315.     time(¤t);  
  316.     int error = localtime_s(&pdatetime, ¤t) ;  
  317.     char date[100];  
  318.     memset(date, 0x00, 100);  
  319.     sprintf_s(date, 100, "%04d-%02d-%02d",  
  320.         pdatetime.tm_year + 1900,  
  321.         pdatetime.tm_mon + 1,  
  322.         pdatetime.tm_mday);  
  323.   
  324.     return string(date);  
  325. }  
  326.   
  327.   
  328. int CLogger::logdebugmsg_i(const char* fmt, ...)  
  329. {  
  330.     if (getlevel() > CLogger::DEBUG) return 0;  
  331.       
  332.     va_list ap;  
  333.     va_start(ap, fmt);  
  334.     if (getdirector() == CLogger::SCREENOUT)  
  335.     {  
  336.         vfprintf(stdout, fmt, ap);  
  337.     }  
  338.     else  
  339.     {  
  340.         if (getsplit() == CLogger::ONE)  
  341.         {  
  342.             m_fponelog = getonefilehandle();  
  343.             vfprintf(m_fponelog, fmt, ap);  
  344.             if (getmode() == CLogger::TEST)  
  345.             {  
  346.                 fclose(m_fponelog);  
  347.                 m_fponelog = NULL;  
  348.             }  
  349.         }  
  350.         else  
  351.         {  
  352.             m_fpfourdebug = getdebugfilehandle();  
  353.             vfprintf(m_fpfourdebug, fmt, ap);  
  354.             if (getmode() == CLogger::TEST)  
  355.             {  
  356.                 fclose(m_fpfourdebug);  
  357.                 m_fpfourdebug = NULL;  
  358.             }  
  359.         }  
  360.         if (getdirector() == CLogger::BOTH)  
  361.         {  
  362.             vfprintf(stdout, fmt, ap);  
  363.         }  
  364.     }  
  365.     va_end(ap);  
  366.     return 0;  
  367. }  
  368.   
  369.   
  370. int CLogger::loginfomsg_i(const char* fmt, ...)  
  371. {  
  372.     if (getlevel() > CLogger::INFO) return 0;  
  373.   
  374.     va_list ap;  
  375.     va_start(ap, fmt);  
  376.     if (getdirector() == CLogger::SCREENOUT)  
  377.     {  
  378.         vfprintf(stdout, fmt, ap);  
  379.     }  
  380.     else  
  381.     {  
  382.         if (getsplit() == CLogger::ONE)  
  383.         {  
  384.             m_fponelog = getonefilehandle();  
  385.             vfprintf(m_fponelog, fmt, ap);  
  386.             if (getmode() == CLogger::TEST)  
  387.             {  
  388.                 fclose(m_fponelog);  
  389.                 m_fponelog = NULL;  
  390.             }  
  391.         }  
  392.         else  
  393.         {  
  394.             m_fpfourinfo = getinfofilehandle();  
  395.             vfprintf(m_fpfourinfo, fmt, ap);  
  396.             if (getmode() == CLogger::TEST)  
  397.             {  
  398.                 fclose(m_fpfourinfo);  
  399.                 m_fpfourinfo = NULL;  
  400.             }  
  401.         }  
  402.         if (getdirector() == CLogger::BOTH)  
  403.         {  
  404.             vfprintf(stdout, fmt, ap);  
  405.         }  
  406.     }  
  407.     va_end(ap);  
  408.     return 0;  
  409. }  
  410.   
  411.   
  412. int CLogger::logwarnmsg_i(const char* fmt, ...)  
  413. {  
  414.     if (getlevel() > CLogger::WARN) return 0;  
  415.   
  416.     va_list ap;  
  417.     va_start(ap, fmt);  
  418.     if (getdirector() == CLogger::SCREENOUT)  
  419.     {  
  420.         vfprintf(stdout, fmt, ap);  
  421.     }  
  422.     else  
  423.     {  
  424.         if (getsplit() == CLogger::ONE)  
  425.         {  
  426.             m_fponelog = getonefilehandle();  
  427.             vfprintf(m_fponelog, fmt, ap);  
  428.             if (getmode() == CLogger::TEST)  
  429.             {  
  430.                 fclose(m_fponelog);  
  431.                 m_fponelog = NULL;  
  432.             }  
  433.         }  
  434.         else  
  435.         {  
  436.             m_fpfourwarn = getwarnfilehandle();  
  437.             vfprintf(m_fpfourwarn, fmt, ap);  
  438.             if (getmode() == CLogger::TEST)  
  439.             {  
  440.                 fclose(m_fpfourwarn);  
  441.                 m_fpfourwarn = NULL;  
  442.             }  
  443.         }  
  444.         if (getdirector() == CLogger::BOTH)  
  445.         {  
  446.             vfprintf(stdout, fmt, ap);  
  447.         }  
  448.     }  
  449.     va_end(ap);  
  450.     return 0;  
  451. }  
  452.   
  453. int CLogger::logfaultmsg_i(const char* fmt, ...)  
  454. {  
  455.     if (getlevel() > CLogger::FAULT) return 0;  
  456.     va_list ap;  
  457.     va_start(ap, fmt);  
  458.     if (getdirector() == CLogger::SCREENOUT)  
  459.     {  
  460.         vfprintf(stdout, fmt, ap);  
  461.     }  
  462.     else  
  463.     {  
  464.         if (getsplit() == CLogger::ONE)  
  465.         {  
  466.             m_fponelog = getonefilehandle();  
  467.             vfprintf(m_fponelog, fmt, ap);  
  468.             if (getmode() == CLogger::TEST)  
  469.             {  
  470.                 fclose(m_fponelog);  
  471.                 m_fponelog = NULL;  
  472.             }  
  473.         }  
  474.         else  
  475.         {  
  476.             m_fpfourfault = getfaultfilehandle();  
  477.             vfprintf(m_fpfourfault, fmt, ap);  
  478.             if (getmode() == CLogger::TEST)  
  479.             {  
  480.                 fclose(m_fpfourfault);  
  481.                 m_fpfourfault = NULL;  
  482.             }  
  483.         }  
  484.         if (getdirector() == CLogger::BOTH)  
  485.         {  
  486.             vfprintf(stdout, fmt, ap);  
  487.         }  
  488.     }  
  489.     va_end(ap);  
  490.     return 0;  
  491. }  
  492.   
  493. void CLogger::createlogdirectory()  
  494. {     
  495.     if (m_director == CLogger::SCREENOUT) return;  
  496.   
  497.     string fulldir = "..\\log";   
  498.       
  499.     if (_access(fulldir.c_str(), 0) == -1)  
  500.     {  
  501.         printf("create %s\n", fulldir.c_str());  
  502.         _mkdir(fulldir.c_str());      
  503.     }  
  504.       
  505.     fulldir = "..\\log\\debug";  
  506.     if (_access(fulldir.c_str(), 0) == -1)  
  507.     {  
  508.         printf("create %s\n", fulldir.c_str());  
  509.         _mkdir(fulldir.c_str());      
  510.     }  
  511.   
  512.     fulldir = "..\\log\\info";  
  513.     if (_access(fulldir.c_str(), 0) == -1)  
  514.     {  
  515.         printf("create %s\n", fulldir.c_str());  
  516.         _mkdir(fulldir.c_str());      
  517.     }  
  518.   
  519.     fulldir = "..\\log\\warn";  
  520.     if (_access(fulldir.c_str(), 0) == -1)  
  521.     {  
  522.         printf("create %s\n", fulldir.c_str());  
  523.         _mkdir(fulldir.c_str());      
  524.     }  
  525.   
  526.     fulldir = "..\\log\\fault";  
  527.     if (_access(fulldir.c_str(), 0) == -1)  
  528.     {  
  529.         printf("create %s\n", fulldir.c_str());  
  530.         _mkdir(fulldir.c_str());      
  531.     }  
  532. }  
  533.   
  534.   
  535.   
  536. FILE* CLogger::getonefilehandle()  
  537. {  
  538.     string filename = "..\\log\\" + getdate() + ".log";  
  539.     if ((filename.compare(m_filenamelog) == 0) && (m_fponelog != NULL))  
  540.     {  
  541.     }  
  542.     else if((filename.compare(m_filenamelog) == 0) && (m_fponelog == NULL))  
  543.     {  
  544.         fopen_s(&m_fponelog, filename.c_str(), "a+");  
  545.     }  
  546.     else if((filename.compare(m_filenamelog) != 0) && (m_fponelog != NULL))  
  547.     {  
  548.         fclose(m_fponelog);  
  549.         m_fponelog = NULL;  
  550.         fopen_s(&m_fponelog, filename.c_str(), "a+");  
  551.         m_filenamelog = filename;  
  552.     }  
  553.     else if((filename.compare(m_filenamelog) != 0) && (m_fponelog == NULL))  
  554.     {  
  555.         fopen_s(&m_fponelog, filename.c_str(), "a+");  
  556.         m_filenamelog = filename;  
  557.     }  
  558.     return m_fponelog;  
  559. }  
  560.   
  561. FILE*  CLogger::getdebugfilehandle()  
  562. {  
  563.     string filename = "..\\log\\debug\\" + getdate() + ".dlog";  
  564.   
  565.     if ((filename.compare(m_filenamedebug) == 0) && (m_fpfourdebug != NULL))  
  566.     {  
  567.     }  
  568.     else if((filename.compare(m_filenamedebug) == 0) && (m_fpfourdebug == NULL))  
  569.     {  
  570.         fopen_s(&m_fpfourdebug, filename.c_str(), "a+");  
  571.     }  
  572.     else if((filename.compare(m_filenamedebug) != 0) && (m_fpfourdebug != NULL))  
  573.     {  
  574.         fclose(m_fpfourdebug);  
  575.         m_fpfourdebug = NULL;  
  576.         fopen_s(&m_fpfourdebug, filename.c_str(), "a+");  
  577.         m_filenamedebug = filename;  
  578.     }  
  579.     else if((filename.compare(m_filenamedebug) != 0) && (m_fpfourdebug == NULL))  
  580.     {  
  581.         fopen_s(&m_fpfourdebug, filename.c_str(), "a+");  
  582.         m_filenamedebug = filename;  
  583.     }  
  584.     return m_fpfourdebug;  
  585. }  
  586.   
  587. FILE*  CLogger::getinfofilehandle()  
  588. {  
  589.     string filename = "..\\log\\info\\" + getdate() + ".ilog";  
  590.   
  591.     if ((filename.compare(m_filenameinfo) == 0) && (m_fpfourinfo != NULL))  
  592.     {  
  593.     }  
  594.     else if((filename.compare(m_filenameinfo) == 0) && (m_fpfourinfo == NULL))  
  595.     {  
  596.         fopen_s(&m_fpfourinfo, filename.c_str(), "a+");  
  597.     }  
  598.     else if((filename.compare(m_filenameinfo) != 0) && (m_fpfourinfo != NULL))  
  599.     {  
  600.         fclose(m_fpfourinfo);  
  601.         m_fpfourinfo = NULL;  
  602.         fopen_s(&m_fpfourinfo, filename.c_str(), "a+");  
  603.         m_filenameinfo = filename;  
  604.     }  
  605.     else if((filename.compare(m_filenameinfo) != 0) && (m_fpfourinfo == NULL))  
  606.     {  
  607.         fopen_s(&m_fpfourinfo, filename.c_str(), "a+");   
  608.         m_filenameinfo = filename;  
  609.     }  
  610.     return m_fpfourinfo;  
  611. }  
  612.   
  613.   
  614. FILE*  CLogger::getwarnfilehandle()  
  615. {  
  616.     string filename = "..\\log\\warn\\" + getdate() + ".wlog";  
  617.   
  618.     if ((filename.compare(m_filenamewarn) == 0) && (m_fpfourwarn != NULL))  
  619.     {  
  620.     }  
  621.     else if((filename.compare(m_filenamewarn) == 0) && (m_fpfourwarn == NULL))  
  622.     {  
  623.         fopen_s(&m_fpfourwarn, filename.c_str(), "a+");  
  624.     }  
  625.     else if((filename.compare(m_filenamewarn) != 0) && (m_fpfourwarn != NULL))  
  626.     {  
  627.         fclose(m_fpfourwarn);  
  628.         m_fpfourwarn = NULL;  
  629.         fopen_s(&m_fpfourwarn, filename.c_str(), "a+");  
  630.         m_filenamewarn = filename;  
  631.     }  
  632.     else if((filename.compare(m_filenamewarn) != 0) && (m_fpfourwarn == NULL))  
  633.     {  
  634.         fopen_s(&m_fpfourwarn, filename.c_str(), "a+");   
  635.         m_filenamewarn = filename;  
  636.     }  
  637.     return m_fpfourwarn;  
  638. }  
  639.   
  640.   
  641. FILE*  CLogger::getfaultfilehandle()  
  642. {  
  643.     string filename = "..\\log\\fault\\" + getdate() + ".flog";  
  644.   
  645.     if ((filename.compare(m_filenamefault) == 0) && (m_fpfourfault != NULL))  
  646.     {  
  647.     }  
  648.     else if((filename.compare(m_filenamefault) == 0) && (m_fpfourfault == NULL))  
  649.     {  
  650.         fopen_s(&m_fpfourfault, filename.c_str(), "a+");  
  651.     }  
  652.     else if((filename.compare(m_filenamefault) != 0) && (m_fpfourfault != NULL))  
  653.     {  
  654.         fclose(m_fpfourfault);  
  655.         m_fpfourfault = NULL;  
  656.         fopen_s(&m_fpfourfault, filename.c_str(), "a+");  
  657.         m_filenamefault = filename;  
  658.     }  
  659.     else if((filename.compare(m_filenamefault) != 0) && (m_fpfourfault == NULL))  
  660.     {  
  661.         fopen_s(&m_fpfourfault, filename.c_str(), "a+");  
  662.         m_filenamefault = filename;  
  663.     }     
  664.     return m_fpfourfault;  
  665. }  
  666.   
  667. int CLogger::open()  
  668. {  
  669.     return activate(THR_NEW_LWP, 1, 0, ACE_DEFAULT_THREAD_PRIORITY, -1, this, 0, 0, 0, threads);  
  670. }  
  671.   
  672. int CLogger::close()  
  673. {  
  674.     return 0;  
  675. }  
  676.   
  677. int CLogger::svc()  
  678. {  
  679.     while(true)  
  680.     {  
  681.         auto_ptr<ACE_Method_Request> mo(m_activation_queue.dequeue());  
  682.         if (mo->call() == -1)  
  683.         break;  
  684.     }  
  685.     return 0;  
  686. }  
  687.   
  688. ACE_Future<int> CLogger::logdebugmsg(const char* fmt, ...)  
  689. {     
  690.     char logmsg1[1024];  
  691.     memset(logmsg1, 0x00, 1024);  
  692.     va_list ap;  
  693.     va_start(ap, fmt);  
  694.     _vsnprintf_s(logmsg1, 1024, fmt, ap);  
  695.     va_end(ap);  
  696.       
  697.     char logmsg2[1024];  
  698.     memset(logmsg2, 0x00, 1024);  
  699.     sprintf_s(logmsg2, 1024, "[%s] %s", getdatetime().c_str(), logmsg1);  
  700.   
  701.     ACE_Future<int> resultant_future;  
  702.     CLogdebugmsg_MO *pmo = new CLogdebugmsg_MO(this, logmsg2, resultant_future);  
  703.     m_activation_queue.enqueue(pmo);  
  704.     return resultant_future;  
  705. }  
  706.   
  707.   
  708. ACE_Future<int> CLogger::loginfomsg(const char* fmt, ...)  
  709. {  
  710.     char logmsg1[1024];  
  711.     memset(logmsg1, 0x00, 1024);  
  712.     va_list ap;  
  713.     va_start(ap, fmt);  
  714.     _vsnprintf_s(logmsg1, 1024, fmt, ap);  
  715.     va_end(ap);  
  716.       
  717.     char logmsg2[1024];  
  718.     memset(logmsg2, 0x00, 1024);  
  719.     sprintf_s(logmsg2, 1024, "[%s] %s", getdatetime().c_str(), logmsg1);  
  720.   
  721.     ACE_Future<int> resultant_future;  
  722.     m_activation_queue.enqueue(new CLoginfomsg_MO(this, logmsg2, resultant_future));  
  723.     return resultant_future;  
  724. }  
  725.   
  726. ACE_Future<int> CLogger::logwarnmsg(const char* fmt, ...)  
  727. {  
  728.     char logmsg1[1024];  
  729.     memset(logmsg1, 0x00, 1024);  
  730.     va_list ap;  
  731.     va_start(ap, fmt);  
  732.     _vsnprintf_s(logmsg1, 1024, fmt, ap);  
  733.     va_end(ap);  
  734.       
  735.     char logmsg2[1024];  
  736.     memset(logmsg2, 0x00, 1024);  
  737.     sprintf_s(logmsg2, 1024, "[%s] %s", getdatetime().c_str(), logmsg1);  
  738.   
  739.     ACE_Future<int> resultant_future;  
  740.     m_activation_queue.enqueue(new CLogwarnmsg_MO(this, logmsg2, resultant_future));  
  741.     return resultant_future;  
  742. }  
  743.   
  744. ACE_Future<int> CLogger::logfaultmsg(const char* fmt, ...)  
  745. {  
  746.     char logmsg1[1024];  
  747.     memset(logmsg1, 0x00, 1024);  
  748.     va_list ap;