Gentoo Archives: gentoo-commits

From: "Zac Medico (zmedico)" <zmedico@g.o>
To: gentoo-commits@l.g.o
Subject: [gentoo-commits] portage r10851 - main/trunk/pym/_emerge
Date: Sun, 29 Jun 2008 17:27:44
Message-Id: E1KD0gc-0003zC-92@stork.gentoo.org
1 Author: zmedico
2 Date: 2008-06-29 17:27:37 +0000 (Sun, 29 Jun 2008)
3 New Revision: 10851
4
5 Modified:
6 main/trunk/pym/_emerge/__init__.py
7 Log:
8 Centralize select.poll() event handling in MergeTask._schedule(). This will
9 allow the parent process to handle output of multiple child processes
10 running in parllel.
11
12
13 Modified: main/trunk/pym/_emerge/__init__.py
14 ===================================================================
15 --- main/trunk/pym/_emerge/__init__.py 2008-06-29 15:08:37 UTC (rev 10850)
16 +++ main/trunk/pym/_emerge/__init__.py 2008-06-29 17:27:37 UTC (rev 10851)
17 @@ -20,6 +20,8 @@
18 except KeyboardInterrupt:
19 sys.exit(1)
20
21 +import array
22 +import select
23 import gc
24 import os, stat
25 import platform
26 @@ -1527,7 +1529,7 @@
27 """
28 TODO: Support asynchronous execution, to implement parallel builds.
29 """
30 - __slots__ = ("pkg", "settings")
31 + __slots__ = ("pkg", "register", "schedule", "settings", "unregister")
32
33 _phases = ("setup", "unpack", "compile", "test", "install")
34
35 @@ -1562,9 +1564,10 @@
36
37 for mydo in self._phases:
38 ebuild_phase = EbuildPhase(fd_pipes=fd_pipes,
39 - pkg=self.pkg, phase=mydo, settings=settings)
40 + pkg=self.pkg, phase=mydo, register=self.register,
41 + settings=settings, unregister=self.unregister)
42 ebuild_phase.start()
43 - ebuild_phase._output_handler()
44 + self.schedule()
45 retval = ebuild_phase.wait()
46
47 portage._post_phase_userpriv_perms(settings)
48 @@ -1580,7 +1583,8 @@
49
50 class EbuildPhase(SlotObject):
51
52 - __slots__ = ("fd_pipes", "phase", "pkg", "settings",
53 + __slots__ = ("fd_pipes", "phase", "pkg",
54 + "register", "settings", "unregister",
55 "pid", "returncode", "files")
56
57 _file_names = ("log", "stdout", "ebuild")
58 @@ -1662,40 +1666,25 @@
59 files["log"] = open(logfile, 'a')
60 files["stdout"] = os.fdopen(os.dup(fd_pipes_orig[1]), 'w')
61 files["ebuild"] = os.fdopen(master_fd, 'r')
62 + self.register(files["ebuild"].fileno(),
63 + select.POLLIN, self._output_handler)
64
65 - def _output_handler(self):
66 - log_file = self.files.get("log")
67 - if log_file is None:
68 - return
69 - ebuild_file = self.files["ebuild"]
70 - stdout_file = self.files["stdout"]
71 - iwtd = [ebuild_file]
72 - owtd = []
73 - ewtd = []
74 - import array, select
75 - buffsize = self._bufsize
76 - eof = False
77 - while not eof:
78 - events = select.select(iwtd, owtd, ewtd)
79 - for f in events[0]:
80 - # Use non-blocking mode to prevent read
81 - # calls from blocking indefinitely.
82 - buf = array.array('B')
83 - try:
84 - buf.fromfile(f, buffsize)
85 - except EOFError:
86 - pass
87 - if not buf:
88 - eof = True
89 - break
90 - if f is ebuild_file:
91 - buf.tofile(stdout_file)
92 - stdout_file.flush()
93 - buf.tofile(log_file)
94 - log_file.flush()
95 - log_file.close()
96 - stdout_file.close()
97 - ebuild_file.close()
98 + def _output_handler(self, fd, event):
99 + files = self.files
100 + buf = array.array('B')
101 + try:
102 + buf.fromfile(files["ebuild"], self._bufsize)
103 + except EOFError:
104 + pass
105 + if buf:
106 + buf.tofile(files["stdout"])
107 + files["stdout"].flush()
108 + buf.tofile(files["log"])
109 + files["log"].flush()
110 + else:
111 + self.unregister(files["ebuild"].fileno())
112 + for f in files.values():
113 + f.close()
114
115 def wait(self):
116 pid = self.pid
117 @@ -6357,6 +6346,8 @@
118 clone=trees[root]["vartree"].settings)
119 self.curval = 0
120 self._spawned_pids = []
121 + self._poll_event_handlers = {}
122 + self._poll = select.poll()
123
124 class _pkg_failure(portage.exception.PortageException):
125 """
126 @@ -6521,6 +6512,19 @@
127 pass
128 spawned_pids.remove(pid)
129
130 + def _register(self, f, eventmask, handler):
131 + self._poll_event_handlers[f] = handler
132 + self._poll.register(f, eventmask)
133 +
134 + def _unregister(self, f):
135 + self._poll.unregister(f)
136 + del self._poll_event_handlers[f]
137 +
138 + def _schedule(self):
139 + while self._poll_event_handlers:
140 + for f, event in self._poll.poll():
141 + self._poll_event_handlers[f](f, event)
142 +
143 def _merge(self):
144 mylist = self._mergelist
145 favorites = self._favorites
146 @@ -6759,7 +6763,9 @@
147 (mergecount, len(mymergelist), pkg_key)
148 emergelog(xterm_titles, msg, short_msg=short_msg)
149
150 - build = EbuildBuild(pkg=pkg, settings=pkgsettings)
151 + build = EbuildBuild(pkg=pkg, register=self._register,
152 + schedule=self._schedule, settings=pkgsettings,
153 + unregister=self._unregister)
154 retval = build.execute()
155 if retval != os.EX_OK:
156 raise self._pkg_failure(retval)
157 @@ -6794,7 +6800,9 @@
158 (mergecount, len(mymergelist), pkg_key)
159 emergelog(xterm_titles, msg, short_msg=short_msg)
160
161 - build = EbuildBuild(pkg=pkg, settings=pkgsettings)
162 + build = EbuildBuild(pkg=pkg, register=self._register,
163 + schedule=self._schedule, settings=pkgsettings,
164 + unregister=self._unregister)
165 retval = build.execute()
166 if retval != os.EX_OK:
167 raise self._pkg_failure(retval)
168
169 --
170 gentoo-commits@l.g.o mailing list