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 """