Monday, December 12, 2011

On the way for my own thread pool [Semaphore] for multi-threaded applications


In Linux environment, there is a lack of ready made Database connection pool object or even a easily usable connection object invokees. So, i supposed to write my own implementations for the subject. But still there are some pretty good libraries to ease the implementations [eg: boost C++ lib]. But i thought to continue with standard way. Still this code is under development. The following code is still usable, but with lot of cavities. I'v implemented mutex mode here. But need to implement Semaphore  and avoid Blocked Waiting. That require to implement pThread. Your ideas are always welcome.


 /**get a new connection from the pool*/  
 sql::Connection* DBConnector::getConnection(void)  
 {  
  bool gotaconnection = false;  
  for(;!gotaconnection;)  
  {  
  sql::Connection* tmpConnection = NULL;  
  /*if lock is free, lock it and go inside*/  
  if(DBConnector::isFreeThenLock())  
  {  
   /*if there are free connections in the pool go and get it then free the lock and go*/  
   if(freeConnectionList->size() > 0)  
   {  
   tmpConnection = freeConnectionList->front();  
   this->freeConnectionList->pop_front();  
   this->usedConnectionList->push_back(tmpConnection);  
   TEST_LOGGER(SLOGGER_INFO_LOG_LEVEL, "GETCONNECTION : ", (char*)tmpConnection);  
   DBConnector::free();  
   gotaconnection = true;  
   return tmpConnection;  
   }else  
   {/*check if there can create more connections*/  
   TEST_LOGGER(SLOGGER_INFO_LOG_LEVEL, "CURRENT NUM OF CONNECTIONS : ", (freeConnectionList->size() + usedConnectionList->size()));  
   if((freeConnectionList->size() + usedConnectionList->size()) < (maxConnections))  
   {  
    bool successCreation = false;  
    for(;!successCreation;){  
    try{  
    TEST_LOGGER(SLOGGER_INFO_LOG_LEVEL, "CREATING MORE CONNECTIONS : ", "");  
     const std::string tmpUrl = std::string("tcp://").append(this->hostName).append(":").append(this->port);  
     tmpConnection = this->driver->connect(tmpUrl.c_str() , this->userName.c_str() , this->pswd.c_str());  
     tmpConnection->setSchema(this->schemaName.c_str());  
     tmpConnection->setAutoCommit(true);  
     this->usedConnectionList->push_back(tmpConnection);  
     TEST_LOGGER(SLOGGER_DEBUG_LOG_LEVEL, "CREATE CONNECTION : ", (char*)tmpConnection);  
     TEST_LOGGER(SLOGGER_INFO_LOG_LEVEL, "GETCONNECTION : ", (char*)tmpConnection);  
     successCreation = true;  
     gotaconnection = true;  
     DBConnector::free();  
     return tmpConnection;  
    }catch(sql::SQLException &e)  
    {  
     TEST_LOGGER(SLOGGER_FATAL_LOG_LEVEL, "ERROR RECREATING CONNECTIONS : ", e.what());  
     successCreation = false;  
     continue;  
    }  
    }  
   }else  
   {  
    TEST_LOGGER(SLOGGER_ERROR_LOG_LEVEL, "CAN'T ALLOCATE MORE CONNECTIONS, RETURNNING NULL : ", "");  
    DBConnector::free();  
    gotaconnection = true;  
    return NULL;  
   }  
   }  
  }  
  TEST_LOGGER(SLOGGER_ERROR_LOG_LEVEL, "COULD NOT GET A CONNECTIONS, WAIT AND RETRY: ", "");  
  DBConnector::free();  
  //Sleep(1);  
  }  
  return NULL;  
 }  
 Here is the sub functions that are on development to make ease the coding:  
 /**release a connection back to the pool*/  
 void DBConnector::releaseConnection(sql::Connection* connToRelease)  
 {  
  if(DBConnector::isFreeThenLock())  
  this->usedConnectionList->remove(connToRelease);  
  if(connToRelease!=NULL && !connToRelease->isClosed()){  
  this->freeConnectionList->push_back(connToRelease);  
  TEST_LOGGER(SLOGGER_INFO_LOG_LEVEL, "RELEASECONNECTION: ", (char*)connToRelease);  
  }else{  
  TEST_LOGGER(SLOGGER_FATAL_LOG_LEVEL, "DISCARD CONNECTION: ", (char*)connToRelease);  
  }  
  DBConnector::free();  
 }  
 /*check if the pool object is free and lock it its free*/  
 bool DBConnector::isFree(void)  
 {  
  return DBConnector::syncLock == 0 ? true : false;  
 }  
 /*check if the pool object is free to use for concurrent access*/  
 bool DBConnector::isFreeThenLock(void)  
 {  
  if(DBConnector::syncLock == 0)  
  {  
  DBConnector::syncLock = 1;  
  TEST_LOGGER(SLOGGER_INFO_LOG_LEVEL, "LOCKED: ", "");  
  return true;  
  }  
  return false;  
 }  
 /*release pool lock*/  
 bool DBConnector::free(void)  
 {  
  if(DBConnector::syncLock != 0)  
  {  
  TEST_LOGGER(SLOGGER_INFO_LOG_LEVEL, "FREED: ", "");  
  DBConnector::syncLock = 0;  
  return true;  
  }  
  DBConnector::syncLock = 1;  
  return false;  
 }  
 bool DBConnector::error(void)  
 {  
  DBConnector::syncLock = -1;  
  TEST_LOGGER(SLOGGER_ERROR_LOG_LEVEL, "ERROR: ", "");  
  return false;  
 }  

No comments:

Post a Comment