自己写的一个基于ocilib的c连接池,未经测试

来源:互联网 发布:ubuntu hadoop 编辑:程序博客网 时间:2024/04/28 17:53
#include "ocilib.h"#include "pthread.h"#define DBFAIL -1#define NOWAIT 1#define WAITING0#define USE 0#define NOUSE 1typedef struct(    OCI_Connection *cn;intstatus;    //0-未用 1-使用中TP_DBCONN_NODE *next;)TP_DBCONN_NODE;TP_DBCONN_NODE *g_header = NULL;int g_cur_conn_num = 0;int g_now_use_conn = 0;int g_min_conn;int g_max_conn;int g_incr_conn;char g_user[128] = {0};char g_passwd[128]= {0};char g_tns[128]= {0};pthread_mutex_t conn_mutx;pthread_t pool_thread;int g_adjust_count = 0; //减少连接数的计数int g_adjust_pecent = 80; //进行调度的比率int g_adjust_threshold = 10; //进行调度的阈值void oci_err_handler(OCI_Error *err){   printf(                "code  : ORA-%05i\n"                "msg   : %s\n"                "sql   : %s\n",                OCI_ErrorGetOCICode(err),                 OCI_ErrorGetString(err),                OCI_GetSql(OCI_ErrorGetStatement(err))           );}int oci_db_pool_init(char *user, char *passwd, char *tns, int min_conn, int max_conn, int incr_conn){TP_DBCONN_NODE *tmp_node = NULL;TP_DBCONN_NODE *pre_tmp_node = NULL;pthread_attr_t attr;int i;g_min_conn = min_conn;g_max_conn = max_conn;g_incr_conn = incr_conn;strncpy(g_user, user, sizeof(g_user) - 1);strncpy(g_passwd, passwd, sizeof(g_passwd) - 1);strncpy(g_tns, tns, sizeof(g_tns) - 1);pthread_attr_init(&attr);    pthread_attr_setstacksize(&attr, 512000);//500K//初始化OCIif (!OCI_Initialize(oci_err_handler, NULL, OCI_ENV_DEFAULT|OCI_ENV_THREADED|OCI_ENV_CONTEXT))        return DBFAIL;//初始化数据库连接for (i = 0; i < min_conn; i++){pre_tmp_node = tmp_node;tmp_node = malloc(sizeof(TP_DBCONN_NODE));memset((void *)tmp_node, 0, sizeof(TP_DBCONN_NODE));tmp_node->cn = OCI_ConnectionCreate(tns, user, passwd, OCI_SESSION_DEFAULT);if (tmp_node->cn == NULL){free(tmp_node);oci_db_pool_free();return DBFAIL;}if (i == 0)//头节点g_header = tmp_node;else//非头节点pre_tmp_node->next = tmp_node; //TODOcur_conn_num++;}if (pthread_mutex_init(&conn_mutx, NULL) != 0){oci_db_pool_free();return DBFAIL;}//创建连接池守护线程if (pthread_create(&pool_thread, &attr, (void *)db_pool_run, NULL) != 0)                        printf("pthread_create error\n");}int oci_db_pool_free(){TP_DBCONN_NODE *tmp_node = g_header;TP_DBCONN_NODE *pre_tmp_node = NULL;while (tmp_node != NULL){pre_tmp_node = tmp_node;tmp_node = tmp_node->next;//断开数据库连接OCI_ConnectionFree(pre_tmp_node->cn);//释放内存free(pre_tmp_node);}cur_conn_num = 0;g_header = NULL;OCI_Cleanup();pthread_mutex_destory(&conn_mutx);}//增加一个数据库连接OCI_Connection *oci_db_add_conn(int type){TP_DBCONN_NODE *tmp_node = NULL;TP_DBCONN_NODE *pre_tmp_node = NULL;//加锁if (pthread_mutex_lock(&conn_mutx) != 0){return NULL;}//寻找最后一个节点tmp_node = g_header;while (tmp_node->next != NULL){tmp_node = tmp_node->next;if (tmp_node == NULL)break;}if (tmp_node != NULL){pre_tmp_node = tmp_node;tmp_node = malloc(sizeof(TP_DBCONN_NODE));memset((void *)tmp_node, 0, sizeof(TP_DBCONN_NODE));tmp_node->cn = OCI_ConnectionCreate(g_tns, g_user, g_passwd, OCI_SESSION_DEFAULT);if (tmp_node->cn == NULL){free(tmp_node);tmp_node = NULL;}else{if (g_header == NULL)//头节点g_header = tmp_node;else//非头节点pre_tmp_node->next = tmp_node; tmp_node->status = type;g_cur_conn_num++;}}else tmp_node = NULL;//释放锁if (pthread_mutex_unlock(&conn_mutx) != 0){return NULL;}return tmp_node;}//减少一个数据库连接int oci_db_del_conn(){TP_DBCONN_NODE *tmp_node = NULL;TP_DBCONN_NODE *pre_tmp_node = NULL;int ret;//加锁if (pthread_mutex_lock(&conn_mutx) != 0){return NULL;}tmp_node = g_header;//释放连接while (tmp_node->stauts != 0){pre_tmp_node = tmp_node;tmp_node = tmp_node->next;if (tmp_node == NULL)break;}if (tmp_node != NULL){//断开数据库连接OCI_ConnectionFree(tmp_node->cn);if (tmp_node == g_header){g_header = g_header->next;free(tmp_node);}else{pre_tmp_node->next = tmp_node->next;free(tmp_node);}g_cur_conn_num--;ret = 0;}elseret = -1;//释放锁if (pthread_mutex_unlock(&conn_mutx) != 0){return NULL;}return ret;}/*0-WAITING1-NOWAIT*/OCI_Connection *oci_db_get_conn(int type){TP_DBCONN_NODE *tmp_node = NULL;OCI_Connection *cn = NULL;//获取锁if (type == NOWAIT){if (pthread_mutex_trylock(&conn_mutx) != 0)return NULL;}else{if (pthread_mutex_lock(&conn_mutx) != 0)return NULL;}tmp_node = g_header;//查找现有列表获取连接while (tmp_node->status != 0){tmp_node = tmp_node->next;if (tmp_node == NULL)break;}//在现有连接中找到if (tmp_node != NULL){cn = tmp_node->cn;tmp_node->status = 1;if ((oci_db_test_conn(tmp_node->cn) != TRUE) //查询失败?{OCI_ConnectionFree(tmp_node->cn);tmp_node->cn = OCI_ConnectionCreate(g_tns, g_user, g_passwd, OCI_SESSION_DEFAULT);if (tmp_node->cn == NULL){tmp_node->status = 2;}}g_now_use_conn++;}else //未找到 已满?{//新增数据库连接if (g_cur_conn_num < g_max_conn){cn = oci_db_add_conn(USE);}}//释放锁if (pthread_mutex_unlock(&conn_mutx) != 0){return NULL;}return cn;}//释放一个连接int oci_db_free_conn(OCI_Connection *cn){TP_DBCONN_NODE *tmp_node = NULL;//加锁if (pthread_mutex_lock(&conn_mutx) != 0){return NULL;}tmp_node = g_header;//释放连接while (cn != tmp_node->cn){tmp_node = tmp_node->next;if (tmp_node == NULL)break;}tmp_node->status = 0;g_now_use_conn--;//释放锁if (pthread_mutex_unlock(&conn_mutx) != 0){return NULL;}}//检测连接int oci_db_test_conn(OCI_Connection *cn){OCI_Statement *st;int ret;st = OCI_StatementCreate(cn);ret = OCI_ExecuteStmt(st, "select 1 from dual;");OCI_StatementFree(st);return ret;}//检测活跃状态int oci_db_active_test(){TP_DBCONN_NODE *tmp_node = NULL;while (tmp_node != NULL){if (tmp_node->status != 1){if ((oci_db_test_conn(tmp_node->cn) != TRUE) //查询失败?{OCI_ConnectionFree(tmp_node->cn);tmp_node->cn = OCI_ConnectionCreate(g_tns, g_user, g_passwd, OCI_SESSION_DEFAULT);if (tmp_node->cn == NULL){tmp_node->status = 2;}}}tmp_node = tmp_node->next;}}static void db_pool_run(void * args){while(1){sleep(10);oci_db_active_test();if ((g_now_use_conn *100 / g_cur_conn_num) < g_adjust_pecent)g_adjust_count++;elseg_adjust_count = 0;if (g_adjust_count > g_adjust_threshold){oci_db_del_conn();g_adjust_count = 0;}}}

 
原创粉丝点击