ConnectionManager.cpp #3

  • //
  • guest/
  • eskopljak/
  • p4api.net/
  • main/
  • p4bridge/
  • ConnectionManager.cpp
  • View
  • Commits
  • Open Download .zip Download (7 KB)
#include "StdAfx.h"

#include "P4Connection.h"
#include "P4BridgeClient.h"
#include "P4BridgeServer.h"
#include "ConnectionManager.h"

#define DELETE_OBJECT(obj) if( obj != NULL ) { delete obj; obj = NULL; }

//#ifdef _DEBUG_MEMORY
//IdleConnection::IdleConnection(P4Connection* pcon, _int64 releaseTime)
//		: DoublyLinkedListItem(NULL), p4base(tIdleConnection) 
//{ 
//	pCon = pcon; 
//	ReleaseTime = releaseTime;
//} 
//#endif
//IdleConnection::~IdleConnection(void)
//{
//	DELETE_OBJECT(pCon);
//}

#ifdef _DEBUG_MEMORY
ConnectionManager::ConnectionManager(P4BridgeServer* pserver)
	: DoublyLinkedList(&(pserver->Locker)), p4base(tConnectionManager)
#else
ConnectionManager::ConnectionManager(P4BridgeServer* pserver)
	: DoublyLinkedList(&(pserver->Locker))
#endif
{
	Initialized = 0;

	pServer = pserver;

	client = NULL;
	user = NULL;
	port = NULL;
	password = NULL;
	programName = NULL;
	programVer = NULL;
	cwd = NULL;

	charset = (CharSetApi::CharSet) 0;
	file_charset = (CharSetApi::CharSet) 0;

	IdleConnections = new DoublyLinkedList(&(pserver->Locker));
}

ConnectionManager::~ConnectionManager(void)
{
	if (disposed != 0)
	{
		return;
	}
	LOCK(&pServer->Locker); 

	disposed = 1;

	DiscardConnections();

	// The P4Connection list will be deleted by the destructor for DoublyLinkedList
	//P4Connection* connection = (P4Connection*)First();

	//while (connection)
	//{
	//	P4Connection* nextConnection = (P4Connection*)connection->Next();
	//	delete connection;
	//	connection = nextConnection;
	//}

	Initialized = 0;

	DELETE_OBJECT(client);
	DELETE_OBJECT(user);
	DELETE_OBJECT(port);
	DELETE_OBJECT(password);
	DELETE_OBJECT(programName);
	DELETE_OBJECT(programVer);
	DELETE_OBJECT(cwd);
}
	
const StrPtr* ConnectionManager::GetCharset( )
{
	const StrPtr* ret = &(GetConnection(0)->GetCharset( ));
	ReleaseConnection(0,0);
	return ret;
}

int ConnectionManager::Disconnect( void )
{
	LOCK(&pServer->Locker); 

	Initialized = 0;

	P4Connection* connection = (P4Connection*)First();

	while (connection)
	{
		if (connection->Id >=1)
		{
			// this connection is running a command and so it cannot
			// be closed, set initialized to false, so it will reinitialize 
			// for the next command

			//connection->clientNeedsInit = 1;
			//Initialized = 0;

			return 0;
		}
		connection = (P4Connection*)connection->Next();;
	}
	// not running any commands, so discard all connections

	DiscardConnections();
	return 1;
}

void ConnectionManager::DiscardConnections()
{
	// discard idle connections
	DELETE_OBJECT(IdleConnections);

	//while (idle)
	//{
	//	IdleConnection* pCur = idle;

	//	idle = (IdleConnection*)pCur->Prev();
	//	pCur->pCon->Disconnect();

	//	delete pCur;
	//}

	P4Connection* connection = (P4Connection*)Last();

	while (connection)
	{
		P4Connection* pCur = connection;
		connection = (P4Connection*)pCur->Prev();
		pCur->Disconnect();

		delete pCur;
	}
	this->pFirstItem = NULL;
	this->pLastItem = NULL;
}
P4Connection* ConnectionManager::GetConnection(int cmdId)
{
	LOCK(&pServer->Locker); 

	P4Connection* con = (P4Connection*)Find(cmdId);

	if (con) 
	{
		return con;
	}
	if (!IdleConnections)
	{
		IdleConnections = new DoublyLinkedList(&(pServer->Locker));
	}
	P4Connection* idle = (P4Connection*)IdleConnections->First();
	if (idle)
	{
		//LOG_DEBUG1(4 ,"Using existing Connection for command: %X", cmdId);
		//LOG_DEBUG1(4 ,"Now have %d connections in ConnectionManager", itemCount);
		con = idle;
		con->Id = cmdId;

		IdleConnections->Remove(idle,0);

		Add(con);
		return con;
	}
	return NewConnection(cmdId);
}

void ConnectionManager::ReleaseConnection(int cmdId, unsigned _int64 releaseTime)
{
	LOCK(&pServer->Locker); 

	P4Connection* con = (P4Connection*)Find(cmdId);

	ReleaseConnection(con, releaseTime);
}

