Mercurial > public > mercurial-scm > hg-stable
comparison mercurial/commandserver.py @ 29586:42cdba9cfee4
commandserver: separate initialization and cleanup of forked process
Separated _initworkerprocess() and _serverequest() can be reused when
implementing a prefork service.
author | Yuya Nishihara <yuya@tcha.org> |
---|---|
date | Sun, 22 May 2016 13:53:32 +0900 |
parents | 6ed452d0f1f1 |
children | 536eec443b4a |
comparison
equal
deleted
inserted
replaced
29585:6ed452d0f1f1 | 29586:42cdba9cfee4 |
---|---|
340 return sv.serve() | 340 return sv.serve() |
341 finally: | 341 finally: |
342 sv.cleanup() | 342 sv.cleanup() |
343 _restoreio(ui, fin, fout) | 343 _restoreio(ui, fin, fout) |
344 | 344 |
345 def _serverequest(ui, repo, conn, createcmdserver): | 345 def _initworkerprocess(): |
346 # use a different process group from the master process, making this | 346 # use a different process group from the master process, making this |
347 # process pass kernel "is_current_pgrp_orphaned" check so signals like | 347 # process pass kernel "is_current_pgrp_orphaned" check so signals like |
348 # SIGTSTP, SIGTTIN, SIGTTOU are not ignored. | 348 # SIGTSTP, SIGTTIN, SIGTTOU are not ignored. |
349 os.setpgid(0, 0) | 349 os.setpgid(0, 0) |
350 # change random state otherwise forked request handlers would have a | 350 # change random state otherwise forked request handlers would have a |
351 # same state inherited from parent. | 351 # same state inherited from parent. |
352 random.seed() | 352 random.seed() |
353 | 353 |
354 def _serverequest(ui, repo, conn, createcmdserver): | |
354 fin = conn.makefile('rb') | 355 fin = conn.makefile('rb') |
355 fout = conn.makefile('wb') | 356 fout = conn.makefile('wb') |
356 sv = None | 357 sv = None |
357 try: | 358 try: |
358 sv = createcmdserver(repo, conn, fin, fout) | 359 sv = createcmdserver(repo, conn, fin, fout) |
383 try: | 384 try: |
384 fout.close() # implicit flush() may cause another EPIPE | 385 fout.close() # implicit flush() may cause another EPIPE |
385 except IOError as inst: | 386 except IOError as inst: |
386 if inst.errno != errno.EPIPE: | 387 if inst.errno != errno.EPIPE: |
387 raise | 388 raise |
388 # trigger __del__ since ForkingMixIn uses os._exit | |
389 gc.collect() | |
390 | 389 |
391 class unixservicehandler(object): | 390 class unixservicehandler(object): |
392 """Set of pluggable operations for unix-mode services | 391 """Set of pluggable operations for unix-mode services |
393 | 392 |
394 Almost all methods except for createcmdserver() are called in the main | 393 Almost all methods except for createcmdserver() are called in the main |
515 self.ui.debug('worker process exited (pid=%d)\n' % pid) | 514 self.ui.debug('worker process exited (pid=%d)\n' % pid) |
516 self._workerpids.discard(pid) | 515 self._workerpids.discard(pid) |
517 | 516 |
518 def _serveworker(self, conn): | 517 def _serveworker(self, conn): |
519 signal.signal(signal.SIGCHLD, self._oldsigchldhandler) | 518 signal.signal(signal.SIGCHLD, self._oldsigchldhandler) |
519 _initworkerprocess() | |
520 h = self._servicehandler | 520 h = self._servicehandler |
521 _serverequest(self.ui, self.repo, conn, h.createcmdserver) | 521 try: |
522 _serverequest(self.ui, self.repo, conn, h.createcmdserver) | |
523 finally: | |
524 gc.collect() # trigger __del__ since worker process uses os._exit | |
522 | 525 |
523 _servicemap = { | 526 _servicemap = { |
524 'pipe': pipeservice, | 527 'pipe': pipeservice, |
525 'unix': unixforkingservice, | 528 'unix': unixforkingservice, |
526 } | 529 } |