예제 #1
0
  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;
  }
예제 #2
0
    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
	}