Mercurial > public > mercurial-scm > hg
comparison mercurial/commandserver.py @ 29542:6011ad3b0a42
commandserver: manually create file objects from socket
Prepares for moving away from SocketServer. See the subsequent patches for
why.
author | Yuya Nishihara <yuya@tcha.org> |
---|---|
date | Sun, 22 May 2016 12:44:25 +0900 |
parents | dda6bf886839 |
children | d74b8a4fde3b |
comparison
equal
deleted
inserted
replaced
29541:9631ff5ebbeb | 29542:6011ad3b0a42 |
---|---|
336 return sv.serve() | 336 return sv.serve() |
337 finally: | 337 finally: |
338 sv.cleanup() | 338 sv.cleanup() |
339 _restoreio(ui, fin, fout) | 339 _restoreio(ui, fin, fout) |
340 | 340 |
341 class _requesthandler(socketserver.StreamRequestHandler): | 341 class _requesthandler(socketserver.BaseRequestHandler): |
342 def handle(self): | 342 def handle(self): |
343 # use a different process group from the master process, making this | 343 # use a different process group from the master process, making this |
344 # process pass kernel "is_current_pgrp_orphaned" check so signals like | 344 # process pass kernel "is_current_pgrp_orphaned" check so signals like |
345 # SIGTSTP, SIGTTIN, SIGTTOU are not ignored. | 345 # SIGTSTP, SIGTTIN, SIGTTOU are not ignored. |
346 os.setpgid(0, 0) | 346 os.setpgid(0, 0) |
347 # change random state otherwise forked request handlers would have a | 347 # change random state otherwise forked request handlers would have a |
348 # same state inherited from parent. | 348 # same state inherited from parent. |
349 random.seed() | 349 random.seed() |
350 ui = self.server.ui | 350 ui = self.server.ui |
351 | |
352 conn = self.request | |
353 fin = conn.makefile('rb') | |
354 fout = conn.makefile('wb') | |
351 sv = None | 355 sv = None |
352 try: | 356 try: |
353 sv = self._createcmdserver() | 357 sv = self._createcmdserver(conn, fin, fout) |
354 try: | 358 try: |
355 sv.serve() | 359 sv.serve() |
356 # handle exceptions that may be raised by command server. most of | 360 # handle exceptions that may be raised by command server. most of |
357 # known exceptions are caught by dispatch. | 361 # known exceptions are caught by dispatch. |
358 except error.Abort as inst: | 362 except error.Abort as inst: |
368 # also write traceback to error channel. otherwise client cannot | 372 # also write traceback to error channel. otherwise client cannot |
369 # see it because it is written to server's stderr by default. | 373 # see it because it is written to server's stderr by default. |
370 if sv: | 374 if sv: |
371 cerr = sv.cerr | 375 cerr = sv.cerr |
372 else: | 376 else: |
373 cerr = channeledoutput(self.wfile, 'e') | 377 cerr = channeledoutput(fout, 'e') |
374 traceback.print_exc(file=cerr) | 378 traceback.print_exc(file=cerr) |
375 raise | 379 raise |
376 finally: | 380 finally: |
381 fin.close() | |
382 try: | |
383 fout.close() # implicit flush() may cause another EPIPE | |
384 except IOError as inst: | |
385 if inst.errno != errno.EPIPE: | |
386 raise | |
377 # trigger __del__ since ForkingMixIn uses os._exit | 387 # trigger __del__ since ForkingMixIn uses os._exit |
378 gc.collect() | 388 gc.collect() |
379 | 389 |
380 def _createcmdserver(self): | 390 def _createcmdserver(self, conn, fin, fout): |
381 ui = self.server.ui | 391 ui = self.server.ui |
382 repo = self.server.repo | 392 repo = self.server.repo |
383 return server(ui, repo, self.rfile, self.wfile) | 393 return server(ui, repo, fin, fout) |
384 | 394 |
385 class unixservice(object): | 395 class unixservice(object): |
386 """ | 396 """ |
387 Listens on unix domain socket and forks server per connection | 397 Listens on unix domain socket and forks server per connection |
388 """ | 398 """ |