1e5c31af7Sopenharmony_ci/*-------------------------------------------------------------------------
2e5c31af7Sopenharmony_ci * drawElements Quality Program Execution Server
3e5c31af7Sopenharmony_ci * ---------------------------------------------
4e5c31af7Sopenharmony_ci *
5e5c31af7Sopenharmony_ci * Copyright 2014 The Android Open Source Project
6e5c31af7Sopenharmony_ci *
7e5c31af7Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
8e5c31af7Sopenharmony_ci * you may not use this file except in compliance with the License.
9e5c31af7Sopenharmony_ci * You may obtain a copy of the License at
10e5c31af7Sopenharmony_ci *
11e5c31af7Sopenharmony_ci *      http://www.apache.org/licenses/LICENSE-2.0
12e5c31af7Sopenharmony_ci *
13e5c31af7Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
14e5c31af7Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
15e5c31af7Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16e5c31af7Sopenharmony_ci * See the License for the specific language governing permissions and
17e5c31af7Sopenharmony_ci * limitations under the License.
18e5c31af7Sopenharmony_ci *
19e5c31af7Sopenharmony_ci *//*!
20e5c31af7Sopenharmony_ci * \file
21e5c31af7Sopenharmony_ci * \brief Test Execution Server.
22e5c31af7Sopenharmony_ci *//*--------------------------------------------------------------------*/
23e5c31af7Sopenharmony_ci
24e5c31af7Sopenharmony_ci#include "xsExecutionServer.hpp"
25e5c31af7Sopenharmony_ci#include "deClock.h"
26e5c31af7Sopenharmony_ci
27e5c31af7Sopenharmony_ci#include <cstdio>
28e5c31af7Sopenharmony_ci
29e5c31af7Sopenharmony_ciusing std::vector;
30e5c31af7Sopenharmony_ciusing std::string;
31e5c31af7Sopenharmony_ci
32e5c31af7Sopenharmony_ci#if 1
33e5c31af7Sopenharmony_ci#	define DBG_PRINT(X) printf X
34e5c31af7Sopenharmony_ci#else
35e5c31af7Sopenharmony_ci#	define DBG_PRINT(X)
36e5c31af7Sopenharmony_ci#endif
37e5c31af7Sopenharmony_ci
38e5c31af7Sopenharmony_cinamespace xs
39e5c31af7Sopenharmony_ci{
40e5c31af7Sopenharmony_ci
41e5c31af7Sopenharmony_ciinline bool MessageBuilder::isComplete (void) const
42e5c31af7Sopenharmony_ci{
43e5c31af7Sopenharmony_ci	if (m_buffer.size() < MESSAGE_HEADER_SIZE)
44e5c31af7Sopenharmony_ci		return false;
45e5c31af7Sopenharmony_ci	else
46e5c31af7Sopenharmony_ci		return m_buffer.size() == getMessageSize();
47e5c31af7Sopenharmony_ci}
48e5c31af7Sopenharmony_ci
49e5c31af7Sopenharmony_ciconst deUint8* MessageBuilder::getMessageData (void) const
50e5c31af7Sopenharmony_ci{
51e5c31af7Sopenharmony_ci	return m_buffer.size() > MESSAGE_HEADER_SIZE ? &m_buffer[MESSAGE_HEADER_SIZE] : DE_NULL;
52e5c31af7Sopenharmony_ci}
53e5c31af7Sopenharmony_ci
54e5c31af7Sopenharmony_cisize_t MessageBuilder::getMessageDataSize (void) const
55e5c31af7Sopenharmony_ci{
56e5c31af7Sopenharmony_ci	DE_ASSERT(isComplete());
57e5c31af7Sopenharmony_ci	return m_buffer.size() - MESSAGE_HEADER_SIZE;
58e5c31af7Sopenharmony_ci}
59e5c31af7Sopenharmony_ci
60e5c31af7Sopenharmony_civoid MessageBuilder::read (ByteBuffer& src)
61e5c31af7Sopenharmony_ci{
62e5c31af7Sopenharmony_ci	// Try to get header.
63e5c31af7Sopenharmony_ci	if (m_buffer.size() < MESSAGE_HEADER_SIZE)
64e5c31af7Sopenharmony_ci	{
65e5c31af7Sopenharmony_ci		while (m_buffer.size() < MESSAGE_HEADER_SIZE &&
66e5c31af7Sopenharmony_ci			   src.getNumElements() > 0)
67e5c31af7Sopenharmony_ci			m_buffer.push_back(src.popBack());
68e5c31af7Sopenharmony_ci
69e5c31af7Sopenharmony_ci		DE_ASSERT(m_buffer.size() <= MESSAGE_HEADER_SIZE);
70e5c31af7Sopenharmony_ci
71e5c31af7Sopenharmony_ci		if (m_buffer.size() == MESSAGE_HEADER_SIZE)
72e5c31af7Sopenharmony_ci		{
73e5c31af7Sopenharmony_ci			// Got whole header, parse it.
74e5c31af7Sopenharmony_ci			Message::parseHeader(&m_buffer[0], (int)m_buffer.size(), m_messageType, m_messageSize);
75e5c31af7Sopenharmony_ci		}
76e5c31af7Sopenharmony_ci	}
77e5c31af7Sopenharmony_ci
78e5c31af7Sopenharmony_ci	if (m_buffer.size() >= MESSAGE_HEADER_SIZE)
79e5c31af7Sopenharmony_ci	{
80e5c31af7Sopenharmony_ci		// We have header.
81e5c31af7Sopenharmony_ci		size_t msgSize			= getMessageSize();
82e5c31af7Sopenharmony_ci		size_t numBytesLeft		= msgSize - m_buffer.size();
83e5c31af7Sopenharmony_ci		size_t numToRead		= (size_t)de::min(src.getNumElements(), (int)numBytesLeft);
84e5c31af7Sopenharmony_ci
85e5c31af7Sopenharmony_ci		if (numToRead > 0)
86e5c31af7Sopenharmony_ci		{
87e5c31af7Sopenharmony_ci			int curBufPos = (int)m_buffer.size();
88e5c31af7Sopenharmony_ci			m_buffer.resize(curBufPos+numToRead);
89e5c31af7Sopenharmony_ci			src.popBack(&m_buffer[curBufPos], (int)numToRead);
90e5c31af7Sopenharmony_ci		}
91e5c31af7Sopenharmony_ci	}
92e5c31af7Sopenharmony_ci}
93e5c31af7Sopenharmony_ci
94e5c31af7Sopenharmony_civoid MessageBuilder::clear (void)
95e5c31af7Sopenharmony_ci{
96e5c31af7Sopenharmony_ci	m_buffer.clear();
97e5c31af7Sopenharmony_ci	m_messageType	= MESSAGETYPE_NONE;
98e5c31af7Sopenharmony_ci	m_messageSize	= 0;
99e5c31af7Sopenharmony_ci}
100e5c31af7Sopenharmony_ci
101e5c31af7Sopenharmony_ciExecutionServer::ExecutionServer (xs::TestProcess* testProcess, deSocketFamily family, int port, RunMode runMode)
102e5c31af7Sopenharmony_ci	: TcpServer		(family, port)
103e5c31af7Sopenharmony_ci	, m_testDriver	(testProcess)
104e5c31af7Sopenharmony_ci	, m_runMode		(runMode)
105e5c31af7Sopenharmony_ci{
106e5c31af7Sopenharmony_ci}
107e5c31af7Sopenharmony_ci
108e5c31af7Sopenharmony_ciExecutionServer::~ExecutionServer (void)
109e5c31af7Sopenharmony_ci{
110e5c31af7Sopenharmony_ci}
111e5c31af7Sopenharmony_ci
112e5c31af7Sopenharmony_ciTestDriver* ExecutionServer::acquireTestDriver (void)
113e5c31af7Sopenharmony_ci{
114e5c31af7Sopenharmony_ci	if (!m_testDriverLock.tryLock())
115e5c31af7Sopenharmony_ci		throw Error("Failed to acquire test driver");
116e5c31af7Sopenharmony_ci
117e5c31af7Sopenharmony_ci	return &m_testDriver;
118e5c31af7Sopenharmony_ci}
119e5c31af7Sopenharmony_ci
120e5c31af7Sopenharmony_civoid ExecutionServer::releaseTestDriver (TestDriver* driver)
121e5c31af7Sopenharmony_ci{
122e5c31af7Sopenharmony_ci	DE_ASSERT(&m_testDriver == driver);
123e5c31af7Sopenharmony_ci	DE_UNREF(driver);
124e5c31af7Sopenharmony_ci	m_testDriverLock.unlock();
125e5c31af7Sopenharmony_ci}
126e5c31af7Sopenharmony_ci
127e5c31af7Sopenharmony_ciConnectionHandler* ExecutionServer::createHandler (de::Socket* socket, const de::SocketAddress& clientAddress)
128e5c31af7Sopenharmony_ci{
129e5c31af7Sopenharmony_ci	printf("ExecutionServer: New connection from %s:%d\n", clientAddress.getHost(), clientAddress.getPort());
130e5c31af7Sopenharmony_ci	return new ExecutionRequestHandler(this, socket);
131e5c31af7Sopenharmony_ci}
132e5c31af7Sopenharmony_ci
133e5c31af7Sopenharmony_civoid ExecutionServer::connectionDone (ConnectionHandler* handler)
134e5c31af7Sopenharmony_ci{
135e5c31af7Sopenharmony_ci	if (m_runMode == RUNMODE_SINGLE_EXEC)
136e5c31af7Sopenharmony_ci		m_socket.close();
137e5c31af7Sopenharmony_ci
138e5c31af7Sopenharmony_ci	TcpServer::connectionDone(handler);
139e5c31af7Sopenharmony_ci}
140e5c31af7Sopenharmony_ci
141e5c31af7Sopenharmony_ciExecutionRequestHandler::ExecutionRequestHandler (ExecutionServer* server, de::Socket* socket)
142e5c31af7Sopenharmony_ci	: ConnectionHandler	(server, socket)
143e5c31af7Sopenharmony_ci	, m_execServer		(server)
144e5c31af7Sopenharmony_ci	, m_testDriver		(DE_NULL)
145e5c31af7Sopenharmony_ci	, m_bufferIn		(RECV_BUFFER_SIZE)
146e5c31af7Sopenharmony_ci	, m_bufferOut		(SEND_BUFFER_SIZE)
147e5c31af7Sopenharmony_ci	, m_run				(false)
148e5c31af7Sopenharmony_ci	, m_sendRecvTmpBuf	(SEND_RECV_TMP_BUFFER_SIZE)
149e5c31af7Sopenharmony_ci{
150e5c31af7Sopenharmony_ci	// Set flags.
151e5c31af7Sopenharmony_ci	m_socket->setFlags(DE_SOCKET_NONBLOCKING|DE_SOCKET_KEEPALIVE|DE_SOCKET_CLOSE_ON_EXEC);
152e5c31af7Sopenharmony_ci
153e5c31af7Sopenharmony_ci	// Init protocol keepalives.
154e5c31af7Sopenharmony_ci	initKeepAlives();
155e5c31af7Sopenharmony_ci}
156e5c31af7Sopenharmony_ci
157e5c31af7Sopenharmony_ciExecutionRequestHandler::~ExecutionRequestHandler (void)
158e5c31af7Sopenharmony_ci{
159e5c31af7Sopenharmony_ci	if (m_testDriver)
160e5c31af7Sopenharmony_ci		m_execServer->releaseTestDriver(m_testDriver);
161e5c31af7Sopenharmony_ci}
162e5c31af7Sopenharmony_ci
163e5c31af7Sopenharmony_civoid ExecutionRequestHandler::handle (void)
164e5c31af7Sopenharmony_ci{
165e5c31af7Sopenharmony_ci	DBG_PRINT(("ExecutionRequestHandler::handle()\n"));
166e5c31af7Sopenharmony_ci
167e5c31af7Sopenharmony_ci	try
168e5c31af7Sopenharmony_ci	{
169e5c31af7Sopenharmony_ci		// Process execution session.
170e5c31af7Sopenharmony_ci		processSession();
171e5c31af7Sopenharmony_ci	}
172e5c31af7Sopenharmony_ci	catch (const std::exception& e)
173e5c31af7Sopenharmony_ci	{
174e5c31af7Sopenharmony_ci		printf("ExecutionRequestHandler::run(): %s\n", e.what());
175e5c31af7Sopenharmony_ci	}
176e5c31af7Sopenharmony_ci
177e5c31af7Sopenharmony_ci	DBG_PRINT(("ExecutionRequestHandler::handle(): Done!\n"));
178e5c31af7Sopenharmony_ci
179e5c31af7Sopenharmony_ci	// Release test driver.
180e5c31af7Sopenharmony_ci	if (m_testDriver)
181e5c31af7Sopenharmony_ci	{
182e5c31af7Sopenharmony_ci		try
183e5c31af7Sopenharmony_ci		{
184e5c31af7Sopenharmony_ci			m_testDriver->reset();
185e5c31af7Sopenharmony_ci		}
186e5c31af7Sopenharmony_ci		catch (...)
187e5c31af7Sopenharmony_ci		{
188e5c31af7Sopenharmony_ci		}
189e5c31af7Sopenharmony_ci		m_execServer->releaseTestDriver(m_testDriver);
190e5c31af7Sopenharmony_ci		m_testDriver = DE_NULL;
191e5c31af7Sopenharmony_ci	}
192e5c31af7Sopenharmony_ci
193e5c31af7Sopenharmony_ci	// Close connection.
194e5c31af7Sopenharmony_ci	if (m_socket->isConnected())
195e5c31af7Sopenharmony_ci		m_socket->shutdown();
196e5c31af7Sopenharmony_ci}
197e5c31af7Sopenharmony_ci
198e5c31af7Sopenharmony_civoid ExecutionRequestHandler::acquireTestDriver (void)
199e5c31af7Sopenharmony_ci{
200e5c31af7Sopenharmony_ci	DE_ASSERT(!m_testDriver);
201e5c31af7Sopenharmony_ci
202e5c31af7Sopenharmony_ci	// Try to acquire test driver - may fail.
203e5c31af7Sopenharmony_ci	m_testDriver = m_execServer->acquireTestDriver();
204e5c31af7Sopenharmony_ci	DE_ASSERT(m_testDriver);
205e5c31af7Sopenharmony_ci	m_testDriver->reset();
206e5c31af7Sopenharmony_ci
207e5c31af7Sopenharmony_ci}
208e5c31af7Sopenharmony_ci
209e5c31af7Sopenharmony_civoid ExecutionRequestHandler::processSession (void)
210e5c31af7Sopenharmony_ci{
211e5c31af7Sopenharmony_ci	m_run = true;
212e5c31af7Sopenharmony_ci
213e5c31af7Sopenharmony_ci	deUint64 lastIoTime = deGetMicroseconds();
214e5c31af7Sopenharmony_ci
215e5c31af7Sopenharmony_ci	while (m_run)
216e5c31af7Sopenharmony_ci	{
217e5c31af7Sopenharmony_ci		bool anyIO = false;
218e5c31af7Sopenharmony_ci
219e5c31af7Sopenharmony_ci		// Read from socket to buffer.
220e5c31af7Sopenharmony_ci		anyIO = receive() || anyIO;
221e5c31af7Sopenharmony_ci
222e5c31af7Sopenharmony_ci		// Send bytes in buffer.
223e5c31af7Sopenharmony_ci		anyIO = send() || anyIO;
224e5c31af7Sopenharmony_ci
225e5c31af7Sopenharmony_ci		// Process incoming data.
226e5c31af7Sopenharmony_ci		if (m_bufferIn.getNumElements() > 0)
227e5c31af7Sopenharmony_ci		{
228e5c31af7Sopenharmony_ci			DE_ASSERT(!m_msgBuilder.isComplete());
229e5c31af7Sopenharmony_ci			m_msgBuilder.read(m_bufferIn);
230e5c31af7Sopenharmony_ci		}
231e5c31af7Sopenharmony_ci
232e5c31af7Sopenharmony_ci		if (m_msgBuilder.isComplete())
233e5c31af7Sopenharmony_ci		{
234e5c31af7Sopenharmony_ci			// Process message.
235e5c31af7Sopenharmony_ci			processMessage(m_msgBuilder.getMessageType(), m_msgBuilder.getMessageData(), m_msgBuilder.getMessageDataSize());
236e5c31af7Sopenharmony_ci
237e5c31af7Sopenharmony_ci			m_msgBuilder.clear();
238e5c31af7Sopenharmony_ci		}
239e5c31af7Sopenharmony_ci
240e5c31af7Sopenharmony_ci		// Keepalives, anyone?
241e5c31af7Sopenharmony_ci		pollKeepAlives();
242e5c31af7Sopenharmony_ci
243e5c31af7Sopenharmony_ci		// Poll test driver for IO.
244e5c31af7Sopenharmony_ci		if (m_testDriver)
245e5c31af7Sopenharmony_ci			anyIO = getTestDriver()->poll(m_bufferOut) || anyIO;
246e5c31af7Sopenharmony_ci
247e5c31af7Sopenharmony_ci		// If no IO happens in a reasonable amount of time, go to sleep.
248e5c31af7Sopenharmony_ci		{
249e5c31af7Sopenharmony_ci			deUint64 curTime = deGetMicroseconds();
250e5c31af7Sopenharmony_ci			if (anyIO)
251e5c31af7Sopenharmony_ci				lastIoTime = curTime;
252e5c31af7Sopenharmony_ci			else if (curTime-lastIoTime > SERVER_IDLE_THRESHOLD*1000)
253e5c31af7Sopenharmony_ci				deSleep(SERVER_IDLE_SLEEP); // Too long since last IO, sleep for a while.
254e5c31af7Sopenharmony_ci			else
255e5c31af7Sopenharmony_ci				deYield(); // Just give other threads chance to run.
256e5c31af7Sopenharmony_ci		}
257e5c31af7Sopenharmony_ci	}
258e5c31af7Sopenharmony_ci}
259e5c31af7Sopenharmony_ci
260e5c31af7Sopenharmony_civoid ExecutionRequestHandler::processMessage (MessageType type, const deUint8* data, size_t dataSize)
261e5c31af7Sopenharmony_ci{
262e5c31af7Sopenharmony_ci	switch (type)
263e5c31af7Sopenharmony_ci	{
264e5c31af7Sopenharmony_ci		case MESSAGETYPE_HELLO:
265e5c31af7Sopenharmony_ci		{
266e5c31af7Sopenharmony_ci			HelloMessage msg(data, dataSize);
267e5c31af7Sopenharmony_ci			DBG_PRINT(("HelloMessage: version = %d\n", msg.version));
268e5c31af7Sopenharmony_ci			if (msg.version != PROTOCOL_VERSION)
269e5c31af7Sopenharmony_ci				throw ProtocolError("Unsupported protocol version");
270e5c31af7Sopenharmony_ci			break;
271e5c31af7Sopenharmony_ci		}
272e5c31af7Sopenharmony_ci
273e5c31af7Sopenharmony_ci		case MESSAGETYPE_TEST:
274e5c31af7Sopenharmony_ci		{
275e5c31af7Sopenharmony_ci			TestMessage msg(data, dataSize);
276e5c31af7Sopenharmony_ci			DBG_PRINT(("TestMessage: '%s'\n", msg.test.c_str()));
277e5c31af7Sopenharmony_ci			break;
278e5c31af7Sopenharmony_ci		}
279e5c31af7Sopenharmony_ci
280e5c31af7Sopenharmony_ci		case MESSAGETYPE_KEEPALIVE:
281e5c31af7Sopenharmony_ci		{
282e5c31af7Sopenharmony_ci			KeepAliveMessage msg(data, dataSize);
283e5c31af7Sopenharmony_ci			DBG_PRINT(("KeepAliveMessage\n"));
284e5c31af7Sopenharmony_ci			keepAliveReceived();
285e5c31af7Sopenharmony_ci			break;
286e5c31af7Sopenharmony_ci		}
287e5c31af7Sopenharmony_ci
288e5c31af7Sopenharmony_ci		case MESSAGETYPE_EXECUTE_BINARY:
289e5c31af7Sopenharmony_ci		{
290e5c31af7Sopenharmony_ci			ExecuteBinaryMessage msg(data, dataSize);
291e5c31af7Sopenharmony_ci			DBG_PRINT(("ExecuteBinaryMessage: '%s', '%s', '%s', '%s'\n", msg.name.c_str(), msg.params.c_str(), msg.workDir.c_str(), msg.caseList.substr(0, 10).c_str()));
292e5c31af7Sopenharmony_ci			getTestDriver()->startProcess(msg.name.c_str(), msg.params.c_str(), msg.workDir.c_str(), msg.caseList.c_str());
293e5c31af7Sopenharmony_ci			keepAliveReceived(); // \todo [2011-10-11 pyry] Remove this once Candy is fixed.
294e5c31af7Sopenharmony_ci			break;
295e5c31af7Sopenharmony_ci		}
296e5c31af7Sopenharmony_ci
297e5c31af7Sopenharmony_ci		case MESSAGETYPE_STOP_EXECUTION:
298e5c31af7Sopenharmony_ci		{
299e5c31af7Sopenharmony_ci			StopExecutionMessage msg(data, dataSize);
300e5c31af7Sopenharmony_ci			DBG_PRINT(("StopExecutionMessage\n"));
301e5c31af7Sopenharmony_ci			getTestDriver()->stopProcess();
302e5c31af7Sopenharmony_ci			break;
303e5c31af7Sopenharmony_ci		}
304e5c31af7Sopenharmony_ci
305e5c31af7Sopenharmony_ci		default:
306e5c31af7Sopenharmony_ci			throw ProtocolError("Unsupported message");
307e5c31af7Sopenharmony_ci	}
308e5c31af7Sopenharmony_ci}
309e5c31af7Sopenharmony_ci
310e5c31af7Sopenharmony_civoid ExecutionRequestHandler::initKeepAlives (void)
311e5c31af7Sopenharmony_ci{
312e5c31af7Sopenharmony_ci	deUint64 curTime = deGetMicroseconds();
313e5c31af7Sopenharmony_ci	m_lastKeepAliveSent		= curTime;
314e5c31af7Sopenharmony_ci	m_lastKeepAliveReceived	= curTime;
315e5c31af7Sopenharmony_ci}
316e5c31af7Sopenharmony_ci
317e5c31af7Sopenharmony_civoid ExecutionRequestHandler::keepAliveReceived (void)
318e5c31af7Sopenharmony_ci{
319e5c31af7Sopenharmony_ci	m_lastKeepAliveReceived = deGetMicroseconds();
320e5c31af7Sopenharmony_ci}
321e5c31af7Sopenharmony_ci
322e5c31af7Sopenharmony_civoid ExecutionRequestHandler::pollKeepAlives (void)
323e5c31af7Sopenharmony_ci{
324e5c31af7Sopenharmony_ci	deUint64 curTime = deGetMicroseconds();
325e5c31af7Sopenharmony_ci
326e5c31af7Sopenharmony_ci	// Check that we've got keepalives in timely fashion.
327e5c31af7Sopenharmony_ci	if (curTime - m_lastKeepAliveReceived > KEEPALIVE_TIMEOUT*1000)
328e5c31af7Sopenharmony_ci		throw ProtocolError("Keepalive timeout occurred");
329e5c31af7Sopenharmony_ci
330e5c31af7Sopenharmony_ci	// Send some?
331e5c31af7Sopenharmony_ci	if (curTime - m_lastKeepAliveSent > KEEPALIVE_SEND_INTERVAL*1000 &&
332e5c31af7Sopenharmony_ci		m_bufferOut.getNumFree() >= MESSAGE_HEADER_SIZE)
333e5c31af7Sopenharmony_ci	{
334e5c31af7Sopenharmony_ci		vector<deUint8> buf;
335e5c31af7Sopenharmony_ci		KeepAliveMessage().write(buf);
336e5c31af7Sopenharmony_ci		m_bufferOut.pushFront(&buf[0], (int)buf.size());
337e5c31af7Sopenharmony_ci
338e5c31af7Sopenharmony_ci		m_lastKeepAliveSent = deGetMicroseconds();
339e5c31af7Sopenharmony_ci	}
340e5c31af7Sopenharmony_ci}
341e5c31af7Sopenharmony_ci
342e5c31af7Sopenharmony_cibool ExecutionRequestHandler::receive (void)
343e5c31af7Sopenharmony_ci{
344e5c31af7Sopenharmony_ci	size_t maxLen = de::min(m_sendRecvTmpBuf.size(), (size_t)m_bufferIn.getNumFree());
345e5c31af7Sopenharmony_ci
346e5c31af7Sopenharmony_ci	if (maxLen > 0)
347e5c31af7Sopenharmony_ci	{
348e5c31af7Sopenharmony_ci		size_t			numRecv;
349e5c31af7Sopenharmony_ci		deSocketResult	result	= m_socket->receive(&m_sendRecvTmpBuf[0], maxLen, &numRecv);
350e5c31af7Sopenharmony_ci
351e5c31af7Sopenharmony_ci		if (result == DE_SOCKETRESULT_SUCCESS)
352e5c31af7Sopenharmony_ci		{
353e5c31af7Sopenharmony_ci			DE_ASSERT(numRecv > 0);
354e5c31af7Sopenharmony_ci			m_bufferIn.pushFront(&m_sendRecvTmpBuf[0], (int)numRecv);
355e5c31af7Sopenharmony_ci			return true;
356e5c31af7Sopenharmony_ci		}
357e5c31af7Sopenharmony_ci		else if (result == DE_SOCKETRESULT_CONNECTION_CLOSED)
358e5c31af7Sopenharmony_ci		{
359e5c31af7Sopenharmony_ci			m_run = false;
360e5c31af7Sopenharmony_ci			return true;
361e5c31af7Sopenharmony_ci		}
362e5c31af7Sopenharmony_ci		else if (result == DE_SOCKETRESULT_WOULD_BLOCK)
363e5c31af7Sopenharmony_ci			return false;
364e5c31af7Sopenharmony_ci		else if (result == DE_SOCKETRESULT_CONNECTION_TERMINATED)
365e5c31af7Sopenharmony_ci			throw ConnectionError("Connection terminated");
366e5c31af7Sopenharmony_ci		else
367e5c31af7Sopenharmony_ci			throw ConnectionError("receive() failed");
368e5c31af7Sopenharmony_ci	}
369e5c31af7Sopenharmony_ci	else
370e5c31af7Sopenharmony_ci		return false;
371e5c31af7Sopenharmony_ci}
372e5c31af7Sopenharmony_ci
373e5c31af7Sopenharmony_cibool ExecutionRequestHandler::send (void)
374e5c31af7Sopenharmony_ci{
375e5c31af7Sopenharmony_ci	size_t maxLen = de::min(m_sendRecvTmpBuf.size(), (size_t)m_bufferOut.getNumElements());
376e5c31af7Sopenharmony_ci
377e5c31af7Sopenharmony_ci	if (maxLen > 0)
378e5c31af7Sopenharmony_ci	{
379e5c31af7Sopenharmony_ci		m_bufferOut.peekBack(&m_sendRecvTmpBuf[0], (int)maxLen);
380e5c31af7Sopenharmony_ci
381e5c31af7Sopenharmony_ci		size_t			numSent;
382e5c31af7Sopenharmony_ci		deSocketResult	result	= m_socket->send(&m_sendRecvTmpBuf[0], maxLen, &numSent);
383e5c31af7Sopenharmony_ci
384e5c31af7Sopenharmony_ci		if (result == DE_SOCKETRESULT_SUCCESS)
385e5c31af7Sopenharmony_ci		{
386e5c31af7Sopenharmony_ci			DE_ASSERT(numSent > 0);
387e5c31af7Sopenharmony_ci			m_bufferOut.popBack((int)numSent);
388e5c31af7Sopenharmony_ci			return true;
389e5c31af7Sopenharmony_ci		}
390e5c31af7Sopenharmony_ci		else if (result == DE_SOCKETRESULT_CONNECTION_CLOSED)
391e5c31af7Sopenharmony_ci		{
392e5c31af7Sopenharmony_ci			m_run = false;
393e5c31af7Sopenharmony_ci			return true;
394e5c31af7Sopenharmony_ci		}
395e5c31af7Sopenharmony_ci		else if (result == DE_SOCKETRESULT_WOULD_BLOCK)
396e5c31af7Sopenharmony_ci			return false;
397e5c31af7Sopenharmony_ci		else if (result == DE_SOCKETRESULT_CONNECTION_TERMINATED)
398e5c31af7Sopenharmony_ci			throw ConnectionError("Connection terminated");
399e5c31af7Sopenharmony_ci		else
400e5c31af7Sopenharmony_ci			throw ConnectionError("send() failed");
401e5c31af7Sopenharmony_ci	}
402e5c31af7Sopenharmony_ci	else
403e5c31af7Sopenharmony_ci		return false;
404e5c31af7Sopenharmony_ci}
405e5c31af7Sopenharmony_ci
406e5c31af7Sopenharmony_ci} // xs
407