1 |
Author: zmedico |
2 |
Date: 2008-07-04 03:03:44 +0000 (Fri, 04 Jul 2008) |
3 |
New Revision: 10920 |
4 |
|
5 |
Modified: |
6 |
main/trunk/pym/_emerge/__init__.py |
7 |
Log: |
8 |
When logging is disabled, make the EbuildPhase create a dummy pipe to provide |
9 |
a file descriptor that the scheduler can use to monitor the process from |
10 |
inside a poll() loop. |
11 |
|
12 |
|
13 |
Modified: main/trunk/pym/_emerge/__init__.py |
14 |
=================================================================== |
15 |
--- main/trunk/pym/_emerge/__init__.py 2008-07-04 00:46:07 UTC (rev 10919) |
16 |
+++ main/trunk/pym/_emerge/__init__.py 2008-07-04 03:03:44 UTC (rev 10920) |
17 |
@@ -1881,6 +1881,11 @@ |
18 |
_files_dict = slot_dict_class(_file_names, prefix="") |
19 |
_bufsize = 4096 |
20 |
|
21 |
+ # A file descriptor is required for the scheduler to monitor changes from |
22 |
+ # inside a poll() loop. When logging is not enabled, create a pipe just to |
23 |
+ # serve this purpose alone. |
24 |
+ _dummy_pipe_fd = 9 |
25 |
+ |
26 |
def start(self): |
27 |
root_config = self.pkg.root_config |
28 |
tree = self.tree |
29 |
@@ -1931,7 +1936,6 @@ |
30 |
mode[1] &= ~termios.OPOST |
31 |
termios.tcsetattr(slave_fd, termios.TCSANOW, mode) |
32 |
|
33 |
- import fcntl |
34 |
fcntl.fcntl(master_fd, fcntl.F_SETFL, |
35 |
fcntl.fcntl(master_fd, fcntl.F_GETFL) | os.O_NONBLOCK) |
36 |
|
37 |
@@ -1945,6 +1949,17 @@ |
38 |
fd_pipes[1] = slave_fd |
39 |
fd_pipes[2] = slave_fd |
40 |
|
41 |
+ else: |
42 |
+ # Create a dummy pipe so the scheduler can monitor |
43 |
+ # the process from inside a poll() loop. |
44 |
+ master_fd, slave_fd = os.pipe() |
45 |
+ fcntl.fcntl(master_fd, fcntl.F_SETFL, |
46 |
+ fcntl.fcntl(master_fd, fcntl.F_GETFL) | os.O_NONBLOCK) |
47 |
+ fd_pipes.setdefault(0, sys.stdin.fileno()) |
48 |
+ fd_pipes.setdefault(1, sys.stdout.fileno()) |
49 |
+ fd_pipes.setdefault(2, sys.stderr.fileno()) |
50 |
+ fd_pipes[self._dummy_pipe_fd] = slave_fd |
51 |
+ |
52 |
retval = portage.doebuild(ebuild_path, self.phase, |
53 |
root_config.root, settings, debug, |
54 |
mydbapi=mydbapi, tree=tree, |
55 |
@@ -1953,14 +1968,17 @@ |
56 |
self.pid = retval[0] |
57 |
|
58 |
if logfile: |
59 |
- os.close(slave_fd) |
60 |
files.log = open(logfile, 'a') |
61 |
files.stdout = os.fdopen(os.dup(fd_pipes_orig[1]), 'w') |
62 |
- files.ebuild = os.fdopen(master_fd, 'r') |
63 |
- self.registered = True |
64 |
- self.register(files.ebuild.fileno(), |
65 |
- select.POLLIN, self._output_handler) |
66 |
+ output_handler = self._output_handler |
67 |
+ else: |
68 |
+ output_handler = self._dummy_handler |
69 |
|
70 |
+ os.close(slave_fd) |
71 |
+ files.ebuild = os.fdopen(master_fd, 'r') |
72 |
+ self.registered = True |
73 |
+ self.register(files.ebuild.fileno(), select.POLLIN, output_handler) |
74 |
+ |
75 |
def _output_handler(self, fd, event): |
76 |
files = self.files |
77 |
buf = array.array('B') |
78 |
@@ -1980,6 +1998,27 @@ |
79 |
self.registered = False |
80 |
self.unregister(fd) |
81 |
|
82 |
+ def _dummy_handler(self, fd, event): |
83 |
+ """ |
84 |
+ This method is mainly interested in detecting EOF, since |
85 |
+ the only purpose of the pipe is to allow the scheduler to |
86 |
+ monitor the process from inside a poll() loop. |
87 |
+ """ |
88 |
+ files = self.files |
89 |
+ buf = array.array('B') |
90 |
+ try: |
91 |
+ buf.fromfile(files.ebuild, self._bufsize) |
92 |
+ except EOFError: |
93 |
+ pass |
94 |
+ if buf: |
95 |
+ pass |
96 |
+ else: |
97 |
+ fd = files.ebuild.fileno() |
98 |
+ for f in files.values(): |
99 |
+ f.close() |
100 |
+ self.registered = False |
101 |
+ self.unregister(fd) |
102 |
+ |
103 |
def _set_returncode(self, wait_retval): |
104 |
SubProcess._set_returncode(self, wait_retval) |
105 |
msg = portage._doebuild_exit_status_check( |
106 |
|
107 |
-- |
108 |
gentoo-commits@l.g.o mailing list |