connectionmanager.cxx

来自「vovida的软交换」· CXX 代码 · 共 277 行

CXX
277
字号
/* ==================================================================== * The Vovida Software License, Version 1.0  *  * Copyright (c) 2000 Vovida Networks, Inc.  All rights reserved. *  * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: *  * 1. Redistributions of source code must retain the above copyright *    notice, this list of conditions and the following disclaimer. *  * 2. Redistributions in binary form must reproduce the above copyright *    notice, this list of conditions and the following disclaimer in *    the documentation and/or other materials provided with the *    distribution. *  * 3. The names "VOCAL", "Vovida Open Communication Application Library", *    and "Vovida Open Communication Application Library (VOCAL)" must *    not be used to endorse or promote products derived from this *    software without prior written permission. For written *    permission, please contact vocal@vovida.org. * * 4. Products derived from this software may not be called "VOCAL", nor *    may "VOCAL" appear in their name, without prior written *    permission of Vovida Networks, Inc. *  * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND * NON-INFRINGEMENT ARE DISCLAIMED.  IN NO EVENT SHALL VOVIDA * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH * DAMAGE. *  * ==================================================================== *  * This software consists of voluntary contributions made by Vovida * Networks, Inc. and many individuals on behalf of Vovida Networks, * Inc.  For more information on Vovida Networks, Inc., please see * <http://www.vovida.org/>. * *//**   * This implements a pool of database connections as well as * its accessor/mutator functions to the DB of choice. * * ConnectionManager.cxx  version 1.0 -- 14 Mar 2003 *                        Suha Cubukcuoglu  */#include "VDbException.hxx"#include "PGSQLConnection.hxx"#include "ConnectionManager.hxx"#include "cpLog.h"using namespace std;// Initialise total number of DB connections to zeroint ConnectionManager::NumDBCons = 0; // Initialize number of unused DB connections to zeroint ConnectionManager::freeDBCon = 0;// Initialize pointer to the instance of this classConnectionManager* ConnectionManager::myConManager = NULL; // Allocate memory for the mutex variable to manage// threads accessing the DBConPool Vocal::Threads::Mutex ConnectionManager::myMutex;/** Returns an existing instance of the ConnectionManager *  object, or creates one if none exist. */ConnectionManager*ConnectionManager::getInstance(){    if(myConManager == NULL){        myConManager = new ConnectionManager();    }    return myConManager;}         /** Upon passing a 'dbinfo', this function tries to find *  an unused DBConnection in the pool to return. If all *  connections are taken or the pool is empty, it obtains *  a new connection to the database. */DBConnection* ConnectionManager::searchDBConPool(const DBInfo dbInfo){    // Lock access to DBConPool    Vocal::Threads::Lock lock(myMutex);        // create an iterator    vector<DBConInfo>::iterator p;    // initialize the iterator    p = DBConPool.begin();    //check for an existing unused connection    if(!DBConPool.empty()){        while(p != DBConPool.end()){            if(!(p->used)){                 p->used = true;                 decrementFreeDBCon();                 return p->myDBCon;            }                        p++;        }    }               // Create a new DBConInfo object. Get a new connection    // from the database, set it to be 'used', timestamp it    // and add it to the pool.                                 DBConInfo myDBConInfo ;     myDBConInfo.myDBCon = GetDBConnection(dbInfo);    myDBConInfo.used = true;    myDBConInfo.myTime = time(NULL);          if(myDBConInfo.myDBCon != NULL){        DBConPool.push_back(myDBConInfo);    }        NumDBCons++;        // Return the newly created DBConnection* to the    // cache.    return myDBConInfo.myDBCon;}    /** Finds the first 'used' DBconnection in the pool *  and sets it to 'unused'. This function gets called *  by a client which wishes to "free" a the DB connection. */boolConnectionManager::returnDBCon(DBConnection *dbconn){    // Lock access to DBConPool    Vocal::Threads::Lock lock(myMutex);        // create an iterator    vector<DBConInfo>::iterator p;    // initialize the iterator    p = DBConPool.begin();        while(p != DBConPool.end()){        if( p->myDBCon == dbconn){             p->used = false;             incrementFreeDBCon();             return true;        }                                                                            p++;    }    return false;}/** Deletes a DBConInfo from the pool if the connection *  contained in it is broken, or if it is older than a *  specified time.  */voidConnectionManager::checkDBConns(){       // Lock access to DBConPool    Vocal::Threads::Lock lock(myMutex);    // create an iterator    vector<DBConInfo>::iterator p;        // initialize the iterator    p = DBConPool.begin();              // Check to see if the database connections are OK.    while(p != DBConPool.end()){        if(!(((p->myDBCon))->checkDBCon())){                      DBConPool.erase(p);                       NumDBCons--;        }        p++;    }        // 'oldest' is the variable to hold the     // current longest duration among    // DBConnections. 'current' is the timestamp    // of the DBConInfo object to be examined.         time_t oldest, current;        //create an iterator     vector<DBConInfo>::iterator i;        if(NumDBCons > MAX_CONNECTIONS){         while(NumDBCons >= MAX_CONNECTIONS){             cpLog(LOG_DEBUG, "Purging DBConPool!");               i = DBConPool.end();              oldest = time(NULL);                          for(p = DBConPool.begin(); p != DBConPool.end(); p++){                       if(p->used == false){                     cpLog(LOG_DEBUG, "Found an unused connection!");                     current = p->myTime;                                           if(difftime(current, oldest) < 0){                          cpLog(LOG_DEBUG, "Setting oldest!");                           oldest = current;                                       i = p;                     }                  }             }                          if(i != DBConPool.end()){                cpLog(LOG_DEBUG, "Deleted a DBConInfo object!");                DBConPool.erase(i);                NumDBCons--;                cpLog(LOG_DEBUG, "Size of the pool: [%d]", NumDBCons);             }             else             {                cpLog(LOG_DEBUG, "No unused DBCons found!");                break;             }                  }           }    }                        /** Return a new connection to a database. *  Only relational databases are supported. */DBConnection* ConnectionManager::GetDBConnection(const DBInfo dbInfo){    // Check to see if the type of database begin used    // is PGSQL or MYSQL. If otherwise print an error    // message and return NULL pointer.    if (dbInfo.dbBackend == "PGSQL")    {      try {             myDBConnectionP = new PGSQLConnection(                    dbInfo.database,                    dbInfo.host,                    dbInfo.user,                     dbInfo.password);      }       catch (VException& e)	{	  cpLog(LOG_ERR, "Error getting DB connection: %s,",e.getDescription().c_str());	  return NULL;	}    }    else    {        cpLog (LOG_ERR, "DB Backend not supported.");        myDBConnectionP = NULL;    }       // return the new DBConnection*     return myDBConnectionP;}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?