Patchwork D2461: wireprotoserver: ability to run an SSH server until an event is set

login
register
mail settings
Submitter phabricator
Date Feb. 26, 2018, 9:16 p.m.
Message ID <differential-rev-PHID-DREV-p7sua36al5ymmmfnawdy-req@phab.mercurial-scm.org>
Download mbox | patch
Permalink /patch/28421/
State Superseded
Headers show

Comments

phabricator - Feb. 26, 2018, 9:16 p.m.
indygreg created this revision.
Herald added a subscriber: mercurial-devel.
Herald added a reviewer: hg-reviewers.

REVISION SUMMARY
  It seems useful to be able to start an SSH protocol server that
  won't run forever and won't call sys.exit() when it stops. This
  could be used to facilitate intra-process testing of the SSH
  protocol, for example.
  
  We teach the server function to loop until a threading.Event is set
  and invent a new API to run the server until an event is set. It also
  won't sys.exit() afterwards.
  
  There aren't many callers of serve_forever(). So we could refactor
  them relatively easily. But I was lazy.
  
  threading.Event might be a bit heavyweight. An alternative would be
  a list whose only elements is changed. We can't use a simple scalar
  value like a bool or int because those types are immutable. Events
  are what you use in systems programming for this use case, so the
  use of threading.Event seems justified.

REPOSITORY
  rHG Mercurial

REVISION DETAIL
  https://phab.mercurial-scm.org/D2461

AFFECTED FILES
  mercurial/wireprotoserver.py

CHANGE DETAILS




To: indygreg, #hg-reviewers
Cc: mercurial-devel

Patch

diff --git a/mercurial/wireprotoserver.py b/mercurial/wireprotoserver.py
--- a/mercurial/wireprotoserver.py
+++ b/mercurial/wireprotoserver.py
@@ -9,6 +9,7 @@ 
 import contextlib
 import struct
 import sys
+import threading
 
 from .i18n import _
 from . import (
@@ -373,7 +374,7 @@ 
 class sshv2protocolhandler(sshv1protocolhandler):
     """Protocol handler for version 2 of the SSH protocol."""
 
-def _runsshserver(ui, repo, fin, fout):
+def _runsshserver(ui, repo, fin, fout, ev):
     # This function operates like a state machine of sorts. The following
     # states are defined:
     #
@@ -430,7 +431,7 @@ 
     proto = sshv1protocolhandler(ui, fin, fout)
     protoswitched = False
 
-    while True:
+    while not ev.is_set():
         if state == 'protov1-serving':
             # Commands are issued on new lines.
             request = fin.readline()[:-1]
@@ -601,5 +602,9 @@ 
         util.setbinary(self._fout)
 
     def serve_forever(self):
-        _runsshserver(self._ui, self._repo, self._fin, self._fout)
+        self.serveuntil(threading.Event())
         sys.exit(0)
+
+    def serveuntil(self, ev):
+        """Serve until a threading.Event is set."""
+        _runsshserver(self._ui, self._repo, self._fin, self._fout, ev)