##// END OF EJS Templates
chgserver: discard buffered output before restoring fds (issue6207)...
Yuya Nishihara -
r45745:a17454a1 stable
parent child Browse files
Show More
@@ -434,8 +434,11 b' class chgcmdserver(commandserver.server)'
434 434 self._oldios.append((ch, fp, fd))
435 435
436 436 def _restoreio(self):
437 if not self._oldios:
438 return
439 nullfd = os.open(os.devnull, os.O_WRONLY)
437 440 ui = self.ui
438 for (ch, fp, fd), (cn, fn, _mode) in zip(self._oldios, _iochannels):
441 for (ch, fp, fd), (cn, fn, mode) in zip(self._oldios, _iochannels):
439 442 newfp = getattr(ui, fn)
440 443 # close newfp while it's associated with client; otherwise it
441 444 # would be closed when newfp is deleted
@@ -443,6 +446,12 b' class chgcmdserver(commandserver.server)'
443 446 newfp.close()
444 447 # restore original fd: fp is open again
445 448 try:
449 if newfp is fp and 'w' in mode:
450 # Discard buffered data which couldn't be flushed because
451 # of EPIPE. The data should belong to the current session
452 # and should never persist.
453 os.dup2(nullfd, fp.fileno())
454 fp.flush()
446 455 os.dup2(fd, fp.fileno())
447 456 except OSError as err:
448 457 # According to issue6330, running chg on heavy loaded systems
@@ -459,6 +468,7 b' class chgcmdserver(commandserver.server)'
459 468 os.close(fd)
460 469 setattr(self, cn, ch)
461 470 setattr(ui, fn, fp)
471 os.close(nullfd)
462 472 del self._oldios[:]
463 473
464 474 def validate(self):
@@ -152,6 +152,49 b' chg waits for pager if runcommand raises'
152 152 crash-pager: going to crash
153 153 [255]
154 154
155 no stdout data should be printed after pager quits, and the buffered data
156 should never persist (issue6207)
157
158 "killed!" may be printed if terminated by SIGPIPE, which isn't important
159 in this test.
160
161 $ cat > $TESTTMP/bulkwrite.py <<'EOF'
162 > import time
163 > from mercurial import error, registrar
164 > cmdtable = {}
165 > command = registrar.command(cmdtable)
166 > @command(b'bulkwrite')
167 > def bulkwrite(ui, repo, *pats, **opts):
168 > ui.write(b'going to write massive data\n')
169 > ui.flush()
170 > t = time.time()
171 > while time.time() - t < 2:
172 > ui.write(b'x' * 1023 + b'\n') # will be interrupted by SIGPIPE
173 > raise error.Abort(b"write() doesn't block")
174 > EOF
175
176 $ cat > $TESTTMP/fakepager.py <<'EOF'
177 > import sys
178 > import time
179 > sys.stdout.write('paged! %r\n' % sys.stdin.readline())
180 > time.sleep(1) # new data will be written
181 > EOF
182
183 $ cat >> .hg/hgrc <<EOF
184 > [extensions]
185 > bulkwrite = $TESTTMP/bulkwrite.py
186 > EOF
187
188 $ chg bulkwrite --pager=on --color no --config ui.formatted=True
189 paged! 'going to write massive data\n'
190 killed! (?)
191 [255]
192
193 $ chg bulkwrite --pager=on --color no --config ui.formatted=True
194 paged! 'going to write massive data\n'
195 killed! (?)
196 [255]
197
155 198 $ cd ..
156 199
157 200 server lifecycle
General Comments 0
You need to be logged in to leave comments. Login now