예제 #1
0
bool CClientService::ConnectPipes () {
	LOGINFO (TEXT ("Connecting pipes to JVM"));
	m_oPipesSemaphore.Wait ();
	if (!m_poPipes) {
		m_oPipesSemaphore.Signal ();
		LOGFATAL (TEXT ("Pipes not created"));
		assert (0);
		return false;
	}
	if (!m_poJVM) {
		m_oPipesSemaphore.Signal ();
		LOGFATAL (TEXT ("JVM not created"));
		assert (0);
		return false;
	}
	CSettings oSettings;
	const TCHAR *pszPipeName = oSettings.GetConnectionPipe ();
	LOGDEBUG (TEXT ("Connecting to ") << pszPipeName);
	unsigned long lTimeout = m_poJVM->FirstConnection () ? oSettings.GetStartTimeout () : oSettings.GetConnectTimeout ();
	m_lSendTimeout = lTimeout;
	m_lShortTimeout = oSettings.GetSendTimeout ();
	unsigned long lTime = GetTickCount ();
	CNamedPipe *poPipe;
	do {
		poPipe = CNamedPipe::ClientWrite (pszPipeName);
		if (poPipe) {
			break;
		} else {
			int ec = GetLastError ();
			if (ec == ENOENT) {
				if (GetTickCount () - lTime > lTimeout) {
					m_oPipesSemaphore.Signal ();
					LOGWARN (TEXT ("Timeout waiting for JVM service to open ") << pszPipeName);
					return false;
				} else {
					if (m_poJVM->IsAlive ()) {
						LOGDEBUG (TEXT ("Waiting for JVM service to open pipe"));
						CThread::Sleep (oSettings.GetServicePoll ());
					} else {
						m_oPipesSemaphore.Signal ();
						LOGWARN (TEXT ("JVM service terminated before opening ") << pszPipeName);
						return false;
					}
				}
			} else {
				m_oPipesSemaphore.Signal ();
				LOGWARN (TEXT ("Couldn't connect to ") << pszPipeName << TEXT (", error ") << ec);
				return false;
			}
		}
	} while (true);
	LOGDEBUG (TEXT ("Connected to service"));
	bool bResult = m_poPipes->Connect (m_pszLanguageID, poPipe, lTimeout);
	if (!bResult) {
		LOGWARN (TEXT ("Couldn't connect to JVM service, error ") << GetLastError ());
	}
	delete poPipe;
	m_oPipesSemaphore.Signal ();
	return bResult;
}
예제 #2
0
bool CClientService::Send (int cProcessingDirectives, FudgeMsg msg) const {
	FudgeStatus status;
	FudgeMsgEnvelope env;
	fudge_byte *ptrBuffer;
	fudge_i32 cbBuffer;
	if ((status = FudgeMsgEnvelope_create (&env, cProcessingDirectives, 0, 0, msg)) != FUDGE_OK) {
		LOGWARN (TEXT ("Couldn't create message envelope, status ") << status);
		return false;
	}
	status = FudgeCodec_encodeMsg (env, &ptrBuffer, &cbBuffer);
	FudgeMsgEnvelope_release (env);
	if (status != FUDGE_OK) {
		LOGWARN (TEXT ("Couldn't encode message, status ") << status);
		return false;
	}
	bool bResult;
	if (m_oPipesSemaphore.Wait (m_lSendTimeout)) {
		if (m_poPipes && m_poPipes->IsConnected ()) {
			int nPoll = 0;
			long lStartTime = GetTickCount ();
retrySend:
			if (m_poPipes->Write (ptrBuffer, cbBuffer, m_lSendTimeout)) {
				bResult = true;
			} else {
				int ec = GetLastError ();
#ifdef _WIN32
				if (ec == ERROR_PIPE_LISTENING) {
					// No process at the other end of the pipe
#else
				if (ec == EPIPE) {
					// Broken pipe -- they start off broken the way we create them
#endif
					if (GetTickCount () - lStartTime >= m_lSendTimeout) {
						LOGWARN (TEXT ("Timeout exceeded waiting for other end of the pipe"));
						ec = ETIMEDOUT;
					} else if (IsFirstConnection ()) {
						LOGDEBUG (TEXT ("No process at the other end of the pipe"));
						if (m_poJVM->IsAlive ()) {
							LOGDEBUG (TEXT ("Waiting for JVM"));
							if (!nPoll) {
								CSettings oSettings;
								nPoll = oSettings.GetServicePoll ();
							}
							CThread::Sleep (nPoll);
							goto retrySend;
						} else {
							LOGERROR (TEXT ("JVM service terminated before connecting to pipes, error ") << ec);
						}
					} else {
#ifdef _WIN32
						LOGFATAL (TEXT ("Not first connection but ERROR_PIPE_LISTENING returned"));
						assert (0);
#endif /* ifdef _WIN32 */
						LOGWARN (TEXT ("Couldn't write message, error ") << ec << TEXT (", rewritten to ENOTCONN"));
						ec = ENOTCONN;
					}
				} else {
					LOGWARN (TEXT ("Couldn't write message, error ") << ec);
				}
				SetLastError (ec);
				m_poPipes->Disconnected ();
				bResult = false;
			}
		} else {
			LOGWARN (TEXT ("Pipes not available for message"));
			bResult = false;
			SetLastError (ENOTCONN);
		}
		m_oPipesSemaphore.Signal ();
	} else {