diff options
author | Leonardo Sandoval <leonardo.sandoval.gonzalez@linux.intel.com> | 2017-09-04 14:35:48 -0700 |
---|---|---|
committer | Richard Purdie <richard.purdie@linuxfoundation.org> | 2017-09-11 17:30:28 +0100 |
commit | f6f6b3e5d5a77010d5716b2cb980b271ee5dc8e8 (patch) | |
tree | f4d9e7737b858892c911ffe69fa23d8be5aba689 /meta/classes/package_ipk.bbclass | |
parent | a8ab6d5c829d02107a968e5925c96f78bc98522a (diff) | |
download | poky-f6f6b3e5d5a77010d5716b2cb980b271ee5dc8e8.tar.gz |
package_[deb|ipk]: improve multiprocess logic when creating deb/ipk packages
Current implementation does not handle possible exceptions coming from child
processes, the latter responsible for creating packages. With the aim to have more
control, use pipes to communicate exceptions and stop package creation in case
of failure.
Helps to debug [YOCTO #12012].
(From OE-Core rev: 11350a67ba137f560d04aa643ff500a7ff112c73)
Signed-off-by: Leonardo Sandoval <leonardo.sandoval.gonzalez@linux.intel.com>
Signed-off-by: Ross Burton <ross.burton@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
Diffstat (limited to 'meta/classes/package_ipk.bbclass')
-rw-r--r-- | meta/classes/package_ipk.bbclass | 36 |
1 files changed, 33 insertions, 3 deletions
diff --git a/meta/classes/package_ipk.bbclass b/meta/classes/package_ipk.bbclass index ec90996184..8439cda6dd 100644 --- a/meta/classes/package_ipk.bbclass +++ b/meta/classes/package_ipk.bbclass | |||
@@ -17,7 +17,29 @@ OPKG_ARGS += "${@['', '--add-exclude ' + ' --add-exclude '.join((d.getVar('PACKA | |||
17 | OPKGLIBDIR = "${localstatedir}/lib" | 17 | OPKGLIBDIR = "${localstatedir}/lib" |
18 | 18 | ||
19 | python do_package_ipk () { | 19 | python do_package_ipk () { |
20 | from multiprocessing import Process | 20 | import multiprocessing |
21 | import traceback | ||
22 | |||
23 | class IPKWritePkgProcess(multiprocessing.Process): | ||
24 | def __init__(self, *args, **kwargs): | ||
25 | multiprocessing.Process.__init__(self, *args, **kwargs) | ||
26 | self._pconn, self._cconn = multiprocessing.Pipe() | ||
27 | self._exception = None | ||
28 | |||
29 | def run(self): | ||
30 | try: | ||
31 | multiprocessing.Process.run(self) | ||
32 | self._cconn.send(None) | ||
33 | except Exception as e: | ||
34 | tb = traceback.format_exc() | ||
35 | self._cconn.send((e, tb)) | ||
36 | |||
37 | @property | ||
38 | def exception(self): | ||
39 | if self._pconn.poll(): | ||
40 | self._exception = self._pconn.recv() | ||
41 | return self._exception | ||
42 | |||
21 | 43 | ||
22 | oldcwd = os.getcwd() | 44 | oldcwd = os.getcwd() |
23 | 45 | ||
@@ -41,20 +63,28 @@ python do_package_ipk () { | |||
41 | 63 | ||
42 | max_process = int(d.getVar("BB_NUMBER_THREADS") or os.cpu_count() or 1) | 64 | max_process = int(d.getVar("BB_NUMBER_THREADS") or os.cpu_count() or 1) |
43 | launched = [] | 65 | launched = [] |
66 | error = None | ||
44 | pkgs = packages.split() | 67 | pkgs = packages.split() |
45 | while pkgs: | 68 | while not error and pkgs: |
46 | if len(launched) < max_process: | 69 | if len(launched) < max_process: |
47 | p = Process(target=ipk_write_pkg, args=(pkgs.pop(), d)) | 70 | p = IPKWritePkgProcess(target=ipk_write_pkg, args=(pkgs.pop(), d)) |
48 | p.start() | 71 | p.start() |
49 | launched.append(p) | 72 | launched.append(p) |
50 | for q in launched: | 73 | for q in launched: |
51 | # The finished processes are joined when calling is_alive() | 74 | # The finished processes are joined when calling is_alive() |
52 | if not q.is_alive(): | 75 | if not q.is_alive(): |
53 | launched.remove(q) | 76 | launched.remove(q) |
77 | if q.exception: | ||
78 | error, traceback = q.exception | ||
79 | break | ||
80 | |||
54 | for p in launched: | 81 | for p in launched: |
55 | p.join() | 82 | p.join() |
56 | 83 | ||
57 | os.chdir(oldcwd) | 84 | os.chdir(oldcwd) |
85 | |||
86 | if error: | ||
87 | raise error | ||
58 | } | 88 | } |
59 | do_package_ipk[vardeps] += "ipk_write_pkg" | 89 | do_package_ipk[vardeps] += "ipk_write_pkg" |
60 | do_package_ipk[vardepsexclude] = "BB_NUMBER_THREADS" | 90 | do_package_ipk[vardepsexclude] = "BB_NUMBER_THREADS" |