ConnectionError SOCKS5BytestreamServer::recv( int timeout ) { if( !m_tcpServer ) return ConnNotConnected; ConnectionError ce = m_tcpServer->recv( timeout ); if( ce != ConnNoError ) return ce; // First take a snapshot of our connections, and then iterate the snapshot // (so that the live map can be modified by an erase while we // iterate the snapshot of the map) ConnectionMap connectionsSnapshot; m_mutex.lock(); connectionsSnapshot.insert( m_connections.begin(), m_connections.end() ); m_mutex.unlock(); ConnectionMap::const_iterator it = connectionsSnapshot.begin(); for( ; it != connectionsSnapshot.end(); ++it ) { (*it).first->recv( timeout ); } connectionsSnapshot.clear(); m_mutex.lock(); util::clearList( m_oldConnections ); m_mutex.unlock(); return ConnNoError; }
IDatabase* DatabaseFactory::getDatabase(EDataTypes dataType, EDataActions dataAction) { FUNCTION_ENTRY("getDatabase"); // Set up a local variable to point to the database that is either created or found IDatabase* theDatabase = NULL; ThreadGuard guard( m_getDatabaseLock ); // get the connection string for this datatype/action std::string dbConnection; // forever loop will exit by exception or when a good db is found while(1) { // If this call fails it will throw something. try { DbConnection::getInstance().getConnectionString(dataType, dataAction, dbConnection); } catch(DbConnectionFailed&) { // we exit the forever loop with this throw TA_THROW(DatabaseException("Unable to find a working database")); } // Get the ID of this thread - we want one database connection per thread int threadId = Thread::getCurrentThreadId(); // Look to see if there is already a database connection for this thread //<ThreadID: Map<ConnectionString, SimpleDBDatabase>> ThreadMap::iterator threadIter ( m_databaseMap.find( threadId )); if ( threadIter == m_databaseMap.end() ) { // add new ConnectionMap. Set db* to null untill it's defined ConnectionMap cmap; cmap.insert( ConnectionMap::value_type( dbConnection, 0 ) ); threadIter = m_databaseMap.insert(ThreadMap::value_type(threadId, cmap) ).first; } ConnectionMap::iterator connIter ( threadIter->second.find( dbConnection ) ); if (connIter == threadIter->second.end()) { connIter = threadIter->second.insert(ConnectionMap::value_type( dbConnection, 0 )).first; } if (connIter->second != 0 ) { // Then the connection already exists. theDatabase = connIter->second; //TODO: need to set dataType and DataAction theDatabase->setDataTypeAction(dataType, dataAction); } else // Database doesn't exist for this thread, so need to create it. { LOG(SourceInfo, DebugUtil::GenericLog, DebugUtil::DebugInfo, "New SimpleDbDatabase object created for thread %lu", threadId); theDatabase = new TA_Base_Core::SimpleDbDatabase(dataType, dataAction); // add to map connIter->second = theDatabase; } // Now that we have a database object, we need to connect it - do this everytime // 'cause if the database is alerady connected, nothing will happen, but if it has // been inadvertandtly disconnected, then it will be reconnected try // The connect line can generate a DatabaseException { theDatabase->connect( dbConnection ); // we can also exit the forever loop this (preferred) way FUNCTION_EXIT; return theDatabase; } catch (DatabaseException&) { // A DatabaseException was generated. Need to delete the database object for now. delete theDatabase; threadIter->second.erase(connIter); TA_Base_Core::Thread::sleep(100); // do not rethrow, just sleep for a while // there may be another database we can talk to. } } // end forever loop }