Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(258)

Side by Side Diff: pylib/gyp/input.py

Issue 11098023: Make child process errors kill gyp when parallel processing is on. (Closed) Base URL: http://git.chromium.org/external/gyp.git@master
Patch Set: Created 8 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« pylib/gyp/generator/ninja.py ('K') | « pylib/gyp/generator/ninja.py ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 # Copyright (c) 2012 Google Inc. All rights reserved. 1 # Copyright (c) 2012 Google Inc. All rights reserved.
2 # Use of this source code is governed by a BSD-style license that can be 2 # Use of this source code is governed by a BSD-style license that can be
3 # found in the LICENSE file. 3 # found in the LICENSE file.
4 4
5 from compiler.ast import Const 5 from compiler.ast import Const
6 from compiler.ast import Dict 6 from compiler.ast import Dict
7 from compiler.ast import Discard 7 from compiler.ast import Discard
8 from compiler.ast import List 8 from compiler.ast import List
9 from compiler.ast import Module 9 from compiler.ast import Module
10 from compiler.ast import Node 10 from compiler.ast import Node
11 from compiler.ast import Stmt 11 from compiler.ast import Stmt
12 import compiler 12 import compiler
13 import copy 13 import copy
14 import gyp.common 14 import gyp.common
15 import multiprocessing 15 import multiprocessing
16 import optparse 16 import optparse
17 import os.path 17 import os.path
18 import re 18 import re
19 import shlex 19 import shlex
20 import signal
20 import subprocess 21 import subprocess
21 import sys 22 import sys
22 import threading 23 import threading
23 import time 24 import time
24 from gyp.common import GypError 25 from gyp.common import GypError
25 26
26 27
27 # A list of types that are treated as linkable. 28 # A list of types that are treated as linkable.
28 linkable_types = ['executable', 'shared_library', 'loadable_module'] 29 linkable_types = ['executable', 'shared_library', 'loadable_module']
29 30
(...skipping 419 matching lines...) Expand 10 before | Expand all | Expand 10 after
449 def CallLoadTargetBuildFile(global_flags, 450 def CallLoadTargetBuildFile(global_flags,
450 build_file_path, data, 451 build_file_path, data,
451 aux_data, variables, 452 aux_data, variables,
452 includes, depth, check): 453 includes, depth, check):
453 """Wrapper around LoadTargetBuildFile for parallel processing. 454 """Wrapper around LoadTargetBuildFile for parallel processing.
454 455
455 This wrapper is used when LoadTargetBuildFile is executed in 456 This wrapper is used when LoadTargetBuildFile is executed in
456 a worker process. 457 a worker process.
457 """ 458 """
458 459
460 signal.signal(signal.SIGINT, signal.SIG_IGN)
461
459 # Apply globals so that the worker process behaves the same. 462 # Apply globals so that the worker process behaves the same.
460 for key, value in global_flags.iteritems(): 463 for key, value in global_flags.iteritems():
461 globals()[key] = value 464 globals()[key] = value
462 465
463 # Save the keys so we can return data that changed. 466 # Save the keys so we can return data that changed.
464 data_keys = set(data) 467 data_keys = set(data)
465 aux_data_keys = set(aux_data) 468 aux_data_keys = set(aux_data)
466 469
467 result = LoadTargetBuildFile(build_file_path, data, 470 result = LoadTargetBuildFile(build_file_path, data,
468 aux_data, variables, 471 aux_data, variables,
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
540 def LoadTargetBuildFileParallel(build_file_path, data, aux_data, 543 def LoadTargetBuildFileParallel(build_file_path, data, aux_data,
541 variables, includes, depth, check): 544 variables, includes, depth, check):
542 parallel_state = ParallelState() 545 parallel_state = ParallelState()
543 parallel_state.condition = threading.Condition() 546 parallel_state.condition = threading.Condition()
544 parallel_state.dependencies = [build_file_path] 547 parallel_state.dependencies = [build_file_path]
545 parallel_state.scheduled = set([build_file_path]) 548 parallel_state.scheduled = set([build_file_path])
546 parallel_state.pending = 0 549 parallel_state.pending = 0
547 parallel_state.data = data 550 parallel_state.data = data
548 parallel_state.aux_data = aux_data 551 parallel_state.aux_data = aux_data
549 552
550 parallel_state.condition.acquire() 553 try:
551 while parallel_state.dependencies or parallel_state.pending: 554 parallel_state.condition.acquire()
552 if not parallel_state.dependencies: 555 while parallel_state.dependencies or parallel_state.pending:
553 parallel_state.condition.wait() 556 if not parallel_state.dependencies:
554 continue 557 parallel_state.condition.wait()
558 continue
555 559
556 dependency = parallel_state.dependencies.pop() 560 dependency = parallel_state.dependencies.pop()
557 561
558 parallel_state.pending += 1 562 parallel_state.pending += 1
559 data_in = {} 563 data_in = {}
560 data_in['target_build_files'] = data['target_build_files'] 564 data_in['target_build_files'] = data['target_build_files']
561 aux_data_in = {} 565 aux_data_in = {}
562 global_flags = { 566 global_flags = {
563 'path_sections': globals()['path_sections'], 567 'path_sections': globals()['path_sections'],
564 'non_configuration_keys': globals()['non_configuration_keys'], 568 'non_configuration_keys': globals()['non_configuration_keys'],
565 'absolute_build_file_paths': globals()['absolute_build_file_paths'], 569 'absolute_build_file_paths': globals()['absolute_build_file_paths'],
566 'multiple_toolsets': globals()['multiple_toolsets']} 570 'multiple_toolsets': globals()['multiple_toolsets']}
567 571
568 if not parallel_state.pool: 572 if not parallel_state.pool:
569 parallel_state.pool = multiprocessing.Pool(8) 573 parallel_state.pool = multiprocessing.Pool(8)
570 parallel_state.pool.apply_async( 574 parallel_state.pool.apply_async(
571 CallLoadTargetBuildFile, 575 CallLoadTargetBuildFile,
572 args = (global_flags, dependency, 576 args = (global_flags, dependency,
573 data_in, aux_data_in, 577 data_in, aux_data_in,
574 variables, includes, depth, check), 578 variables, includes, depth, check),
575 callback = parallel_state.LoadTargetBuildFileCallback) 579 callback = parallel_state.LoadTargetBuildFileCallback)
580 except KeyboardInterrupt, e:
581 parallel_state.pool.terminate()
582 raise e
576 583
577 parallel_state.condition.release() 584 parallel_state.condition.release()
578 585
579 586
580 # Look for the bracket that matches the first bracket seen in a 587 # Look for the bracket that matches the first bracket seen in a
581 # string, and return the start and end as a tuple. For example, if 588 # string, and return the start and end as a tuple. For example, if
582 # the input is something like "<(foo <(bar)) blah", then it would 589 # the input is something like "<(foo <(bar)) blah", then it would
583 # return (1, 13), indicating the entire string except for the leading 590 # return (1, 13), indicating the entire string except for the leading
584 # "<" and trailing " blah". 591 # "<" and trailing " blah".
585 def FindEnclosingBracketGroup(input): 592 def FindEnclosingBracketGroup(input):
(...skipping 2042 matching lines...) Expand 10 before | Expand all | Expand 10 after
2628 ValidateRunAsInTarget(target, target_dict, build_file) 2635 ValidateRunAsInTarget(target, target_dict, build_file)
2629 ValidateActionsInTarget(target, target_dict, build_file) 2636 ValidateActionsInTarget(target, target_dict, build_file)
2630 2637
2631 # Generators might not expect ints. Turn them into strs. 2638 # Generators might not expect ints. Turn them into strs.
2632 TurnIntIntoStrInDict(data) 2639 TurnIntIntoStrInDict(data)
2633 2640
2634 # TODO(mark): Return |data| for now because the generator needs a list of 2641 # TODO(mark): Return |data| for now because the generator needs a list of
2635 # build files that came in. In the future, maybe it should just accept 2642 # build files that came in. In the future, maybe it should just accept
2636 # a list, and not the whole data dict. 2643 # a list, and not the whole data dict.
2637 return [flat_list, targets, data] 2644 return [flat_list, targets, data]
OLDNEW
« pylib/gyp/generator/ninja.py ('K') | « pylib/gyp/generator/ninja.py ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698