void
CClientProxy1_0::disconnect()
{
	removeHandlers();
	getStream()->close();
	EVENTQUEUE->addEvent(CEvent(getDisconnectedEvent(), getEventTarget()));
}
Exemple #2
0
void
CTCPSocket::close()
{
	// remove ourself from the multiplexer
	setJob(NULL);

	CLock lock(&m_mutex);

	// clear buffers and enter disconnected state
	if (m_connected) {
		sendEvent(getDisconnectedEvent());
	}
	onDisconnected();

	// close the socket
	if (m_socket != NULL) {
		CArchSocket socket = m_socket;
		m_socket = NULL;
		try {
			ARCH->closeSocket(socket);
		}
		catch (XArchNetwork& e) {
			// ignore, there's not much we can do
			LOG((CLOG_WARN "error closing socket: %s", e.what().c_str()));
		}
	}
}
void
CIpcClientProxy::disconnect()
{
	LOG((CLOG_DEBUG "ipc disconnect, closing stream"));
	m_disconnecting = true;
	m_stream.close();
	EVENTQUEUE->addEvent(CEvent(getDisconnectedEvent(), this));
}
Exemple #4
0
void
CClient::handleDisconnected(const CEvent&, void*)
{
	cleanupTimer();
	cleanupScreen();
	cleanupConnection();
	LOG((CLOG_DEBUG1 "disconnected"));
	sendEvent(getDisconnectedEvent(), NULL);
}
Exemple #5
0
void
CClient::handleOutputError(const CEvent&, void*)
{
	cleanupTimer();
	cleanupScreen();
	cleanupConnection();
	LOG((CLOG_WARN "error sending to server"));
	sendEvent(getDisconnectedEvent(), NULL);
}
Exemple #6
0
void
CClient::disconnect(const char* msg)
{
	m_connectOnResume = false;
	cleanupTimer();
	cleanupScreen();
	cleanupConnecting();
	cleanupConnection();
	if (msg != NULL) {
		sendConnectionFailedEvent(msg);
	}
	else {
		sendEvent(getDisconnectedEvent(), NULL);
	}
}
Exemple #7
0
UInt32
CTCPSocket::read(void* buffer, UInt32 n)
{
	// copy data directly from our input buffer
	CLock lock(&m_mutex);
	UInt32 size = m_inputBuffer.getSize();
	if (n > size) {
		n = size;
	}
	if (buffer != NULL && n != 0) {
		memcpy(buffer, m_inputBuffer.peek(n), n);
	}
	m_inputBuffer.pop(n);

	// if no more data and we cannot read or write then send disconnected
	if (n > 0 && m_inputBuffer.getSize() == 0 && !m_readable && !m_writable) {
		sendEvent(getDisconnectedEvent());
		m_connected = false;
	}

	return n;
}
Exemple #8
0
ISocketMultiplexerJob*
CTCPSocket::serviceConnected(ISocketMultiplexerJob* job,
				bool read, bool write, bool error)
{
	CLock lock(&m_mutex);

	if (error) {
		sendEvent(getDisconnectedEvent());
		onDisconnected();
		return newJob();
	}

	bool needNewJob = false;

	if (write) {
		try {
			// write data
			UInt32 n = m_outputBuffer.getSize();
			const void* buffer = m_outputBuffer.peek(n);
			n = (UInt32)ARCH->writeSocket(m_socket, buffer, n);

			// discard written data
			if (n > 0) {
				m_outputBuffer.pop(n);
				if (m_outputBuffer.getSize() == 0) {
					sendEvent(getOutputFlushedEvent());
					m_flushed = true;
					m_flushed.broadcast();
					needNewJob = true;
				}
			}
		}
		catch (XArchNetworkShutdown&) {
			// remote read end of stream hungup.  our output side
			// has therefore shutdown.
			onOutputShutdown();
			sendEvent(getOutputShutdownEvent());
			if (!m_readable && m_inputBuffer.getSize() == 0) {
				sendEvent(getDisconnectedEvent());
				m_connected = false;
			}
			needNewJob = true;
		}
		catch (XArchNetworkDisconnected&) {
			// stream hungup
			onDisconnected();
			sendEvent(getDisconnectedEvent());
			needNewJob = true;
		}
		catch (XArchNetwork& e) {
			// other write error
			LOG((CLOG_WARN "error writing socket: %s", e.what().c_str()));
			onDisconnected();
			sendEvent(getOutputErrorEvent());
			sendEvent(getDisconnectedEvent());
			needNewJob = true;
		}
	}

	if (read && m_readable) {
		try {
			UInt8 buffer[4096];
			size_t n = ARCH->readSocket(m_socket, buffer, sizeof(buffer));
			if (n > 0) {
				bool wasEmpty = (m_inputBuffer.getSize() == 0);

				// slurp up as much as possible
				do {
					m_inputBuffer.write(buffer, n);
					n = ARCH->readSocket(m_socket, buffer, sizeof(buffer));
				} while (n > 0);

				// send input ready if input buffer was empty
				if (wasEmpty) {
					sendEvent(getInputReadyEvent());
				}
			}
			else {
				// remote write end of stream hungup.  our input side
				// has therefore shutdown but don't flush our buffer
				// since there's still data to be read.
				sendEvent(getInputShutdownEvent());
				if (!m_writable && m_inputBuffer.getSize() == 0) {
					sendEvent(getDisconnectedEvent());
					m_connected = false;
				}
				m_readable = false;
				needNewJob = true;
			}
		}
		catch (XArchNetworkDisconnected&) {
			// stream hungup
			sendEvent(getDisconnectedEvent());
			onDisconnected();
			needNewJob = true;
		}
		catch (XArchNetwork& e) {
			// ignore other read error
			LOG((CLOG_WARN "error reading socket: %s", e.what().c_str()));
		}
	}

	return needNewJob ? newJob() : job;
}