21
21
// ===----------------------------------------------------------------------===//
22
22
23
23
#include " swift/Basic/TaskQueue.h"
24
-
25
24
#include " swift/Basic/LLVM.h"
26
-
27
25
#include " llvm/ADT/StringExtras.h"
28
26
#include " llvm/Support/FileSystem.h"
29
27
#include " llvm/Support/MemoryBuffer.h"
35
33
#include < psapi.h>
36
34
#endif
37
35
38
- using namespace llvm ::sys;
39
-
40
- namespace swift {
41
- namespace sys {
42
-
43
- class Task {
44
- public:
45
- // / The path to the executable which this Task will execute.
46
- const char *ExecPath;
47
-
48
- // / Any arguments which should be passed during execution.
49
- ArrayRef<const char *> Args;
50
-
51
- // / The environment which should be used during execution. If empty,
52
- // / the current process's environment will be used instead.
53
- ArrayRef<const char *> Env;
54
-
55
- // / True if the errors of the Task should be stored in Errors instead of Output.
56
- bool SeparateErrors;
57
-
58
- // / Context associated with this Task.
59
- void *Context;
60
-
61
- Task (const char *ExecPath, ArrayRef<const char *> Args,
62
- ArrayRef<const char *> Env = llvm::None, void *Context = nullptr , bool SeparateErrors = false )
63
- : ExecPath(ExecPath), Args(Args), Env(Env), Context(Context), SeparateErrors(SeparateErrors) {}
64
- };
36
+ #include " Task.inc"
65
37
66
- } // end namespace sys
67
- } // end namespace swift
38
+ using namespace llvm ::sys;
68
39
69
40
bool TaskQueue::supportsBufferingOutput () {
70
41
// The default implementation supports buffering output.
@@ -84,7 +55,7 @@ unsigned TaskQueue::getNumberOfParallelTasks() const {
84
55
void TaskQueue::addTask (const char *ExecPath, ArrayRef<const char *> Args,
85
56
ArrayRef<const char *> Env, void *Context,
86
57
bool SeparateErrors) {
87
- std::unique_ptr<Task> T ( new Task (ExecPath, Args, Env, Context, SeparateErrors) );
58
+ auto T = make_unique< Task> (ExecPath, Args, Env, Context, SeparateErrors);
88
59
QueuedTasks.push (std::move (T));
89
60
}
90
61
@@ -99,54 +70,27 @@ bool TaskQueue::execute(TaskBeganCallback Began, TaskFinishedCallback Finished,
99
70
while (!QueuedTasks.empty () && ContinueExecution) {
100
71
std::unique_ptr<Task> T (QueuedTasks.front ().release ());
101
72
QueuedTasks.pop ();
73
+ bool ExecutionFailed = T->execute ();
102
74
103
- SmallVector<const char *, 128 > Argv;
104
- Argv.push_back (T->ExecPath );
105
- Argv.append (T->Args .begin (), T->Args .end ());
106
- Argv.push_back (nullptr );
107
-
108
- llvm::Optional<llvm::ArrayRef<llvm::StringRef>> Envp =
109
- T->Env .empty () ? decltype (Envp)(None)
110
- : decltype (Envp)(llvm::toStringRefArray (T->Env .data ()));
111
-
112
- llvm::SmallString<64 > stdoutPath;
113
- if (fs::createTemporaryFile (" stdout" , " tmp" , stdoutPath))
114
- return true ;
115
- llvm::sys::RemoveFileOnSignal (stdoutPath);
116
-
117
- llvm::SmallString<64 > stderrPath;
118
- if (T->SeparateErrors ) {
119
- if (fs::createTemporaryFile (" stderr" , " tmp" , stdoutPath))
120
- return true ;
121
- llvm::sys::RemoveFileOnSignal (stderrPath);
122
- }
123
-
124
- Optional<StringRef> redirects[] = {None, {stdoutPath}, {T->SeparateErrors ? stderrPath : stdoutPath}};
125
-
126
- bool ExecutionFailed = false ;
127
- ProcessInfo PI = ExecuteNoWait (T->ExecPath ,
128
- llvm::toStringRefArray (Argv.data ()), Envp,
129
- /* redirects*/ redirects, /* memoryLimit*/ 0 ,
130
- /* ErrMsg*/ nullptr , &ExecutionFailed);
131
75
if (ExecutionFailed) {
132
76
return true ;
133
77
}
134
78
135
79
if (Began) {
136
- Began (PI.Pid , T->Context );
80
+ Began (T-> PI .Pid , T->Context );
137
81
}
138
82
139
83
std::string ErrMsg;
140
- PI = Wait (PI, 0 , true , &ErrMsg);
141
- int ReturnCode = PI.ReturnCode ;
84
+ T-> PI = Wait (T-> PI , 0 , true , &ErrMsg);
85
+ int ReturnCode = T-> PI .ReturnCode ;
142
86
143
- auto stdoutBuffer = llvm::MemoryBuffer::getFile (stdoutPath );
144
- StringRef stdoutContents = stdoutBuffer .get ()->getBuffer ();
87
+ auto StdoutBuffer = llvm::MemoryBuffer::getFile (T-> StdoutPath );
88
+ StringRef StdoutContents = StdoutBuffer .get ()->getBuffer ();
145
89
146
- StringRef stderrContents ;
90
+ StringRef StderrContents ;
147
91
if (T->SeparateErrors ) {
148
- auto stderrBuffer = llvm::MemoryBuffer::getFile (stderrPath );
149
- stderrContents = stderrBuffer .get ()->getBuffer ();
92
+ auto StderrBuffer = llvm::MemoryBuffer::getFile (T-> StderrPath );
93
+ StderrContents = StderrBuffer .get ()->getBuffer ();
150
94
}
151
95
152
96
#if defined(_WIN32)
@@ -155,36 +99,37 @@ bool TaskQueue::execute(TaskBeganCallback Began, TaskFinishedCallback Finished,
155
99
//
156
100
// This isn't a true signal on Windows, but we'll treat it as such so that
157
101
// we clean up after it properly
158
- bool crashed = ReturnCode & 0xC0000000 ;
159
-
160
- FILETIME creationTime ;
161
- FILETIME exitTime ;
162
- FILETIME utimeTicks ;
163
- FILETIME stimeTicks ;
164
- PROCESS_MEMORY_COUNTERS counters = {};
165
- GetProcessTimes (PI.Process , &creationTime , &exitTime , &stimeTicks ,
166
- &utimeTicks );
102
+ bool Crashed = ReturnCode & 0xC0000000 ;
103
+
104
+ FILETIME CreationTime ;
105
+ FILETIME ExitTime ;
106
+ FILETIME UtimeTicks ;
107
+ FILETIME StimeTicks ;
108
+ PROCESS_MEMORY_COUNTERS Counters = {};
109
+ GetProcessTimes (T-> PI .Process , &CreationTime , &ExitTime , &StimeTicks ,
110
+ &UtimeTicks );
167
111
// Each tick is 100ns
168
- uint64_t utime =
169
- ((uint64_t )utimeTicks .dwHighDateTime << 32 | utimeTicks .dwLowDateTime ) /
112
+ uint64_t Utime =
113
+ ((uint64_t )UtimeTicks .dwHighDateTime << 32 | UtimeTicks .dwLowDateTime ) /
170
114
10 ;
171
- uint64_t stime =
172
- ((uint64_t )stimeTicks .dwHighDateTime << 32 | stimeTicks .dwLowDateTime ) /
115
+ uint64_t Stime =
116
+ ((uint64_t )StimeTicks .dwHighDateTime << 32 | StimeTicks .dwLowDateTime ) /
173
117
10 ;
174
- GetProcessMemoryInfo (PI.Process , &counters , sizeof (counters ));
118
+ GetProcessMemoryInfo (T-> PI .Process , &Counters , sizeof (Counters ));
175
119
176
- TaskProcessInformation tpi ( PI.Pid , utime, stime ,
177
- counters .PeakWorkingSetSize );
120
+ TaskProcessInformation TPI (T-> PI .Pid , Utime, Stime ,
121
+ Counters .PeakWorkingSetSize );
178
122
#else
179
- // Wait() returning a return code of -2 indicates the process received
180
- // a signal during execution.
181
- bool crashed = ReturnCode == -2 ;
182
- TaskProcessInformation tpi ( PI.Pid );
123
+ // Wait() returning a return code of -2 indicates the process received
124
+ // a signal during execution.
125
+ bool Crashed = ReturnCode == -2 ;
126
+ TaskProcessInformation TPI (T-> PI .Pid );
183
127
#endif
184
- if (crashed ) {
128
+ if (Crashed ) {
185
129
if (Signalled) {
186
130
TaskFinishedResponse Response =
187
- Signalled (PI.Pid , ErrMsg, stdoutContents, stderrContents, T->Context , ReturnCode, tpi);
131
+ Signalled (T->PI .Pid , ErrMsg, StdoutContents, StderrContents,
132
+ T->Context , ReturnCode, TPI);
188
133
ContinueExecution = Response != TaskFinishedResponse::StopExecution;
189
134
} else {
190
135
// If we don't have a Signalled callback, unconditionally stop.
@@ -194,16 +139,17 @@ bool TaskQueue::execute(TaskBeganCallback Began, TaskFinishedCallback Finished,
194
139
// Wait() returned a normal return code, so just indicate that the task
195
140
// finished.
196
141
if (Finished) {
197
- TaskFinishedResponse Response = Finished (PI.Pid , PI.ReturnCode ,
198
- stdoutContents, stderrContents, tpi, T->Context );
142
+ TaskFinishedResponse Response =
143
+ Finished (T->PI .Pid , T->PI .ReturnCode , StdoutContents,
144
+ StderrContents, TPI, T->Context );
199
145
ContinueExecution = Response != TaskFinishedResponse::StopExecution;
200
- } else if (PI.ReturnCode != 0 ) {
146
+ } else if (T-> PI .ReturnCode != 0 ) {
201
147
ContinueExecution = false ;
202
148
}
203
149
}
204
- llvm::sys::fs::remove (stdoutPath );
150
+ llvm::sys::fs::remove (T-> StdoutPath );
205
151
if (T->SeparateErrors )
206
- llvm::sys::fs::remove (stderrPath );
152
+ llvm::sys::fs::remove (T-> StderrPath );
207
153
}
208
154
209
155
return !ContinueExecution;
0 commit comments