📄 connectionpool.cpp
字号:
/* * ConnectionPool.cc - Manage the database connections * * Author: Kyle Hu * Version: 0.1 Alpha * Create: Jun 16 2003 */#include "ConnectionPool.h"#include <string.h>#include <stdio.h>#include <stdlib.h>#include <unistd.h>#include <pthread.h>void *IdleWatcher(void *arg){ ConnectionPool *pool = (ConnectionPool *) arg;#ifdef DEBUG fprintf(stdout, "DEBUG: Starting IdleWatcher loop...\n");#endif while (!pool->bStop) { sleep(2); pool->CheckIdle(); }#ifdef DEBUG fprintf(stdout, "DEBUG: Exiting IdleWatcher loop.\n");#endif return NULL;}ConnectionPool::ConnectionPool(const char *host, const char *user, const char *passwd, const char *db, unsigned int port, const char *unix_socket, unsigned int client_flag, int capacity, int timeout, int max_query){ int c = 1; while (c < capacity) c <<= 1; nCapacity = capacity; nIdleTimeout = timeout; nMaxQuery = max_query; nIdlePoolSize = 0; nBusyPoolSize = 0; pIdlePool = new FIFO(); pthread_mutex_init(&mutex, NULL); int err = pthread_create(&WatcherThread, NULL, IdleWatcher, this); if (err != 0) { fprintf(stderr, "ERROR: Cannot create idle-connection watcher thread. Error code: %d.\n", err); throw err; } // Clear the string buffer first. sHost = NULL; sUsername = NULL; sPassword = NULL; sDatabase = NULL; sUnixSocket = NULL; // Use strncpy() to aviod buffer overflow. if (host) { sHost = (char *) malloc(strlen(host) + 1); strcpy(sHost, host); } if (user) { sUsername = (char *) malloc(strlen(user) + 1); strcpy(sUsername, user); } if (passwd) { sPassword = (char *) malloc(strlen(passwd) + 1); strcpy(sPassword, passwd); } if (db) { sDatabase = (char *) malloc(strlen(db) + 1); strcpy(sDatabase, db); } if (unix_socket) { sUnixSocket = (char *) malloc(strlen(unix_socket) + 1); strcpy(sUnixSocket, unix_socket); }#ifdef DEBUG fprintf(stdout, "DEBUG: Connection param: host=%s, user=%s, db=%s.\n", sHost, sUsername, sDatabase);#endif nPort = port; nClientFlag = client_flag; nID = 0; bStop = false;}ConnectionPool::~ConnectionPool(){ bStop = true; pthread_join(WatcherThread, NULL); CloseAllConnections(); free(ppBusyPool); free(sHost); free(sUsername); free(sPassword); free(sDatabase); free(sUnixSocket);#ifdef DEBUG fprintf(stdout, "DEBUG: ConnectionPool destroyed.\n");#endif}CONNECTION *ConnectionPool::CreateConnection(){#ifdef DEBUG fprintf(stdout, "DEBUG: Creating new connection: %d.\n", nID);#endif MYSQL *pHandle = mysql_init(NULL); if (!pHandle) return NULL; MYSQL *pConnect = mysql_real_connect(pHandle, sHost, sUsername, sPassword, sDatabase, nPort, sUnixSocket, nClientFlag); if (pConnect) { CONNECTION *pConn = (CONNECTION *) malloc(sizeof(CONNECTION)); pConn->nID = nID++; pConn->nCreationTime = time(NULL); pConn->nLastIdleTime = 0; pConn->nLastQueryTime = 0; pConn->nQueryCount = 0; pConn->bBusy = false; pConn->pConn = pHandle; return pConn; } else { mysql_close(pHandle); return NULL; }}void ConnectionPool::CloseConnection(CONNECTION *pConn){#ifdef DEBUG fprintf(stdout, "DEBUG: Closing connection: %d.\n", pConn->nID);#endif mysql_close(pConn->pConn); free(pConn);}void ConnectionPool::CloseAllConnections(){ // Free the connections in the idle pool./* if (pIdlePool) { if (pIdlePool->pPrevNode) pIdlePool->pPrevNode->pNextNode = NULL; NODE *pNode = pIdlePool; while (pNode) { CloseConnection(pNode->pConn); pIdlePool = pNode->pNextNode; free(pNode); pNode = pIdlePool; } } // Free the connections in the busy pool. for (int i = 0; i < nCapacity; i++) { NODE *pNode = ppBusyPool[i]; NODE *p; while (pNode) { fprintf(stderr, "WARNING: Closing busy connection: %d!\n", pNode->pConn->nID); CloseConnection(pNode->pConn); p = pNode->pNextNode; free(pNode); pNode = p; } }*/}CONNECTION *ConnectionPool::GetConnection(){ CONNECTION *pConn; pthread_mutex_lock(&mutex); pConn = Get(); if (pConn) { pConn->bBusy = true; Put(pConn->nID, pConn); } pthread_mutex_unlock(&mutex); return pConn;}void ConnectionPool::FreeConnection(CONNECTION *pConn){ pthread_mutex_lock(&mutex); CONNECTION *p = Get(pConn->nID); if (p) { p->bBusy = false; Put(p); } pthread_mutex_unlock(&mutex);}void ConnectionPool::CheckIdle(){#ifdef DEBUG fprintf(stdout, "DEBUG: Checking for idle connectiins.\n");#endif pthread_mutex_lock(&mutex); time_t t = time(NULL); CONNECTION *pConn = Peek(); while (pConn) { if (pConn->nLastIdleTime + nIdleTimeout < t) { pConn = Get(); CloseConnection(pConn); pConn = Peek(); } else break; } pthread_mutex_unlock(&mutex);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -