@@ -110,17 +110,21 @@ defmodule Kernel.ParallelCompiler do
110
110
:erlang . put ( :elixir_compiler_file , file )
111
111
:erlang . process_flag ( :error_handler , Kernel.ErrorHandler )
112
112
113
- exit ( try do
114
- _ = if output do
115
- :elixir_compiler . file_to_path ( file , output )
116
- else
117
- :elixir_compiler . file ( file , Keyword . get ( options , :dest ) )
113
+ result =
114
+ try do
115
+ _ = if output do
116
+ :elixir_compiler . file_to_path ( file , output )
117
+ else
118
+ :elixir_compiler . file ( file , Keyword . get ( options , :dest ) )
119
+ end
120
+ :ok
121
+ catch
122
+ kind , reason ->
123
+ { kind , reason , System . stacktrace }
118
124
end
119
- { :shutdown , file }
120
- catch
121
- kind , reason ->
122
- { :failure , kind , reason , System . stacktrace }
123
- end )
125
+
126
+ send ( parent , { :file_compiled , self ( ) , file , result } )
127
+ exit ( :shutdown )
124
128
end
125
129
126
130
timeout = Keyword . get ( options , :long_compilation_threshold , 10 ) * 1_000
@@ -226,26 +230,52 @@ defmodule Kernel.ParallelCompiler do
226
230
end
227
231
spawn_compilers ( state )
228
232
229
- { :DOWN , _down_ref , :process , down_pid , { :shutdown , file } } ->
233
+ { :file_compiled , child_pid , file , :ok } ->
234
+ discard_down ( child_pid )
235
+
230
236
if callback = Keyword . get ( options , :each_file ) do
231
237
callback . ( file )
232
238
end
233
239
234
- cancel_waiting_timer ( queued , down_pid )
240
+ cancel_waiting_timer ( queued , child_pid )
235
241
236
242
# Sometimes we may have spurious entries in the waiting
237
243
# list because someone invoked try/rescue UndefinedFunctionError
238
- new_entries = List . delete ( entries , down_pid )
239
- new_queued = List . keydelete ( queued , down_pid , 0 )
240
- new_waiting = List . keydelete ( waiting , down_pid , 1 )
244
+ new_entries = List . delete ( entries , child_pid )
245
+ new_queued = List . keydelete ( queued , child_pid , 0 )
246
+ new_waiting = List . keydelete ( waiting , child_pid , 1 )
241
247
spawn_compilers ( % { state | entries: new_entries , waiting: new_waiting , queued: new_queued } )
242
248
243
- { :DOWN , down_ref , :process , _down_pid , reason } ->
244
- handle_failure ( down_ref , reason , queued )
249
+ { :file_compiled , child_pid , file , { kind , reason , stack } } ->
250
+ discard_down ( child_pid )
251
+ print_error ( file , kind , reason , stack )
252
+ terminate ( queued )
253
+
254
+ { :DOWN , ref , :process , _pid , reason } ->
255
+ handle_down ( queued , ref , reason )
245
256
wait_for_messages ( state )
246
257
end
247
258
end
248
259
260
+ defp discard_down ( pid ) do
261
+ receive do
262
+ { :DOWN , _ , :process , ^ pid , _ } -> :ok
263
+ end
264
+ end
265
+
266
+ defp handle_down ( _queued , _ref , :normal ) do
267
+ :ok
268
+ end
269
+ defp handle_down ( queued , ref , reason ) do
270
+ case List . keyfind ( queued , ref , 1 ) do
271
+ { _child , ^ ref , file , _timer_ref } ->
272
+ print_error ( file , :exit , reason , [ ] )
273
+ terminate ( queued )
274
+ _ ->
275
+ :ok
276
+ end
277
+ end
278
+
249
279
defp handle_deadlock ( waiting , queued ) do
250
280
deadlock =
251
281
for { pid , _ , file , _ } <- queued do
@@ -255,7 +285,7 @@ defmodule Kernel.ParallelCompiler do
255
285
{ _kind , ^ pid , _ , on , _ } = List . keyfind ( waiting , pid , 1 )
256
286
error = CompileError . exception ( description: "deadlocked waiting on module #{ inspect on } " ,
257
287
file: nil , line: nil )
258
- print_failure ( file , { :failure , : error, error , stacktrace } )
288
+ print_error ( file , : error, error , stacktrace )
259
289
260
290
{ file , on }
261
291
end
@@ -279,35 +309,16 @@ defmodule Kernel.ParallelCompiler do
279
309
exit ( { :shutdown , 1 } )
280
310
end
281
311
282
- defp handle_failure ( ref , reason , queued ) do
283
- if file = find_failure ( ref , queued ) do
284
- print_failure ( file , reason )
285
- for { pid , _ , _ , _ } <- queued do
286
- Process . exit ( pid , :kill )
287
- end
288
- exit ( { :shutdown , 1 } )
289
- end
290
- end
291
-
292
- defp find_failure ( ref , queued ) do
293
- case List . keyfind ( queued , ref , 1 ) do
294
- { _child , ^ ref , file , _timer_ref } -> file
295
- _ -> nil
312
+ defp terminate ( queued ) do
313
+ for { pid , _ , _ , _ } <- queued do
314
+ Process . exit ( pid , :kill )
296
315
end
316
+ exit ( { :shutdown , 1 } )
297
317
end
298
318
299
- defp print_failure ( _file , { :shutdown , _ } ) do
300
- :ok
301
- end
302
-
303
- defp print_failure ( file , { :failure , kind , reason , stacktrace } ) do
304
- IO . write [ "\n == Compilation error in file #{ Path . relative_to_cwd ( file ) } ==\n " ,
305
- Kernel.CLI . format_error ( kind , reason , stacktrace ) ]
306
- end
307
-
308
- defp print_failure ( file , reason ) do
319
+ defp print_error ( file , kind , reason , stack ) do
309
320
IO . write [ "\n == Compilation error in file #{ Path . relative_to_cwd ( file ) } ==\n " ,
310
- Kernel.CLI . print_error ( :exit , reason , [ ] ) ]
321
+ Kernel.CLI . format_error ( kind , reason , stack ) ]
311
322
end
312
323
313
324
defp cancel_waiting_timer ( queued , child_pid ) do
0 commit comments