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 TestProcess implementation for Win32. 223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*--------------------------------------------------------------------*/ 233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "xsWin32TestProcess.hpp" 253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "deFilePath.hpp" 263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "deString.h" 273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "deMemory.h" 283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "deClock.h" 293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "deFile.h" 303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include <sstream> 323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include <string.h> 333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 343c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing std::string; 353c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing std::vector; 363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 373c827367444ee418f129b2c238299f49d3264554Jarkko Poyrynamespace xs 383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 403c827367444ee418f129b2c238299f49d3264554Jarkko Poyryenum 413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry MAX_OLD_LOGFILE_DELETE_ATTEMPTS = 20, //!< How many times execserver tries to delete old log file 433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry LOGFILE_DELETE_SLEEP_MS = 50 //!< Sleep time (in ms) between log file delete attempts 443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 463c827367444ee418f129b2c238299f49d3264554Jarkko Poyrynamespace win32 473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// Error 503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 513c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic std::string formatErrMsg (DWORD error, const char* msg) 523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry std::ostringstream str; 543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry LPSTR msgBuf; 553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#if defined(UNICODE) 573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry# error Unicode not supported. 583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#endif 593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER|FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS, 613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry NULL, error, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPSTR)&msgBuf, 0, DE_NULL) > 0) 623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry str << msg << ", error " << error << ": " << msgBuf; 633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry str << msg << ", error " << error; 653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return str.str(); 673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 693c827367444ee418f129b2c238299f49d3264554Jarkko PoyryError::Error (DWORD error, const char* msg) 703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry : std::runtime_error(formatErrMsg(error, msg)) 713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , m_error (error) 723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// Event 763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 773c827367444ee418f129b2c238299f49d3264554Jarkko PoyryEvent::Event (bool manualReset, bool initialState) 783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry : m_handle(0) 793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_handle = CreateEvent(NULL, manualReset ? TRUE : FALSE, initialState ? TRUE : FALSE, NULL); 813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (!m_handle) 823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry throw Error(GetLastError(), "CreateEvent() failed"); 833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 853c827367444ee418f129b2c238299f49d3264554Jarkko PoyryEvent::~Event (void) 863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry CloseHandle(m_handle); 883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 903c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid Event::setSignaled (void) 913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (!SetEvent(m_handle)) 933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry throw Error(GetLastError(), "SetEvent() failed"); 943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 963c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid Event::reset (void) 973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (!ResetEvent(m_handle)) 993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry throw Error(GetLastError(), "ResetEvent() failed"); 1003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 1013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// CaseListWriter 1033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1043c827367444ee418f129b2c238299f49d3264554Jarkko PoyryCaseListWriter::CaseListWriter (void) 1053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry : m_dst (INVALID_HANDLE_VALUE) 1063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , m_cancelEvent (true, false) 1073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 1083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 1093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1103c827367444ee418f129b2c238299f49d3264554Jarkko PoyryCaseListWriter::~CaseListWriter (void) 1113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 1123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 1133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1143c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid CaseListWriter::start (const char* caseList, HANDLE dst) 1153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 1163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(!isStarted()); 1173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_dst = dst; 1193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int caseListSize = (int)strlen(caseList)+1; 1213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_caseList.resize(caseListSize); 1223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry std::copy(caseList, caseList+caseListSize, m_caseList.begin()); 1233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry de::Thread::start(); 1253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 1263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1273c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid CaseListWriter::run (void) 1283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 1293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry try 1303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 1313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry Event ioEvent (true, false); // Manual reset, non-signaled state. 1323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry HANDLE waitHandles[] = { ioEvent.getHandle(), m_cancelEvent.getHandle() }; 1333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry OVERLAPPED overlapped; 1343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int curPos = 0; 1353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry deMemset(&overlapped, 0, sizeof(overlapped)); 1373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry overlapped.hEvent = ioEvent.getHandle(); 1383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry while (curPos < (int)m_caseList.size()) 1403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 1413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int maxWriteSize = 4096; 1423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int numToWrite = de::min(maxWriteSize, (int)m_caseList.size() - curPos); 1433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DWORD waitRes = 0; 1443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (!WriteFile(m_dst, &m_caseList[curPos], (DWORD)numToWrite, NULL, &overlapped)) 1463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 1473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DWORD err = GetLastError(); 1483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (err != ERROR_IO_PENDING) 1493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry throw Error(err, "WriteFile() failed"); 1503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 1513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry waitRes = WaitForMultipleObjects(DE_LENGTH_OF_ARRAY(waitHandles), &waitHandles[0], FALSE, INFINITE); 1533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (waitRes == WAIT_OBJECT_0) 1553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 1563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DWORD numBytesWritten = 0; 1573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // \note GetOverlappedResult() will fail with ERROR_IO_INCOMPLETE if IO event is not complete (should be). 1593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (!GetOverlappedResult(m_dst, &overlapped, &numBytesWritten, FALSE)) 1603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry throw Error(GetLastError(), "GetOverlappedResult() failed"); 1613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (numBytesWritten == 0) 1633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry throw Error(GetLastError(), "Writing to pipe failed (pipe closed?)"); 1643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry curPos += (int)numBytesWritten; 1663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 1673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else if (waitRes == WAIT_OBJECT_0 + 1) 1683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 1693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Cancel. 1703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (!CancelIo(m_dst)) 1713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry throw Error(GetLastError(), "CancelIo() failed"); 1723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry break; 1733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 1743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 1753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry throw Error(GetLastError(), "WaitForMultipleObjects() failed"); 1763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 1773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 1783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry catch (const std::exception& e) 1793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 1803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // \todo [2013-08-13 pyry] What to do about this? 1813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry printf("win32::CaseListWriter::run(): %s\n", e.what()); 1823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 1833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 1843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1853c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid CaseListWriter::stop (void) 1863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 1873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (!isStarted()) 1883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return; // Nothing to do. 1893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_cancelEvent.setSignaled(); 1913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Join thread. 1933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry join(); 1943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_cancelEvent.reset(); 1963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_dst = INVALID_HANDLE_VALUE; 1983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 1993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// FileReader 2013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2023c827367444ee418f129b2c238299f49d3264554Jarkko PoyryFileReader::FileReader (ThreadedByteBuffer* dst) 2033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry : m_dstBuf (dst) 2043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , m_handle (INVALID_HANDLE_VALUE) 2053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , m_cancelEvent (false, false) 2063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 2073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 2083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2093c827367444ee418f129b2c238299f49d3264554Jarkko PoyryFileReader::~FileReader (void) 2103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 2113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 2123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2133c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid FileReader::start (HANDLE file) 2143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 2153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(!isStarted()); 2163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_handle = file; 2183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry de::Thread::start(); 2203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 2213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2223c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid FileReader::run (void) 2233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 2243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry try 2253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 2263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry Event ioEvent (true, false); // Manual reset, not signaled state. 2273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry HANDLE waitHandles[] = { ioEvent.getHandle(), m_cancelEvent.getHandle() }; 2283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry OVERLAPPED overlapped; 2293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry std::vector<deUint8> tmpBuf (FILEREADER_TMP_BUFFER_SIZE); 2303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry deUint64 offset = 0; // Overlapped IO requires manual offset keeping. 2313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry deMemset(&overlapped, 0, sizeof(overlapped)); 2333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry overlapped.hEvent = ioEvent.getHandle(); 2343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (;;) 2363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 2373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DWORD numBytesRead = 0; 2383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DWORD waitRes; 2393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry overlapped.Offset = (DWORD)(offset & 0xffffffffu); 2413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry overlapped.OffsetHigh = (DWORD)(offset >> 32); 2423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (!ReadFile(m_handle, &tmpBuf[0], (DWORD)tmpBuf.size(), NULL, &overlapped)) 2443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 2453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DWORD err = GetLastError(); 2463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (err == ERROR_BROKEN_PIPE) 2483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry break; 2493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else if (err == ERROR_HANDLE_EOF) 2503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 2513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (m_dstBuf->isCanceled()) 2523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry break; 2533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry deSleep(FILEREADER_IDLE_SLEEP); 2553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (m_dstBuf->isCanceled()) 2573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry break; 2583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 2593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry continue; 2603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 2613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else if (err != ERROR_IO_PENDING) 2623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry throw Error(err, "ReadFile() failed"); 2633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 2643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry waitRes = WaitForMultipleObjects(DE_LENGTH_OF_ARRAY(waitHandles), &waitHandles[0], FALSE, INFINITE); 2663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (waitRes == WAIT_OBJECT_0) 2683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 2693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // \note GetOverlappedResult() will fail with ERROR_IO_INCOMPLETE if IO event is not complete (should be). 2703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (!GetOverlappedResult(m_handle, &overlapped, &numBytesRead, FALSE)) 2713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 2723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DWORD err = GetLastError(); 2733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (err == ERROR_HANDLE_EOF) 2753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 2763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // End of file - for now. 2773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // \note Should check for end of buffer here, or otherwise may end up in infinite loop. 2783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (m_dstBuf->isCanceled()) 2793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry break; 2803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry deSleep(FILEREADER_IDLE_SLEEP); 2823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (m_dstBuf->isCanceled()) 2843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry break; 2853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 2863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry continue; 2873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 2883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else if (err == ERROR_BROKEN_PIPE) 2893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry break; 2903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 2913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry throw Error(err, "GetOverlappedResult() failed"); 2923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 2933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (numBytesRead == 0) 2953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry throw Error(GetLastError(), "Reading from file failed"); 2963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 2973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry offset += (deUint64)numBytesRead; 2983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 2993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else if (waitRes == WAIT_OBJECT_0 + 1) 3003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 3013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Cancel. 3023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (!CancelIo(m_handle)) 3033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry throw Error(GetLastError(), "CancelIo() failed"); 3043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry break; 3053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 3063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 3073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry throw Error(GetLastError(), "WaitForMultipleObjects() failed"); 3083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry try 3103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 3113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_dstBuf->write((int)numBytesRead, &tmpBuf[0]); 3123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_dstBuf->flush(); 3133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 3143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry catch (const ThreadedByteBuffer::CanceledException&) 3153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 3163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Canceled. 3173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry break; 3183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 3193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 3203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 3213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry catch (const std::exception& e) 3223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 3233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // \todo [2013-08-13 pyry] What to do? 3243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry printf("win32::FileReader::run(): %s\n", e.what()); 3253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 3263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 3273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3283c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid FileReader::stop (void) 3293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 3303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (!isStarted()) 3313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return; // Nothing to do. 3323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_cancelEvent.setSignaled(); 3343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Join thread. 3363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry join(); 3373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_cancelEvent.reset(); 3393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_handle = INVALID_HANDLE_VALUE; 3413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 3423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// TestLogReader 3443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3453c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTestLogReader::TestLogReader (void) 3463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry : m_logBuffer (LOG_BUFFER_BLOCK_SIZE, LOG_BUFFER_NUM_BLOCKS) 3473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , m_logFile (INVALID_HANDLE_VALUE) 3483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , m_reader (&m_logBuffer) 3493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 3503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 3513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3523c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTestLogReader::~TestLogReader (void) 3533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 3543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (m_logFile != INVALID_HANDLE_VALUE) 3553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry CloseHandle(m_logFile); 3563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 3573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3583c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid TestLogReader::start (const char* filename) 3593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 3603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(m_logFile == INVALID_HANDLE_VALUE && !m_reader.isStarted()); 3613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_logFile = CreateFile(filename, 3633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry GENERIC_READ, 3643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry FILE_SHARE_DELETE|FILE_SHARE_READ|FILE_SHARE_WRITE, 3653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_NULL, 3663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry OPEN_EXISTING, 3673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry FILE_ATTRIBUTE_NORMAL|FILE_FLAG_OVERLAPPED, 3683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_NULL); 3693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (m_logFile == INVALID_HANDLE_VALUE) 3713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry throw Error(GetLastError(), "Failed to open log file"); 3723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_reader.start(m_logFile); 3743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 3753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3763c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid TestLogReader::stop (void) 3773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 3783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (!m_reader.isStarted()) 3793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return; // Nothing to do. 3803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_logBuffer.cancel(); 3823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_reader.stop(); 3833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry CloseHandle(m_logFile); 3853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_logFile = INVALID_HANDLE_VALUE; 3863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_logBuffer.clear(); 3883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 3893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// Process 3913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3923c827367444ee418f129b2c238299f49d3264554Jarkko PoyryProcess::Process (void) 3933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry : m_state (STATE_NOT_STARTED) 3943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , m_exitCode (0) 3953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , m_standardIn (INVALID_HANDLE_VALUE) 3963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , m_standardOut (INVALID_HANDLE_VALUE) 3973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , m_standardErr (INVALID_HANDLE_VALUE) 3983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 3993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry deMemset(&m_procInfo, 0, sizeof(m_procInfo)); 4003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 4013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4023c827367444ee418f129b2c238299f49d3264554Jarkko PoyryProcess::~Process (void) 4033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 4043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry try 4053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 4063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (isRunning()) 4073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 4083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry kill(); 4093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry waitForFinish(); 4103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 4113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 4123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry catch (...) 4133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 4143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 4153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry cleanupHandles(); 4173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 4183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4193c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid Process::cleanupHandles (void) 4203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 4213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(!isRunning()); 4223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (m_standardErr != INVALID_HANDLE_VALUE) 4243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry CloseHandle(m_standardErr); 4253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (m_standardOut != INVALID_HANDLE_VALUE) 4273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry CloseHandle(m_standardOut); 4283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (m_standardIn != INVALID_HANDLE_VALUE) 4303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry CloseHandle(m_standardIn); 4313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (m_procInfo.hProcess) 4333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry CloseHandle(m_procInfo.hProcess); 4343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (m_procInfo.hThread) 4363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry CloseHandle(m_procInfo.hThread); 4373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_standardErr = INVALID_HANDLE_VALUE; 4393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_standardOut = INVALID_HANDLE_VALUE; 4403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_standardIn = INVALID_HANDLE_VALUE; 4413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry deMemset(&m_procInfo, 0, sizeof(m_procInfo)); 4433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 4443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry__declspec(thread) static int t_pipeNdx = 0; 4463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4473c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic void createPipeWithOverlappedIO (HANDLE* readHandleOut, HANDLE* writeHandleOut, deUint32 readMode, deUint32 writeMode, SECURITY_ATTRIBUTES* securityAttr) 4483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 4493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int defaultBufSize = 4096; 4503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry char pipeName[128]; 4513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry HANDLE readHandle; 4523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry HANDLE writeHandle; 4533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(((readMode | writeMode) & ~FILE_FLAG_OVERLAPPED) == 0); 4553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry deSprintf(pipeName, sizeof(pipeName), "\\\\.\\Pipe\\dEQP-ExecServer-%08x-%08x-%08x", 4573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry GetCurrentProcessId(), 4583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry GetCurrentThreadId(), 4593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry t_pipeNdx++); 4603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry readHandle = CreateNamedPipe(pipeName, /* Pipe name. */ 4623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry PIPE_ACCESS_INBOUND|readMode, /* Open mode. */ 4633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry PIPE_TYPE_BYTE|PIPE_WAIT, /* Pipe flags. */ 4643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1, /* Max number of instances. */ 4653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry defaultBufSize, /* Output buffer size. */ 4663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry defaultBufSize, /* Input buffer size. */ 4673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 0, /* Use default timeout. */ 4683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry securityAttr); 4693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (readHandle == INVALID_HANDLE_VALUE) 4713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry throw Error(GetLastError(), "CreateNamedPipe() failed"); 4723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry writeHandle = CreateFile(pipeName, 4743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry GENERIC_WRITE, /* Access mode. */ 4753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 0, /* No sharing. */ 4763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry securityAttr, 4773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry OPEN_EXISTING, /* Assume existing object. */ 4783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry FILE_ATTRIBUTE_NORMAL|writeMode, /* Open mode / flags. */ 4793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_NULL /* Template file. */); 4803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (writeHandle == INVALID_HANDLE_VALUE) 4823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 4833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DWORD openErr = GetLastError(); 4843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry CloseHandle(readHandle); 4853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry throw Error(openErr, "Failed to open created pipe, CreateFile() failed"); 4863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 4873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *readHandleOut = readHandle; 4893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *writeHandleOut = writeHandle; 4903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 4913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4923c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid Process::start (const char* commandLine, const char* workingDirectory) 4933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 4943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Pipes. 4953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry HANDLE stdInRead = INVALID_HANDLE_VALUE; 4963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry HANDLE stdInWrite = INVALID_HANDLE_VALUE; 4973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry HANDLE stdOutRead = INVALID_HANDLE_VALUE; 4983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry HANDLE stdOutWrite = INVALID_HANDLE_VALUE; 4993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry HANDLE stdErrRead = INVALID_HANDLE_VALUE; 5003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry HANDLE stdErrWrite = INVALID_HANDLE_VALUE; 5013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (m_state == STATE_RUNNING) 5033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry throw std::runtime_error("Process already running"); 5043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else if (m_state == STATE_FINISHED) 5053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 5063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Process finished, clean up old cruft. 5073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry cleanupHandles(); 5083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_state = STATE_NOT_STARTED; 5093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 5103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Create pipes 5123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry try 5133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 5143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry SECURITY_ATTRIBUTES securityAttr; 5153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry STARTUPINFO startInfo; 5163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry deMemset(&startInfo, 0, sizeof(startInfo)); 5183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry deMemset(&securityAttr, 0, sizeof(securityAttr)); 5193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Security attributes for inheriting handle. 5213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry securityAttr.nLength = sizeof(SECURITY_ATTRIBUTES); 5223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry securityAttr.bInheritHandle = TRUE; 5233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry securityAttr.lpSecurityDescriptor = DE_NULL; 5243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry createPipeWithOverlappedIO(&stdInRead, &stdInWrite, 0, FILE_FLAG_OVERLAPPED, &securityAttr); 5263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry createPipeWithOverlappedIO(&stdOutRead, &stdOutWrite, FILE_FLAG_OVERLAPPED, 0, &securityAttr); 5273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry createPipeWithOverlappedIO(&stdErrRead, &stdErrWrite, FILE_FLAG_OVERLAPPED, 0, &securityAttr); 5283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (!SetHandleInformation(stdInWrite, HANDLE_FLAG_INHERIT, 0) || 5303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry !SetHandleInformation(stdOutRead, HANDLE_FLAG_INHERIT, 0) || 5313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry !SetHandleInformation(stdErrRead, HANDLE_FLAG_INHERIT, 0)) 5323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry throw Error(GetLastError(), "SetHandleInformation() failed"); 5333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Startup info for process. 5353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry startInfo.cb = sizeof(startInfo); 5363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry startInfo.hStdError = stdErrWrite; 5373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry startInfo.hStdOutput = stdOutWrite; 5383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry startInfo.hStdInput = stdInRead; 5393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry startInfo.dwFlags |= STARTF_USESTDHANDLES; 5403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (!CreateProcess(DE_NULL, (LPTSTR)commandLine, DE_NULL, DE_NULL, TRUE /* inherit handles */, 0, DE_NULL, workingDirectory, &startInfo, &m_procInfo)) 5423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry throw Error(GetLastError(), "CreateProcess() failed"); 5433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 5443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry catch (...) 5453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 5463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (stdInRead != INVALID_HANDLE_VALUE) CloseHandle(stdInRead); 5473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (stdInWrite != INVALID_HANDLE_VALUE) CloseHandle(stdInWrite); 5483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (stdOutRead != INVALID_HANDLE_VALUE) CloseHandle(stdOutRead); 5493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (stdOutWrite != INVALID_HANDLE_VALUE) CloseHandle(stdOutWrite); 5503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (stdErrRead != INVALID_HANDLE_VALUE) CloseHandle(stdErrRead); 5513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (stdErrWrite != INVALID_HANDLE_VALUE) CloseHandle(stdErrWrite); 5523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry throw; 5533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 5543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Store handles to be kept. 5563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_standardIn = stdInWrite; 5573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_standardOut = stdOutRead; 5583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_standardErr = stdErrRead; 5593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Close other ends of handles. 5613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry CloseHandle(stdErrWrite); 5623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry CloseHandle(stdOutWrite); 5633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry CloseHandle(stdInRead); 5643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_state = STATE_RUNNING; 5663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 5673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5683c827367444ee418f129b2c238299f49d3264554Jarkko Poyrybool Process::isRunning (void) 5693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 5703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (m_state == STATE_RUNNING) 5713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 5723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int exitCode; 5733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry BOOL result = GetExitCodeProcess(m_procInfo.hProcess, (LPDWORD)&exitCode); 5743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (result != TRUE) 5763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry throw Error(GetLastError(), "GetExitCodeProcess() failed"); 5773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (exitCode == STILL_ACTIVE) 5793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return true; 5803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 5813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 5823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Done. 5833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_exitCode = exitCode; 5843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_state = STATE_FINISHED; 5853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return false; 5863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 5873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 5883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 5893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return false; 5903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 5913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5923c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid Process::waitForFinish (void) 5933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 5943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (m_state == STATE_RUNNING) 5953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 5963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (WaitForSingleObject(m_procInfo.hProcess, INFINITE) != WAIT_OBJECT_0) 5973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry throw Error(GetLastError(), "Waiting for process failed, WaitForSingleObject() failed"); 5983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (isRunning()) 6003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry throw std::runtime_error("Process is still alive"); 6013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 6023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 6033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry throw std::runtime_error("Process is not running"); 6043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 6053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 6063c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid Process::stopProcess (bool kill) 6073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 6083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (m_state == STATE_RUNNING) 6093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 6103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (!TerminateProcess(m_procInfo.hProcess, kill ? -1 : 0)) 6113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry throw Error(GetLastError(), "TerminateProcess() failed"); 6123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 6133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 6143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry throw std::runtime_error("Process is not running"); 6153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 6163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 6173c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid Process::terminate (void) 6183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 6193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry stopProcess(false); 6203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 6213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 6223c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid Process::kill (void) 6233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 6243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry stopProcess(true); 6253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 6263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 6273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} // win32 6283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 6293c827367444ee418f129b2c238299f49d3264554Jarkko PoyryWin32TestProcess::Win32TestProcess (void) 6303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry : m_process (DE_NULL) 6313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , m_processStartTime (0) 6323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , m_infoBuffer (INFO_BUFFER_BLOCK_SIZE, INFO_BUFFER_NUM_BLOCKS) 6333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , m_stdOutReader (&m_infoBuffer) 6343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , m_stdErrReader (&m_infoBuffer) 6353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 6363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 6373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 6383c827367444ee418f129b2c238299f49d3264554Jarkko PoyryWin32TestProcess::~Win32TestProcess (void) 6393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 6403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry delete m_process; 6413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 6423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 6433c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid Win32TestProcess::start (const char* name, const char* params, const char* workingDir, const char* caseList) 6443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 6453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry bool hasCaseList = strlen(caseList) > 0; 6463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 6473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry XS_CHECK(!m_process); 6483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 6493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry de::FilePath logFilePath = de::FilePath::join(workingDir, "TestResults.qpa"); 6503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_logFileName = logFilePath.getPath(); 6513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 6523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Remove old file if such exists. 6533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // \note Sometimes on Windows the test process dies slowly and may not release handle to log file 6543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // until a bit later. 6553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // \todo [2013-07-15 pyry] This should be solved by improving deProcess and killing all child processes as well. 6563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 6573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int tryNdx = 0; 6583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry while (tryNdx < MAX_OLD_LOGFILE_DELETE_ATTEMPTS && deFileExists(m_logFileName.c_str())) 6593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 6603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (deDeleteFile(m_logFileName.c_str())) 6613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry break; 6623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry deSleep(LOGFILE_DELETE_SLEEP_MS); 6633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry tryNdx += 1; 6643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 6653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 6663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (deFileExists(m_logFileName.c_str())) 6673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry throw TestProcessException(string("Failed to remove '") + m_logFileName + "'"); 6683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 6693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 6703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Construct command line. 6713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry string cmdLine = de::FilePath(name).isAbsolutePath() ? name : de::FilePath::join(workingDir, name).normalize().getPath(); 6723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry cmdLine += string(" --deqp-log-filename=") + logFilePath.getBaseName(); 6733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 6743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (hasCaseList) 6753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry cmdLine += " --deqp-stdin-caselist"; 6763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 6773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (strlen(params) > 0) 6783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry cmdLine += string(" ") + params; 6793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 6803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(!m_process); 6813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_process = new win32::Process(); 6823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 6833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry try 6843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 6853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_process->start(cmdLine.c_str(), strlen(workingDir) > 0 ? workingDir : DE_NULL); 6863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 6873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry catch (const std::exception& e) 6883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 6893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry delete m_process; 6903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_process = DE_NULL; 6913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry throw TestProcessException(e.what()); 6923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 6933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 6943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_processStartTime = deGetMicroseconds(); 6953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 6963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Create stdout & stderr readers. 6973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_stdOutReader.start(m_process->getStdOut()); 6983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_stdErrReader.start(m_process->getStdErr()); 6993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 7003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Start case list writer. 7013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (hasCaseList) 7023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_caseListWriter.start(caseList, m_process->getStdIn()); 7033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 7043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 7053c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid Win32TestProcess::terminate (void) 7063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 7073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (m_process) 7083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 7093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry try 7103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 7113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_process->kill(); 7123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 7133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry catch (const std::exception& e) 7143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 7153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry printf("Win32TestProcess::terminate(): Failed to kill process: %s\n", e.what()); 7163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 7173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 7183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 7193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 7203c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid Win32TestProcess::cleanup (void) 7213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 7223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_caseListWriter.stop(); 7233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 7243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // \note Buffers must be canceled before stopping readers. 7253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_infoBuffer.cancel(); 7263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 7273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_stdErrReader.stop(); 7283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_stdOutReader.stop(); 7293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testLogReader.stop(); 7303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 7313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Reset buffers. 7323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_infoBuffer.clear(); 7333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 7343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (m_process) 7353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 7363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry try 7373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 7383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (m_process->isRunning()) 7393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 7403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_process->kill(); 7413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_process->waitForFinish(); 7423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 7433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 7443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry catch (const std::exception& e) 7453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 7463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry printf("Win32TestProcess::cleanup(): Failed to kill process: %s\n", e.what()); 7473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 7483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 7493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry delete m_process; 7503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_process = DE_NULL; 7513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 7523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 7533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 7543c827367444ee418f129b2c238299f49d3264554Jarkko Poyryint Win32TestProcess::readTestLog (deUint8* dst, int numBytes) 7553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 7563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (!m_testLogReader.isRunning()) 7573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 7583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (deGetMicroseconds() - m_processStartTime > LOG_FILE_TIMEOUT*1000) 7593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 7603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Timeout, kill process. 7613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry terminate(); 7623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return 0; // \todo [2013-08-13 pyry] Throw exception? 7633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 7643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 7653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (!deFileExists(m_logFileName.c_str())) 7663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return 0; 7673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 7683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Start reader. 7693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testLogReader.start(m_logFileName.c_str()); 7703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 7713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 7723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(m_testLogReader.isRunning()); 7733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return m_testLogReader.read(dst, numBytes); 7743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 7753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 7763c827367444ee418f129b2c238299f49d3264554Jarkko Poyrybool Win32TestProcess::isRunning (void) 7773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 7783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (m_process) 7793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return m_process->isRunning(); 7803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 7813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return false; 7823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 7833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 7843c827367444ee418f129b2c238299f49d3264554Jarkko Poyryint Win32TestProcess::getExitCode (void) const 7853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 7863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (m_process) 7873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return m_process->getExitCode(); 7883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 7893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return -1; 7903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 7913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 7923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} // xs 793