ConnectionBase* ConnBoshMultStat::getConnection() { if( m_openRequests > 0 && m_openRequests >= m_maxOpenRequests ) { m_logInstance.warn( LogAreaClassConnectionBOSH, "Too many requests already open. Cannot send." ); return 0; } ConnectionBase* conn = 0; switch( m_connMode ) { case ModePipelining: if( !m_activeConnections.empty() ) { m_logInstance.dbg( LogAreaClassConnectionBOSH, "Using default connection for Pipelining." ); return m_activeConnections.front(); } else if( !m_connectionPool.empty() ) { m_logInstance.warn( LogAreaClassConnectionBOSH, "Pipelining selected, but no connection open. Opening one." ); return activateConnection(); } else m_logInstance.warn( LogAreaClassConnectionBOSH, "No available connections to pipeline on." ); break; case ModeLegacyHTTP: case ModePersistentHTTP: { if( !m_connectionPool.empty() ) { m_logInstance.dbg( LogAreaClassConnectionBOSH, "LegacyHTTP/PersistentHTTP selected, " "using connection from pool." ); return activateConnection(); } else if( !m_activeConnections.empty() ) { m_logInstance.dbg( LogAreaClassConnectionBOSH, "No connections in pool, creating a new one." ); conn = m_activeConnections.front()->newInstance(); conn->registerConnectionDataHandler( this ); m_connectionPool.push_back( conn ); conn->connect(); } else m_logInstance.warn( LogAreaClassConnectionBOSH, "No available connections to send on." ); break; } } return 0; }
int activateSession( INOUT SESSION_INFO *sessionInfoPtr ) { int streamState, status; assert( isWritePtr( sessionInfoPtr, sizeof( SESSION_INFO ) ) ); /* Activate the connection if necessary */ if( !( sessionInfoPtr->flags & SESSION_ISOPEN ) ) { /* Try and activate the session */ status = activateConnection( sessionInfoPtr ); if( cryptStatusError( status ) ) return( status ); /* The session activation succeeded, make sure that we don't try and replace the ephemeral attributes established during the session setup during any later operations. This is used for example when we're the server and the client provides us with authentication data but the validity of the data hasn't been confirmed yet by the user (see the comment about the CRYPT_ENVELOPE_RESOURCE status in activateConnection()), normally this would be deleted/overwritten when the session is recycled but once the caller has confirmed it as being valid we lock it to make sure that it won't be changed any more */ if( sessionInfoPtr->attributeList != NULL ) lockEphemeralAttributes( sessionInfoPtr->attributeList ); } /* If it's a secure data transport session it's up to the caller to move data over it, and we're done */ if( !sessionInfoPtr->protocolInfo->isReqResp ) return( CRYPT_OK ); /* Carry out a transaction on the request-response connection. We perform a cleanup of request/response data around the activation, beforehand to catch data such as responses left over from a previous transaction and afterwards to clean up ephemeral data such as requests sent to a server */ cleanupReqResp( sessionInfoPtr, TRUE ); status = sessionInfoPtr->transactFunction( sessionInfoPtr ); cleanupReqResp( sessionInfoPtr, FALSE ); if( cryptStatusError( status ) ) return( status ); /* Check whether the other side has indicated that it's closing the stream and if it has, shut down our side as well and record the fact that the session is now closed */ status = sioctlGet( &sessionInfoPtr->stream, STREAM_IOCTL_CONNSTATE, &streamState, sizeof( int ) ); if( cryptStatusError( status ) || !streamState ) { sessionInfoPtr->flags &= ~SESSION_ISOPEN; sessionInfoPtr->shutdownFunction( sessionInfoPtr ); } return( CRYPT_OK ); }
//----------------------------------------------------------------------------- // 描述: 借用连接 (由 ConnectionPool 调用) //----------------------------------------------------------------------------- bool DbConnection::getDbConnection() { if (!isBusy_) { activateConnection(); isBusy_ = true; return true; } return false; }