xref: /aosp_15_r20/external/deqp/execserver/xsWin32TestProcess.hpp (revision 35238bce31c2a825756842865a792f8cf7f89930)
1 #ifndef _XSWIN32TESTPROCESS_HPP
2 #define _XSWIN32TESTPROCESS_HPP
3 /*-------------------------------------------------------------------------
4  * drawElements Quality Program Execution Server
5  * ---------------------------------------------
6  *
7  * Copyright 2014 The Android Open Source Project
8  *
9  * Licensed under the Apache License, Version 2.0 (the "License");
10  * you may not use this file except in compliance with the License.
11  * You may obtain a copy of the License at
12  *
13  *      http://www.apache.org/licenses/LICENSE-2.0
14  *
15  * Unless required by applicable law or agreed to in writing, software
16  * distributed under the License is distributed on an "AS IS" BASIS,
17  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18  * See the License for the specific language governing permissions and
19  * limitations under the License.
20  *
21  *//*!
22  * \file
23  * \brief TestProcess implementation for Win32.
24  *//*--------------------------------------------------------------------*/
25 
26 #include "xsDefs.hpp"
27 #include "xsTestProcess.hpp"
28 #include "deThread.hpp"
29 
30 #include <vector>
31 #include <string>
32 
33 #if !defined(VC_EXTRALEAN)
34 #define VC_EXTRALEAN 1
35 #endif
36 #if !defined(WIN32_LEAN_AND_MEAN)
37 #define WIN32_LEAN_AND_MEAN 1
38 #endif
39 #if !defined(NOMINMAX)
40 #define NOMINMAX 1
41 #endif
42 #include <windows.h>
43 
44 namespace xs
45 {
46 namespace win32
47 {
48 
49 class Error : public std::runtime_error
50 {
51 public:
52     Error(DWORD error, const char *msg);
53 
54 private:
55     DWORD m_error;
56 };
57 
58 class Event
59 {
60 public:
61     Event(bool manualReset, bool initialState);
62     ~Event(void);
63 
64     void setSignaled(void);
65     void reset(void);
66 
getHandle(void) const67     HANDLE getHandle(void) const
68     {
69         return m_handle;
70     }
71 
72 private:
73     Event(const Event &other);
74     Event &operator=(const Event &other);
75 
76     HANDLE m_handle;
77 };
78 
79 class CaseListWriter : public de::Thread
80 {
81 public:
82     CaseListWriter(void);
83     ~CaseListWriter(void);
84 
85     void start(const char *caseList, HANDLE dst);
86     void stop(void);
87 
88     void run(void);
89 
90 private:
91     std::vector<char> m_caseList;
92     HANDLE m_dst;
93     Event m_cancelEvent;
94 };
95 
96 class FileReader : public de::Thread
97 {
98 public:
99     FileReader(ThreadedByteBuffer *dst);
100     ~FileReader(void);
101 
102     void start(HANDLE file);
103     void stop(void);
104 
105     void run(void);
106 
107 private:
108     ThreadedByteBuffer *m_dstBuf;
109     HANDLE m_handle;
110     Event m_cancelEvent;
111 };
112 
113 class TestLogReader
114 {
115 public:
116     TestLogReader(void);
117     ~TestLogReader(void);
118 
119     void start(const char *filename);
120     void stop(void);
121 
isRunning(void) const122     bool isRunning(void) const
123     {
124         return m_reader.isStarted();
125     }
126 
read(uint8_t * dst,int numBytes)127     int read(uint8_t *dst, int numBytes)
128     {
129         return m_logBuffer.tryRead(numBytes, dst);
130     }
131 
132 private:
133     ThreadedByteBuffer m_logBuffer;
134     HANDLE m_logFile;
135 
136     FileReader m_reader;
137 };
138 
139 // \note deProcess uses anonymous pipes that don't have overlapped IO available.
140 //         For ExecServer purposes we need overlapped IO, and it makes the handles
141 //         incompatible with deFile. Thus separate Process implementation is used for now.
142 class Process
143 {
144 public:
145     Process(void);
146     ~Process(void);
147 
148     void start(const char *commandLine, const char *workingDirectory);
149 
150     void waitForFinish(void);
151     void terminate(void);
152     void kill(void);
153 
154     bool isRunning(void);
getExitCode(void) const155     int getExitCode(void) const
156     {
157         return m_exitCode;
158     }
159 
getStdIn(void) const160     HANDLE getStdIn(void) const
161     {
162         return m_standardIn;
163     }
getStdOut(void) const164     HANDLE getStdOut(void) const
165     {
166         return m_standardOut;
167     }
getStdErr(void) const168     HANDLE getStdErr(void) const
169     {
170         return m_standardErr;
171     }
172 
173 private:
174     Process(const Process &other);
175     Process &operator=(const Process &other);
176 
177     void stopProcess(bool kill);
178     void cleanupHandles(void);
179 
180     enum State
181     {
182         STATE_NOT_STARTED = 0,
183         STATE_RUNNING,
184         STATE_FINISHED,
185 
186         STATE_LAST
187     };
188 
189     State m_state;
190     int m_exitCode;
191 
192     PROCESS_INFORMATION m_procInfo;
193     HANDLE m_standardIn;
194     HANDLE m_standardOut;
195     HANDLE m_standardErr;
196 };
197 
198 } // namespace win32
199 
200 class Win32TestProcess : public TestProcess
201 {
202 public:
203     Win32TestProcess(void);
204     virtual ~Win32TestProcess(void);
205 
206     virtual void start(const char *name, const char *params, const char *workingDir, const char *caseList);
207     virtual void terminate(void);
208     virtual void cleanup(void);
209 
210     virtual bool isRunning(void);
211     virtual int getExitCode(void) const;
212 
213     virtual int readTestLog(uint8_t *dst, int numBytes);
readInfoLog(uint8_t * dst,int numBytes)214     virtual int readInfoLog(uint8_t *dst, int numBytes)
215     {
216         return m_infoBuffer.tryRead(numBytes, dst);
217     }
218 
219 private:
220     Win32TestProcess(const Win32TestProcess &other);
221     Win32TestProcess &operator=(const Win32TestProcess &other);
222 
223     win32::Process *m_process;
224     uint64_t m_processStartTime;
225     std::string m_logFileName;
226 
227     ThreadedByteBuffer m_infoBuffer;
228 
229     // Threads.
230     win32::CaseListWriter m_caseListWriter;
231     win32::FileReader m_stdOutReader;
232     win32::FileReader m_stdErrReader;
233     win32::TestLogReader m_testLogReader;
234 };
235 
236 } // namespace xs
237 
238 #endif // _XSWIN32TESTPROCESS_HPP
239