mercurial/commandserver.py
changeset 29586 42cdba9cfee4
parent 29585 6ed452d0f1f1
child 29587 536eec443b4a
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     }