@@ -86,14 +86,24 @@ public final class JobExecutor {
86
86
/// Queue for executor delegate.
87
87
let delegateQueue : DispatchQueue = DispatchQueue ( label: " org.swift.driver.job-executor-delegate " )
88
88
89
+ /// Operation queue for executing tasks in parallel.
90
+ let jobQueue : OperationQueue
91
+
92
+ /// The process set to use when launching new processes.
93
+ let processSet : ProcessSet ?
94
+
89
95
init (
90
96
argsResolver: ArgsResolver ,
91
97
producerMap: [ VirtualPath : Job ] ,
92
- executorDelegate: JobExecutorDelegate
98
+ executorDelegate: JobExecutorDelegate ,
99
+ jobQueue: OperationQueue ,
100
+ processSet: ProcessSet ?
93
101
) {
94
102
self . producerMap = producerMap
95
103
self . argsResolver = argsResolver
96
104
self . executorDelegate = executorDelegate
105
+ self . jobQueue = jobQueue
106
+ self . processSet = processSet
97
107
}
98
108
}
99
109
@@ -106,14 +116,24 @@ public final class JobExecutor {
106
116
/// The job executor delegate.
107
117
let executorDelegate : JobExecutorDelegate
108
118
119
+ /// The number of jobs to run in parallel.
120
+ let numParallelJobs : Int
121
+
122
+ /// The process set to use when launching new processes.
123
+ let processSet : ProcessSet ?
124
+
109
125
public init (
110
126
jobs: [ Job ] ,
111
127
resolver: ArgsResolver ,
112
- executorDelegate: JobExecutorDelegate
128
+ executorDelegate: JobExecutorDelegate ,
129
+ numParallelJobs: Int ? = nil ,
130
+ processSet: ProcessSet ? = nil
113
131
) {
114
132
self . jobs = jobs
115
133
self . argsResolver = resolver
116
134
self . executorDelegate = executorDelegate
135
+ self . numParallelJobs = numParallelJobs ?? 1
136
+ self . processSet = processSet
117
137
}
118
138
119
139
/// Execute all jobs.
@@ -141,10 +161,16 @@ public final class JobExecutor {
141
161
}
142
162
}
143
163
164
+ let jobQueue = OperationQueue ( )
165
+ jobQueue. name = " org.swift.driver.job-execution "
166
+ jobQueue. maxConcurrentOperationCount = numParallelJobs
167
+
144
168
return Context (
145
169
argsResolver: argsResolver,
146
170
producerMap: producerMap,
147
- executorDelegate: executorDelegate
171
+ executorDelegate: executorDelegate,
172
+ jobQueue: jobQueue,
173
+ processSet: processSet
148
174
)
149
175
}
150
176
}
@@ -281,6 +307,13 @@ class ExecuteJobRule: LLBuildRule {
281
307
return engine. taskIsComplete ( DriverBuildValue . jobExecution ( success: false ) )
282
308
}
283
309
310
+ let context = engine. jobExecutorContext
311
+ context. jobQueue. addOperation {
312
+ self . executeJob ( engine)
313
+ }
314
+ }
315
+
316
+ private func executeJob( _ engine: LLTaskBuildEngine ) {
284
317
let context = engine. jobExecutorContext
285
318
let resolver = context. argsResolver
286
319
let job = key. job
@@ -295,6 +328,11 @@ class ExecuteJobRule: LLBuildRule {
295
328
let process = try context. executorDelegate. launchProcess ( for: job, arguments: arguments)
296
329
pid = Int ( process. processID)
297
330
331
+ // Add it to the process set if it's a real process.
332
+ if case let realProcess as TSCBasic . Process = process {
333
+ try context. processSet? . add ( realProcess)
334
+ }
335
+
298
336
// Inform the delegate.
299
337
context. delegateQueue. async {
300
338
context. executorDelegate. jobStarted ( job: job, arguments: arguments, pid: pid)
0 commit comments