13c827367444ee418f129b2c238299f49d3264554Jarkko Poyry/*------------------------------------------------------------------------- 23c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * drawElements Quality Program Execution Server 33c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * --------------------------------------------- 43c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * 53c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * Copyright 2014 The Android Open Source Project 63c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * 73c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * Licensed under the Apache License, Version 2.0 (the "License"); 83c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * you may not use this file except in compliance with the License. 93c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * You may obtain a copy of the License at 103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * 113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * http://www.apache.org/licenses/LICENSE-2.0 123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * 133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * Unless required by applicable law or agreed to in writing, software 143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * distributed under the License is distributed on an "AS IS" BASIS, 153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * See the License for the specific language governing permissions and 173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * limitations under the License. 183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * 193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*! 203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \file 213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \brief Test Execution Server. 223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*--------------------------------------------------------------------*/ 233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "xsExecutionServer.hpp" 253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "deClock.h" 263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include <cstdio> 283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 293c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing std::vector; 303c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing std::string; 313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#if 1 333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry# define DBG_PRINT(X) printf X 343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#else 353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry# define DBG_PRINT(X) 363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#endif 373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 383c827367444ee418f129b2c238299f49d3264554Jarkko Poyrynamespace xs 393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 413c827367444ee418f129b2c238299f49d3264554Jarkko Poyryinline bool MessageBuilder::isComplete (void) const 423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (m_buffer.size() < MESSAGE_HEADER_SIZE) 443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return false; 453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 46745d7c616351405cfb6d2a7133d261eb4989d626Jarkko Pöyry return m_buffer.size() == getMessageSize(); 473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 493c827367444ee418f129b2c238299f49d3264554Jarkko Poyryconst deUint8* MessageBuilder::getMessageData (void) const 503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return m_buffer.size() > MESSAGE_HEADER_SIZE ? &m_buffer[MESSAGE_HEADER_SIZE] : DE_NULL; 523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 54745d7c616351405cfb6d2a7133d261eb4989d626Jarkko Pöyrysize_t MessageBuilder::getMessageDataSize (void) const 553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(isComplete()); 57745d7c616351405cfb6d2a7133d261eb4989d626Jarkko Pöyry return m_buffer.size() - MESSAGE_HEADER_SIZE; 583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 603c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid MessageBuilder::read (ByteBuffer& src) 613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Try to get header. 633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (m_buffer.size() < MESSAGE_HEADER_SIZE) 643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry while (m_buffer.size() < MESSAGE_HEADER_SIZE && 663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry src.getNumElements() > 0) 673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_buffer.push_back(src.popBack()); 683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(m_buffer.size() <= MESSAGE_HEADER_SIZE); 703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (m_buffer.size() == MESSAGE_HEADER_SIZE) 723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Got whole header, parse it. 743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry Message::parseHeader(&m_buffer[0], (int)m_buffer.size(), m_messageType, m_messageSize); 753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (m_buffer.size() >= MESSAGE_HEADER_SIZE) 793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // We have header. 81745d7c616351405cfb6d2a7133d261eb4989d626Jarkko Pöyry size_t msgSize = getMessageSize(); 82745d7c616351405cfb6d2a7133d261eb4989d626Jarkko Pöyry size_t numBytesLeft = msgSize - m_buffer.size(); 83745d7c616351405cfb6d2a7133d261eb4989d626Jarkko Pöyry size_t numToRead = (size_t)de::min(src.getNumElements(), (int)numBytesLeft); 843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (numToRead > 0) 863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int curBufPos = (int)m_buffer.size(); 883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_buffer.resize(curBufPos+numToRead); 89745d7c616351405cfb6d2a7133d261eb4989d626Jarkko Pöyry src.popBack(&m_buffer[curBufPos], (int)numToRead); 903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 943c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid MessageBuilder::clear (void) 953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_buffer.clear(); 973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_messageType = MESSAGETYPE_NONE; 983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_messageSize = 0; 993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 1003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1013c827367444ee418f129b2c238299f49d3264554Jarkko PoyryExecutionServer::ExecutionServer (xs::TestProcess* testProcess, deSocketFamily family, int port, RunMode runMode) 1023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry : TcpServer (family, port) 1033fdee359c9eee4d6c1d823b23f7f64631b5945f8Jarkko Pöyry , m_testDriver (testProcess) 1043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , m_runMode (runMode) 1053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 1063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 1073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1083c827367444ee418f129b2c238299f49d3264554Jarkko PoyryExecutionServer::~ExecutionServer (void) 1093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 1103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 1113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1123c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTestDriver* ExecutionServer::acquireTestDriver (void) 1133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 1143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (!m_testDriverLock.tryLock()) 1153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry throw Error("Failed to acquire test driver"); 1163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return &m_testDriver; 1183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 1193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1203c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ExecutionServer::releaseTestDriver (TestDriver* driver) 1213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 1223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(&m_testDriver == driver); 1233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_UNREF(driver); 1243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testDriverLock.unlock(); 1253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 1263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1273c827367444ee418f129b2c238299f49d3264554Jarkko PoyryConnectionHandler* ExecutionServer::createHandler (de::Socket* socket, const de::SocketAddress& clientAddress) 1283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 1293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry printf("ExecutionServer: New connection from %s:%d\n", clientAddress.getHost(), clientAddress.getPort()); 1303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return new ExecutionRequestHandler(this, socket); 1313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 1323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1333c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ExecutionServer::connectionDone (ConnectionHandler* handler) 1343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 1353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (m_runMode == RUNMODE_SINGLE_EXEC) 1363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_socket.close(); 1373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry TcpServer::connectionDone(handler); 1393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 1403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1413c827367444ee418f129b2c238299f49d3264554Jarkko PoyryExecutionRequestHandler::ExecutionRequestHandler (ExecutionServer* server, de::Socket* socket) 1423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry : ConnectionHandler (server, socket) 1433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , m_execServer (server) 1443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , m_testDriver (DE_NULL) 1453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , m_bufferIn (RECV_BUFFER_SIZE) 1463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , m_bufferOut (SEND_BUFFER_SIZE) 1473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , m_run (false) 1483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , m_sendRecvTmpBuf (SEND_RECV_TMP_BUFFER_SIZE) 1493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 1503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Set flags. 1513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_socket->setFlags(DE_SOCKET_NONBLOCKING|DE_SOCKET_KEEPALIVE|DE_SOCKET_CLOSE_ON_EXEC); 1523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Init protocol keepalives. 1543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry initKeepAlives(); 1553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 1563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1573c827367444ee418f129b2c238299f49d3264554Jarkko PoyryExecutionRequestHandler::~ExecutionRequestHandler (void) 1583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 1593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (m_testDriver) 1603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_execServer->releaseTestDriver(m_testDriver); 1613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 1623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1633c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ExecutionRequestHandler::handle (void) 1643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 1653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DBG_PRINT(("ExecutionRequestHandler::handle()\n")); 1663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry try 1683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 1693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Process execution session. 1703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry processSession(); 1713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 1723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry catch (const std::exception& e) 1733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 1743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry printf("ExecutionRequestHandler::run(): %s\n", e.what()); 1753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 1763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DBG_PRINT(("ExecutionRequestHandler::handle(): Done!\n")); 1783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Release test driver. 1803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (m_testDriver) 1813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 1823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry try 1833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 1843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testDriver->reset(); 1853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 1863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry catch (...) 1873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 1883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 1893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_execServer->releaseTestDriver(m_testDriver); 1903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testDriver = DE_NULL; 1913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 1923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Close connection. 1943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (m_socket->isConnected()) 1953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_socket->shutdown(); 1963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 1973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1983c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ExecutionRequestHandler::acquireTestDriver (void) 1993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 2003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(!m_testDriver); 2013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Try to acquire test driver - may fail. 2033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testDriver = m_execServer->acquireTestDriver(); 2043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(m_testDriver); 2053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testDriver->reset(); 2063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 2083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2093c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ExecutionRequestHandler::processSession (void) 2103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 2113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_run = true; 2123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry deUint64 lastIoTime = deGetMicroseconds(); 2143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry while (m_run) 2163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 2173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry bool anyIO = false; 2183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Read from socket to buffer. 2203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry anyIO = receive() || anyIO; 2213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Send bytes in buffer. 2233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry anyIO = send() || anyIO; 2243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Process incoming data. 2263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (m_bufferIn.getNumElements() > 0) 2273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 2283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(!m_msgBuilder.isComplete()); 2293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_msgBuilder.read(m_bufferIn); 2303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 2313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (m_msgBuilder.isComplete()) 2333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 2343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Process message. 2353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry processMessage(m_msgBuilder.getMessageType(), m_msgBuilder.getMessageData(), m_msgBuilder.getMessageDataSize()); 2363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_msgBuilder.clear(); 2383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 2393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Keepalives, anyone? 2413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry pollKeepAlives(); 2423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Poll test driver for IO. 2443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (m_testDriver) 2453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry anyIO = getTestDriver()->poll(m_bufferOut) || anyIO; 2463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // If no IO happens in a reasonable amount of time, go to sleep. 2483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 2493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry deUint64 curTime = deGetMicroseconds(); 2503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (anyIO) 2513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry lastIoTime = curTime; 2523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else if (curTime-lastIoTime > SERVER_IDLE_THRESHOLD*1000) 2533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry deSleep(SERVER_IDLE_SLEEP); // Too long since last IO, sleep for a while. 2543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 2553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry deYield(); // Just give other threads chance to run. 2563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 2573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 2583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 2593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 260745d7c616351405cfb6d2a7133d261eb4989d626Jarkko Pöyryvoid ExecutionRequestHandler::processMessage (MessageType type, const deUint8* data, size_t dataSize) 2613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 2623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry switch (type) 2633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 2643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case MESSAGETYPE_HELLO: 2653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 2663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry HelloMessage msg(data, dataSize); 2673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DBG_PRINT(("HelloMessage: version = %d\n", msg.version)); 2683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (msg.version != PROTOCOL_VERSION) 2693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry throw ProtocolError("Unsupported protocol version"); 2703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry break; 2713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 2723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case MESSAGETYPE_TEST: 2743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 2753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry TestMessage msg(data, dataSize); 2763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DBG_PRINT(("TestMessage: '%s'\n", msg.test.c_str())); 2773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry break; 2783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 2793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case MESSAGETYPE_KEEPALIVE: 2813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 2823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry KeepAliveMessage msg(data, dataSize); 2833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DBG_PRINT(("KeepAliveMessage\n")); 2843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry keepAliveReceived(); 2853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry break; 2863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 2873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case MESSAGETYPE_EXECUTE_BINARY: 2893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 2903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ExecuteBinaryMessage msg(data, dataSize); 2913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 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())); 2923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry getTestDriver()->startProcess(msg.name.c_str(), msg.params.c_str(), msg.workDir.c_str(), msg.caseList.c_str()); 2933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry keepAliveReceived(); // \todo [2011-10-11 pyry] Remove this once Candy is fixed. 2943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry break; 2953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 2963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case MESSAGETYPE_STOP_EXECUTION: 2983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 2993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry StopExecutionMessage msg(data, dataSize); 3003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DBG_PRINT(("StopExecutionMessage\n")); 3013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry getTestDriver()->stopProcess(); 3023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry break; 3033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 3043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry default: 3063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry throw ProtocolError("Unsupported message"); 3073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 3083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 3093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3103c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ExecutionRequestHandler::initKeepAlives (void) 3113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 3123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry deUint64 curTime = deGetMicroseconds(); 3133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_lastKeepAliveSent = curTime; 3143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_lastKeepAliveReceived = curTime; 3153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 3163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3173c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ExecutionRequestHandler::keepAliveReceived (void) 3183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 3193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_lastKeepAliveReceived = deGetMicroseconds(); 3203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 3213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3223c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ExecutionRequestHandler::pollKeepAlives (void) 3233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 3243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry deUint64 curTime = deGetMicroseconds(); 3253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Check that we've got keepalives in timely fashion. 3273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (curTime - m_lastKeepAliveReceived > KEEPALIVE_TIMEOUT*1000) 3283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry throw ProtocolError("Keepalive timeout occurred"); 3293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Send some? 3313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (curTime - m_lastKeepAliveSent > KEEPALIVE_SEND_INTERVAL*1000 && 3323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_bufferOut.getNumFree() >= MESSAGE_HEADER_SIZE) 3333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 3343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry vector<deUint8> buf; 3353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry KeepAliveMessage().write(buf); 3363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_bufferOut.pushFront(&buf[0], (int)buf.size()); 3373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_lastKeepAliveSent = deGetMicroseconds(); 3393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 3403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 3413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3423c827367444ee418f129b2c238299f49d3264554Jarkko Poyrybool ExecutionRequestHandler::receive (void) 3433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 344745d7c616351405cfb6d2a7133d261eb4989d626Jarkko Pöyry size_t maxLen = de::min(m_sendRecvTmpBuf.size(), (size_t)m_bufferIn.getNumFree()); 3453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (maxLen > 0) 3473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 348745d7c616351405cfb6d2a7133d261eb4989d626Jarkko Pöyry size_t numRecv; 3493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry deSocketResult result = m_socket->receive(&m_sendRecvTmpBuf[0], maxLen, &numRecv); 3503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (result == DE_SOCKETRESULT_SUCCESS) 3523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 3533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(numRecv > 0); 354745d7c616351405cfb6d2a7133d261eb4989d626Jarkko Pöyry m_bufferIn.pushFront(&m_sendRecvTmpBuf[0], (int)numRecv); 3553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return true; 3563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 3573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else if (result == DE_SOCKETRESULT_CONNECTION_CLOSED) 3583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 3593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_run = false; 3603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return true; 3613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 3623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else if (result == DE_SOCKETRESULT_WOULD_BLOCK) 3633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return false; 3643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else if (result == DE_SOCKETRESULT_CONNECTION_TERMINATED) 3653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry throw ConnectionError("Connection terminated"); 3663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 3673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry throw ConnectionError("receive() failed"); 3683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 3693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 3703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return false; 3713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 3723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3733c827367444ee418f129b2c238299f49d3264554Jarkko Poyrybool ExecutionRequestHandler::send (void) 3743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 375745d7c616351405cfb6d2a7133d261eb4989d626Jarkko Pöyry size_t maxLen = de::min(m_sendRecvTmpBuf.size(), (size_t)m_bufferOut.getNumElements()); 3763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (maxLen > 0) 3783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 379745d7c616351405cfb6d2a7133d261eb4989d626Jarkko Pöyry m_bufferOut.peekBack(&m_sendRecvTmpBuf[0], (int)maxLen); 3803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 381745d7c616351405cfb6d2a7133d261eb4989d626Jarkko Pöyry size_t numSent; 3823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry deSocketResult result = m_socket->send(&m_sendRecvTmpBuf[0], maxLen, &numSent); 3833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (result == DE_SOCKETRESULT_SUCCESS) 3853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 3863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(numSent > 0); 387745d7c616351405cfb6d2a7133d261eb4989d626Jarkko Pöyry m_bufferOut.popBack((int)numSent); 3883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return true; 3893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 3903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else if (result == DE_SOCKETRESULT_CONNECTION_CLOSED) 3913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 3923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_run = false; 3933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return true; 3943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 3953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else if (result == DE_SOCKETRESULT_WOULD_BLOCK) 3963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return false; 3973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else if (result == DE_SOCKETRESULT_CONNECTION_TERMINATED) 3983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry throw ConnectionError("Connection terminated"); 3993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 4003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry throw ConnectionError("send() failed"); 4013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 4023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 4033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return false; 4043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 4053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} // xs 407