Mercurial > hg
comparison mercurial/commandserver.py @ 40875:e7110f44ee2d
commandserver: pass around option to hook repo instance creation
This is necessary to wrap a repo instance so the master process will be
notified on repo.close().
author | Yuya Nishihara <yuya@tcha.org> |
---|---|
date | Wed, 31 Oct 2018 21:57:11 +0900 |
parents | 25e9089c7686 |
children | dc9901558e3c |
comparison
equal
deleted
inserted
replaced
40874:348352658e4b | 40875:e7110f44ee2d |
---|---|
194 class server(object): | 194 class server(object): |
195 """ | 195 """ |
196 Listens for commands on fin, runs them and writes the output on a channel | 196 Listens for commands on fin, runs them and writes the output on a channel |
197 based stream to fout. | 197 based stream to fout. |
198 """ | 198 """ |
199 def __init__(self, ui, repo, fin, fout): | 199 def __init__(self, ui, repo, fin, fout, prereposetups=None): |
200 self.cwd = encoding.getcwd() | 200 self.cwd = encoding.getcwd() |
201 | 201 |
202 if repo: | 202 if repo: |
203 # the ui here is really the repo ui so take its baseui so we don't | 203 # the ui here is really the repo ui so take its baseui so we don't |
204 # end up with its local configuration | 204 # end up with its local configuration |
206 self.repo = repo | 206 self.repo = repo |
207 self.repoui = repo.ui | 207 self.repoui = repo.ui |
208 else: | 208 else: |
209 self.ui = ui | 209 self.ui = ui |
210 self.repo = self.repoui = None | 210 self.repo = self.repoui = None |
211 self._prereposetups = prereposetups | |
211 | 212 |
212 self.cdebug = channeledoutput(fout, 'd') | 213 self.cdebug = channeledoutput(fout, 'd') |
213 self.cerr = channeledoutput(fout, 'e') | 214 self.cerr = channeledoutput(fout, 'e') |
214 self.cout = channeledoutput(fout, 'o') | 215 self.cout = channeledoutput(fout, 'o') |
215 self.cin = channeledinput(fin, fout, 'I') | 216 self.cin = channeledinput(fin, fout, 'I') |
292 # enforced only if cin is a channel. | 293 # enforced only if cin is a channel. |
293 if not util.safehasattr(self.cin, 'fileno'): | 294 if not util.safehasattr(self.cin, 'fileno'): |
294 ui.setconfig('ui', 'nontty', 'true', 'commandserver') | 295 ui.setconfig('ui', 'nontty', 'true', 'commandserver') |
295 | 296 |
296 req = dispatch.request(args[:], copiedui, self.repo, self.cin, | 297 req = dispatch.request(args[:], copiedui, self.repo, self.cin, |
297 self.cout, self.cerr, self.cmsg) | 298 self.cout, self.cerr, self.cmsg, |
299 prereposetups=self._prereposetups) | |
298 | 300 |
299 try: | 301 try: |
300 ret = dispatch.dispatch(req) & 255 | 302 ret = dispatch.dispatch(req) & 255 |
301 self.cresult.write(struct.pack('>i', int(ret))) | 303 self.cresult.write(struct.pack('>i', int(ret))) |
302 finally: | 304 finally: |
418 os.setpgid(0, 0) | 420 os.setpgid(0, 0) |
419 # change random state otherwise forked request handlers would have a | 421 # change random state otherwise forked request handlers would have a |
420 # same state inherited from parent. | 422 # same state inherited from parent. |
421 random.seed() | 423 random.seed() |
422 | 424 |
423 def _serverequest(ui, repo, conn, createcmdserver): | 425 def _serverequest(ui, repo, conn, createcmdserver, prereposetups): |
424 fin = conn.makefile(r'rb') | 426 fin = conn.makefile(r'rb') |
425 fout = conn.makefile(r'wb') | 427 fout = conn.makefile(r'wb') |
426 sv = None | 428 sv = None |
427 try: | 429 try: |
428 sv = createcmdserver(repo, conn, fin, fout) | 430 sv = createcmdserver(repo, conn, fin, fout, prereposetups) |
429 try: | 431 try: |
430 sv.serve() | 432 sv.serve() |
431 # handle exceptions that may be raised by command server. most of | 433 # handle exceptions that may be raised by command server. most of |
432 # known exceptions are caught by dispatch. | 434 # known exceptions are caught by dispatch. |
433 except error.Abort as inst: | 435 except error.Abort as inst: |
482 return False | 484 return False |
483 | 485 |
484 def newconnection(self): | 486 def newconnection(self): |
485 """Called when main process notices new connection""" | 487 """Called when main process notices new connection""" |
486 | 488 |
487 def createcmdserver(self, repo, conn, fin, fout): | 489 def createcmdserver(self, repo, conn, fin, fout, prereposetups): |
488 """Create new command server instance; called in the process that | 490 """Create new command server instance; called in the process that |
489 serves for the current connection""" | 491 serves for the current connection""" |
490 return server(self.ui, repo, fin, fout) | 492 return server(self.ui, repo, fin, fout, prereposetups) |
491 | 493 |
492 class unixforkingservice(object): | 494 class unixforkingservice(object): |
493 """ | 495 """ |
494 Listens on unix domain socket and forks server per connection | 496 Listens on unix domain socket and forks server per connection |
495 """ | 497 """ |
617 def _runworker(self, conn): | 619 def _runworker(self, conn): |
618 signal.signal(signal.SIGCHLD, self._oldsigchldhandler) | 620 signal.signal(signal.SIGCHLD, self._oldsigchldhandler) |
619 _initworkerprocess() | 621 _initworkerprocess() |
620 h = self._servicehandler | 622 h = self._servicehandler |
621 try: | 623 try: |
622 _serverequest(self.ui, self.repo, conn, h.createcmdserver) | 624 _serverequest(self.ui, self.repo, conn, h.createcmdserver, |
625 prereposetups=None) # TODO: pass in hook functions | |
623 finally: | 626 finally: |
624 gc.collect() # trigger __del__ since worker process uses os._exit | 627 gc.collect() # trigger __del__ since worker process uses os._exit |