void ConnectionManager::ReleaseConnection(P4Connection* con, unsigned _int64 releaseTime)
{
	if (con)
	{
		con->ui->clear_results();
		Remove(con, 0);
		con->Id = -1;
		con->ReleaseTime = releaseTime;
		IdleConnections->Add(con);
	}
}

int ConnectionManager::FreeConnections( unsigned _int64 currentTime )
{
	LOCK(&pServer->Locker); 

	if (!IdleConnections)
	{
		return 0;
	}

	P4Connection* con = (P4Connection*)IdleConnections->First();

	while (con)
	{
		if (con->ReleaseTime > currentTime)
		{
			break;
		}
		con->Disconnect();
		IdleConnections->Remove(con);

		con = (P4Connection*)IdleConnections->First();
	}
	return IdleConnections->Count();
}

P4Connection* ConnectionManager::NewConnection(int cmdId)
{
	//LOG_DEBUG1(4 ,"Creating a new Connection for command: %X", cmdId);
	//LOG_DEBUG1(4 ,"Now have %d connections in ConnectionManager", itemCount);

	LOCK(&pServer->Locker); 

	P4Connection* con = new P4Connection(this, pServer, cmdId);

	con->ui = new P4BridgeClient(pServer, con);

	if (client) con->SetClient(	client);
	if (user) con->SetUser(user);
	if (port) con->SetPort(port);
	if (password) con->SetPassword(password);
	if (programName) con->SetProg(programName);
	if (programVer) con->SetVersion(programVer);
	if (cwd) con->SetCwd(cwd);

	con->SetProtocol( "specstring", "" ); 
	con->SetProtocol( "enableStreams", "" );
	con->SetProtocol( "wingui", "999" );
	
	// Set the character set for the untagged client
	con->SetCharset(charset, file_charset);

	return con;
}

//P4Connection* ConnectionManager::DefaultConnection() 
//{ 
//	P4Connection* value = (P4Connection*) Find(0);
//	if (value) 
//	{
//		return value;
//	}
//	return NewConnection(0);
//}

void ConnectionManager::SetCharset( CharSetApi::CharSet c, CharSetApi::CharSet filec )
{
	charset = c; 
	file_charset = filec;	
	P4Connection* curCon = (P4Connection*)pFirstItem;
	while (curCon)
	{
		curCon->SetCharset(c, filec);
		curCon = (P4Connection*) curCon->Next();
	}
	if (!IdleConnections)
	{
		return;
	}
	P4Connection* curCon2 = (P4Connection*)IdleConnections->First();
	while (curCon2)
	{
		curCon2->SetCharset(c, filec);
		curCon2 = (P4Connection*) curCon2->Next();
	}
}

void ConnectionManager::SetCwd( const char* newCwd ) 
{
	DELETE_OBJECT(cwd);

	cwd = CopyStr(newCwd);
	if (!pFirstItem)
	{
		//DefaultConnection();
		return;
	}
	P4Connection* curCon = (P4Connection*)pFirstItem;
	while (curCon)
	{
		curCon->SetCwd(newCwd);
		curCon = (P4Connection*) curCon->Next();
	}
	if (!IdleConnections)
	{
		return;
	}
	P4Connection* curCon2 = (P4Connection*)IdleConnections->First();
	while (curCon2)
	{
		curCon2->SetCwd(newCwd);
		curCon2 = (P4Connection*) curCon2->Next();
	}
}

	void ConnectionManager::SetClient( const char* newVal ) 
	{
		DELETE_OBJECT(client);
		if (newVal) client = CopyStr(newVal);
	}
	void ConnectionManager::SetUser( const char* newVal ) 
	{
		DELETE_OBJECT(user);
		if (newVal) user = CopyStr(newVal);
	}
	void ConnectionManager::SetPort( const char* newVal ) 
	{
		DELETE_OBJECT(port);
		if (newVal) port = CopyStr(newVal);
	}
	void ConnectionManager::SetPassword( const char* newVal ) 
	{
		DELETE_OBJECT(password);
		if (newVal)	password = CopyStr(newVal);
	}
	void ConnectionManager::SetProgramName( const char* newVal ) 
	{
		DELETE_OBJECT(programName);
		if (newVal) programName = CopyStr(newVal);
	}
	void ConnectionManager::SetProgramVer( const char* newVal ) 
	{
		DELETE_OBJECT(programVer);
		if (newVal) programVer = CopyStr(newVal);
	}
# Change User Description Committed
#3 28480 eskopljak submit
#2 28479 eskopljak submit
#1 28441 eskopljak Merging using p4api.net_branch
//guest/perforce_software/p4api-net/main/p4bridge/ConnectionManager.cpp
#1 19043 Liz Lam Rename p4api.net to p4api-net
//guest/perforce_software/p4api.net/main/p4bridge/ConnectionManager.cpp
#1 19042 Liz Lam Rename/move file(s) to proper main branch.
//guest/perforce_software/p4api.net/p4bridge/ConnectionManager.cpp
#4 11220 Matt Attaway Update Workshop version with most recent 14.2 patch of p4api.net
#3 10191 Matt Attaway Bring Workshop version of p4api.net up-to-date with the 14.2 release.
#2 8964 Bill fix line endings
#1 8873 Matt Attaway Initial add of the P4API.NET source code