Mercurial > hg-stable
annotate mercurial/commandserver.py @ 30516:dd539e2d89aa
server: move service table and factory from commandserver
This is necessary to solve future dependency cycle between commandserver.py
and chgserver.py.
'cmd' prefix is added to table and function names to avoid conflicts with
hgweb.
author | Yuya Nishihara <yuya@tcha.org> |
---|---|
date | Sat, 15 Oct 2016 13:57:17 +0900 |
parents | 39d13b8c101d |
children | 20a42325fdef |
rev | line source |
---|---|
14647
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
1 # commandserver.py - communicate with Mercurial's API over a pipe |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
2 # |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
3 # Copyright Matt Mackall <mpm@selenic.com> |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
4 # |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
5 # This software may be used and distributed according to the terms of the |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
6 # GNU General Public License version 2 or any later version. |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
7 |
27351
28e50c4b15ed
commandserver: use absolute_import
Yuya Nishihara <yuya@tcha.org>
parents:
26587
diff
changeset
|
8 from __future__ import absolute_import |
28e50c4b15ed
commandserver: use absolute_import
Yuya Nishihara <yuya@tcha.org>
parents:
26587
diff
changeset
|
9 |
28e50c4b15ed
commandserver: use absolute_import
Yuya Nishihara <yuya@tcha.org>
parents:
26587
diff
changeset
|
10 import errno |
29513
e5b4d79a9140
commandserver: backport handling of forking server from chgserver
Yuya Nishihara <yuya@tcha.org>
parents:
29512
diff
changeset
|
11 import gc |
27351
28e50c4b15ed
commandserver: use absolute_import
Yuya Nishihara <yuya@tcha.org>
parents:
26587
diff
changeset
|
12 import os |
29513
e5b4d79a9140
commandserver: backport handling of forking server from chgserver
Yuya Nishihara <yuya@tcha.org>
parents:
29512
diff
changeset
|
13 import random |
29544
024e8f82f3de
commandserver: add new forking server implemented without using SocketServer
Yuya Nishihara <yuya@tcha.org>
parents:
29543
diff
changeset
|
14 import select |
024e8f82f3de
commandserver: add new forking server implemented without using SocketServer
Yuya Nishihara <yuya@tcha.org>
parents:
29543
diff
changeset
|
15 import signal |
024e8f82f3de
commandserver: add new forking server implemented without using SocketServer
Yuya Nishihara <yuya@tcha.org>
parents:
29543
diff
changeset
|
16 import socket |
14647
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
17 import struct |
27351
28e50c4b15ed
commandserver: use absolute_import
Yuya Nishihara <yuya@tcha.org>
parents:
26587
diff
changeset
|
18 import traceback |
28e50c4b15ed
commandserver: use absolute_import
Yuya Nishihara <yuya@tcha.org>
parents:
26587
diff
changeset
|
19 |
28e50c4b15ed
commandserver: use absolute_import
Yuya Nishihara <yuya@tcha.org>
parents:
26587
diff
changeset
|
20 from .i18n import _ |
28e50c4b15ed
commandserver: use absolute_import
Yuya Nishihara <yuya@tcha.org>
parents:
26587
diff
changeset
|
21 from . import ( |
28e50c4b15ed
commandserver: use absolute_import
Yuya Nishihara <yuya@tcha.org>
parents:
26587
diff
changeset
|
22 encoding, |
28e50c4b15ed
commandserver: use absolute_import
Yuya Nishihara <yuya@tcha.org>
parents:
26587
diff
changeset
|
23 error, |
28e50c4b15ed
commandserver: use absolute_import
Yuya Nishihara <yuya@tcha.org>
parents:
26587
diff
changeset
|
24 util, |
28e50c4b15ed
commandserver: use absolute_import
Yuya Nishihara <yuya@tcha.org>
parents:
26587
diff
changeset
|
25 ) |
14647
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
26 |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
27 logfile = None |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
28 |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
29 def log(*args): |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
30 if not logfile: |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
31 return |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
32 |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
33 for a in args: |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
34 logfile.write(str(a)) |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
35 |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
36 logfile.flush() |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
37 |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
38 class channeledoutput(object): |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
39 """ |
22561
1120b1e2f975
cmdserver: correct doc of channeledoutput
Yuya Nishihara <yuya@tcha.org>
parents:
21195
diff
changeset
|
40 Write data to out in the following format: |
14647
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
41 |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
42 data length (unsigned int), |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
43 data |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
44 """ |
22563
8cc5e673cac0
cmdserver: drop useless in_ attribute from channeledoutput
Yuya Nishihara <yuya@tcha.org>
parents:
22562
diff
changeset
|
45 def __init__(self, out, channel): |
14647
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
46 self.out = out |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
47 self.channel = channel |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
48 |
27415
f4ca33e33781
commandserver: implement name() to clarify channel is not a plain file
Yuya Nishihara <yuya@tcha.org>
parents:
27352
diff
changeset
|
49 @property |
f4ca33e33781
commandserver: implement name() to clarify channel is not a plain file
Yuya Nishihara <yuya@tcha.org>
parents:
27352
diff
changeset
|
50 def name(self): |
f4ca33e33781
commandserver: implement name() to clarify channel is not a plain file
Yuya Nishihara <yuya@tcha.org>
parents:
27352
diff
changeset
|
51 return '<%c-channel>' % self.channel |
f4ca33e33781
commandserver: implement name() to clarify channel is not a plain file
Yuya Nishihara <yuya@tcha.org>
parents:
27352
diff
changeset
|
52 |
14647
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
53 def write(self, data): |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
54 if not data: |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
55 return |
30277
7f2313450e86
cmdserver: write channel header and payload by a single write() call
Yuya Nishihara <yuya@tcha.org>
parents:
29609
diff
changeset
|
56 # single write() to guarantee the same atomicity as the underlying file |
7f2313450e86
cmdserver: write channel header and payload by a single write() call
Yuya Nishihara <yuya@tcha.org>
parents:
29609
diff
changeset
|
57 self.out.write(struct.pack('>cI', self.channel, len(data)) + data) |
14647
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
58 self.out.flush() |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
59 |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
60 def __getattr__(self, attr): |
27915
5f2a308bac94
commandserver: drop tell() and seek() from channels (issue5049)
Yuya Nishihara <yuya@tcha.org>
parents:
27566
diff
changeset
|
61 if attr in ('isatty', 'fileno', 'tell', 'seek'): |
18174
56ef99fbd6f2
commandserver: clean up use of two-argument raise
Augie Fackler <raf@durin42.com>
parents:
17425
diff
changeset
|
62 raise AttributeError(attr) |
22563
8cc5e673cac0
cmdserver: drop useless in_ attribute from channeledoutput
Yuya Nishihara <yuya@tcha.org>
parents:
22562
diff
changeset
|
63 return getattr(self.out, attr) |
14647
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
64 |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
65 class channeledinput(object): |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
66 """ |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
67 Read data from in_. |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
68 |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
69 Requests for input are written to out in the following format: |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
70 channel identifier - 'I' for plain input, 'L' line based (1 byte) |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
71 how many bytes to send at most (unsigned int), |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
72 |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
73 The client replies with: |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
74 data length (unsigned int), 0 meaning EOF |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
75 data |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
76 """ |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
77 |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
78 maxchunksize = 4 * 1024 |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
79 |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
80 def __init__(self, in_, out, channel): |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
81 self.in_ = in_ |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
82 self.out = out |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
83 self.channel = channel |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
84 |
27415
f4ca33e33781
commandserver: implement name() to clarify channel is not a plain file
Yuya Nishihara <yuya@tcha.org>
parents:
27352
diff
changeset
|
85 @property |
f4ca33e33781
commandserver: implement name() to clarify channel is not a plain file
Yuya Nishihara <yuya@tcha.org>
parents:
27352
diff
changeset
|
86 def name(self): |
f4ca33e33781
commandserver: implement name() to clarify channel is not a plain file
Yuya Nishihara <yuya@tcha.org>
parents:
27352
diff
changeset
|
87 return '<%c-channel>' % self.channel |
f4ca33e33781
commandserver: implement name() to clarify channel is not a plain file
Yuya Nishihara <yuya@tcha.org>
parents:
27352
diff
changeset
|
88 |
14647
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
89 def read(self, size=-1): |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
90 if size < 0: |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
91 # if we need to consume all the clients input, ask for 4k chunks |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
92 # so the pipe doesn't fill up risking a deadlock |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
93 size = self.maxchunksize |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
94 s = self._read(size, self.channel) |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
95 buf = s |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
96 while s: |
14728
350dcd481410
cmdserver: fix read-loop string concatenation
Idan Kamara <idankk86@gmail.com>
parents:
14719
diff
changeset
|
97 s = self._read(size, self.channel) |
14647
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
98 buf += s |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
99 |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
100 return buf |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
101 else: |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
102 return self._read(size, self.channel) |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
103 |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
104 def _read(self, size, channel): |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
105 if not size: |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
106 return '' |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
107 assert size > 0 |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
108 |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
109 # tell the client we need at most size bytes |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
110 self.out.write(struct.pack('>cI', channel, size)) |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
111 self.out.flush() |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
112 |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
113 length = self.in_.read(4) |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
114 length = struct.unpack('>I', length)[0] |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
115 if not length: |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
116 return '' |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
117 else: |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
118 return self.in_.read(length) |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
119 |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
120 def readline(self, size=-1): |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
121 if size < 0: |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
122 size = self.maxchunksize |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
123 s = self._read(size, 'L') |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
124 buf = s |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
125 # keep asking for more until there's either no more or |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
126 # we got a full line |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
127 while s and s[-1] != '\n': |
14728
350dcd481410
cmdserver: fix read-loop string concatenation
Idan Kamara <idankk86@gmail.com>
parents:
14719
diff
changeset
|
128 s = self._read(size, 'L') |
14647
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
129 buf += s |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
130 |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
131 return buf |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
132 else: |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
133 return self._read(size, 'L') |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
134 |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
135 def __iter__(self): |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
136 return self |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
137 |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
138 def next(self): |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
139 l = self.readline() |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
140 if not l: |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
141 raise StopIteration |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
142 return l |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
143 |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
144 def __getattr__(self, attr): |
27915
5f2a308bac94
commandserver: drop tell() and seek() from channels (issue5049)
Yuya Nishihara <yuya@tcha.org>
parents:
27566
diff
changeset
|
145 if attr in ('isatty', 'fileno', 'tell', 'seek'): |
18174
56ef99fbd6f2
commandserver: clean up use of two-argument raise
Augie Fackler <raf@durin42.com>
parents:
17425
diff
changeset
|
146 raise AttributeError(attr) |
14647
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
147 return getattr(self.in_, attr) |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
148 |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
149 class server(object): |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
150 """ |
22990
a0e81aa94125
cmdserver: make server streams switchable
Yuya Nishihara <yuya@tcha.org>
parents:
22989
diff
changeset
|
151 Listens for commands on fin, runs them and writes the output on a channel |
a0e81aa94125
cmdserver: make server streams switchable
Yuya Nishihara <yuya@tcha.org>
parents:
22989
diff
changeset
|
152 based stream to fout. |
14647
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
153 """ |
22990
a0e81aa94125
cmdserver: make server streams switchable
Yuya Nishihara <yuya@tcha.org>
parents:
22989
diff
changeset
|
154 def __init__(self, ui, repo, fin, fout): |
14864
1b872599f39f
cmdserver: restore old working dir after dispatch when we have --cwd
Idan Kamara <idankk86@gmail.com>
parents:
14751
diff
changeset
|
155 self.cwd = os.getcwd() |
14647
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
156 |
25832
5857be01962e
commandserver: mark developer-only logging option
Matt Mackall <mpm@selenic.com>
parents:
25660
diff
changeset
|
157 # developer config: cmdserver.log |
14647
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
158 logpath = ui.config("cmdserver", "log", None) |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
159 if logpath: |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
160 global logfile |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
161 if logpath == '-': |
17425
e95ec38f86b0
fix wording and not-completely-trivial spelling errors and bad docstrings
Mads Kiilerich <mads@kiilerich.com>
parents:
16687
diff
changeset
|
162 # write log on a special 'd' (debug) channel |
22990
a0e81aa94125
cmdserver: make server streams switchable
Yuya Nishihara <yuya@tcha.org>
parents:
22989
diff
changeset
|
163 logfile = channeledoutput(fout, 'd') |
14647
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
164 else: |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
165 logfile = open(logpath, 'a') |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
166 |
20650
e811b93f2cb1
cmdserver: allow to start server without repository
Yuya Nishihara <yuya@tcha.org>
parents:
20631
diff
changeset
|
167 if repo: |
e811b93f2cb1
cmdserver: allow to start server without repository
Yuya Nishihara <yuya@tcha.org>
parents:
20631
diff
changeset
|
168 # the ui here is really the repo ui so take its baseui so we don't |
e811b93f2cb1
cmdserver: allow to start server without repository
Yuya Nishihara <yuya@tcha.org>
parents:
20631
diff
changeset
|
169 # end up with its local configuration |
e811b93f2cb1
cmdserver: allow to start server without repository
Yuya Nishihara <yuya@tcha.org>
parents:
20631
diff
changeset
|
170 self.ui = repo.baseui |
e811b93f2cb1
cmdserver: allow to start server without repository
Yuya Nishihara <yuya@tcha.org>
parents:
20631
diff
changeset
|
171 self.repo = repo |
e811b93f2cb1
cmdserver: allow to start server without repository
Yuya Nishihara <yuya@tcha.org>
parents:
20631
diff
changeset
|
172 self.repoui = repo.ui |
e811b93f2cb1
cmdserver: allow to start server without repository
Yuya Nishihara <yuya@tcha.org>
parents:
20631
diff
changeset
|
173 else: |
e811b93f2cb1
cmdserver: allow to start server without repository
Yuya Nishihara <yuya@tcha.org>
parents:
20631
diff
changeset
|
174 self.ui = ui |
e811b93f2cb1
cmdserver: allow to start server without repository
Yuya Nishihara <yuya@tcha.org>
parents:
20631
diff
changeset
|
175 self.repo = self.repoui = None |
14647
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
176 |
22990
a0e81aa94125
cmdserver: make server streams switchable
Yuya Nishihara <yuya@tcha.org>
parents:
22989
diff
changeset
|
177 self.cerr = channeledoutput(fout, 'e') |
a0e81aa94125
cmdserver: make server streams switchable
Yuya Nishihara <yuya@tcha.org>
parents:
22989
diff
changeset
|
178 self.cout = channeledoutput(fout, 'o') |
a0e81aa94125
cmdserver: make server streams switchable
Yuya Nishihara <yuya@tcha.org>
parents:
22989
diff
changeset
|
179 self.cin = channeledinput(fin, fout, 'I') |
a0e81aa94125
cmdserver: make server streams switchable
Yuya Nishihara <yuya@tcha.org>
parents:
22989
diff
changeset
|
180 self.cresult = channeledoutput(fout, 'r') |
14647
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
181 |
22990
a0e81aa94125
cmdserver: make server streams switchable
Yuya Nishihara <yuya@tcha.org>
parents:
22989
diff
changeset
|
182 self.client = fin |
14647
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
183 |
29512
538d0003c9e0
commandserver: promote .cleanup() hook from chgserver
Yuya Nishihara <yuya@tcha.org>
parents:
29511
diff
changeset
|
184 def cleanup(self): |
538d0003c9e0
commandserver: promote .cleanup() hook from chgserver
Yuya Nishihara <yuya@tcha.org>
parents:
29511
diff
changeset
|
185 """release and restore resources taken during server session""" |
538d0003c9e0
commandserver: promote .cleanup() hook from chgserver
Yuya Nishihara <yuya@tcha.org>
parents:
29511
diff
changeset
|
186 pass |
538d0003c9e0
commandserver: promote .cleanup() hook from chgserver
Yuya Nishihara <yuya@tcha.org>
parents:
29511
diff
changeset
|
187 |
14647
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
188 def _read(self, size): |
14706
5fd5dd9a610a
cmdserver: don't raise EOFError when trying to read 0 bytes from the client
Idan Kamara <idankk86@gmail.com>
parents:
14647
diff
changeset
|
189 if not size: |
5fd5dd9a610a
cmdserver: don't raise EOFError when trying to read 0 bytes from the client
Idan Kamara <idankk86@gmail.com>
parents:
14647
diff
changeset
|
190 return '' |
5fd5dd9a610a
cmdserver: don't raise EOFError when trying to read 0 bytes from the client
Idan Kamara <idankk86@gmail.com>
parents:
14647
diff
changeset
|
191 |
14647
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
192 data = self.client.read(size) |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
193 |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
194 # is the other end closed? |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
195 if not data: |
16687
e34106fa0dc3
cleanup: "raise SomeException()" -> "raise SomeException"
Brodie Rao <brodie@sf.io>
parents:
16683
diff
changeset
|
196 raise EOFError |
14647
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
197 |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
198 return data |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
199 |
28156
75f586a1bf55
commandserver: add _readstr and _readlist
Jun Wu <quark@fb.com>
parents:
28027
diff
changeset
|
200 def _readstr(self): |
75f586a1bf55
commandserver: add _readstr and _readlist
Jun Wu <quark@fb.com>
parents:
28027
diff
changeset
|
201 """read a string from the channel |
75f586a1bf55
commandserver: add _readstr and _readlist
Jun Wu <quark@fb.com>
parents:
28027
diff
changeset
|
202 |
75f586a1bf55
commandserver: add _readstr and _readlist
Jun Wu <quark@fb.com>
parents:
28027
diff
changeset
|
203 format: |
75f586a1bf55
commandserver: add _readstr and _readlist
Jun Wu <quark@fb.com>
parents:
28027
diff
changeset
|
204 data length (uint32), data |
75f586a1bf55
commandserver: add _readstr and _readlist
Jun Wu <quark@fb.com>
parents:
28027
diff
changeset
|
205 """ |
75f586a1bf55
commandserver: add _readstr and _readlist
Jun Wu <quark@fb.com>
parents:
28027
diff
changeset
|
206 length = struct.unpack('>I', self._read(4))[0] |
75f586a1bf55
commandserver: add _readstr and _readlist
Jun Wu <quark@fb.com>
parents:
28027
diff
changeset
|
207 if not length: |
75f586a1bf55
commandserver: add _readstr and _readlist
Jun Wu <quark@fb.com>
parents:
28027
diff
changeset
|
208 return '' |
75f586a1bf55
commandserver: add _readstr and _readlist
Jun Wu <quark@fb.com>
parents:
28027
diff
changeset
|
209 return self._read(length) |
75f586a1bf55
commandserver: add _readstr and _readlist
Jun Wu <quark@fb.com>
parents:
28027
diff
changeset
|
210 |
75f586a1bf55
commandserver: add _readstr and _readlist
Jun Wu <quark@fb.com>
parents:
28027
diff
changeset
|
211 def _readlist(self): |
75f586a1bf55
commandserver: add _readstr and _readlist
Jun Wu <quark@fb.com>
parents:
28027
diff
changeset
|
212 """read a list of NULL separated strings from the channel""" |
75f586a1bf55
commandserver: add _readstr and _readlist
Jun Wu <quark@fb.com>
parents:
28027
diff
changeset
|
213 s = self._readstr() |
75f586a1bf55
commandserver: add _readstr and _readlist
Jun Wu <quark@fb.com>
parents:
28027
diff
changeset
|
214 if s: |
75f586a1bf55
commandserver: add _readstr and _readlist
Jun Wu <quark@fb.com>
parents:
28027
diff
changeset
|
215 return s.split('\0') |
75f586a1bf55
commandserver: add _readstr and _readlist
Jun Wu <quark@fb.com>
parents:
28027
diff
changeset
|
216 else: |
75f586a1bf55
commandserver: add _readstr and _readlist
Jun Wu <quark@fb.com>
parents:
28027
diff
changeset
|
217 return [] |
75f586a1bf55
commandserver: add _readstr and _readlist
Jun Wu <quark@fb.com>
parents:
28027
diff
changeset
|
218 |
14647
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
219 def runcommand(self): |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
220 """ reads a list of \0 terminated arguments, executes |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
221 and writes the return code to the result channel """ |
27352
9fd8f1552369
commandserver: cut import cycle by itself
Yuya Nishihara <yuya@tcha.org>
parents:
27351
diff
changeset
|
222 from . import dispatch # avoid cycle |
14647
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
223 |
28157 | 224 args = self._readlist() |
14647
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
225 |
14750
f5f97a0f983f
cmdserver: copy repo.ui before running commands
Idan Kamara <idankk86@gmail.com>
parents:
14728
diff
changeset
|
226 # copy the uis so changes (e.g. --config or --verbose) don't |
f5f97a0f983f
cmdserver: copy repo.ui before running commands
Idan Kamara <idankk86@gmail.com>
parents:
14728
diff
changeset
|
227 # persist between requests |
14751
712954a67be3
cmdserver: assign repo.baseui before running commands
Idan Kamara <idankk86@gmail.com>
parents:
14750
diff
changeset
|
228 copiedui = self.ui.copy() |
21195
9336bc7dca8e
cmdserver: forcibly use L channel to read password input (issue3161)
Yuya Nishihara <yuya@tcha.org>
parents:
20650
diff
changeset
|
229 uis = [copiedui] |
20650
e811b93f2cb1
cmdserver: allow to start server without repository
Yuya Nishihara <yuya@tcha.org>
parents:
20631
diff
changeset
|
230 if self.repo: |
e811b93f2cb1
cmdserver: allow to start server without repository
Yuya Nishihara <yuya@tcha.org>
parents:
20631
diff
changeset
|
231 self.repo.baseui = copiedui |
e811b93f2cb1
cmdserver: allow to start server without repository
Yuya Nishihara <yuya@tcha.org>
parents:
20631
diff
changeset
|
232 # clone ui without using ui.copy because this is protected |
e811b93f2cb1
cmdserver: allow to start server without repository
Yuya Nishihara <yuya@tcha.org>
parents:
20631
diff
changeset
|
233 repoui = self.repoui.__class__(self.repoui) |
e811b93f2cb1
cmdserver: allow to start server without repository
Yuya Nishihara <yuya@tcha.org>
parents:
20631
diff
changeset
|
234 repoui.copy = copiedui.copy # redo copy protection |
21195
9336bc7dca8e
cmdserver: forcibly use L channel to read password input (issue3161)
Yuya Nishihara <yuya@tcha.org>
parents:
20650
diff
changeset
|
235 uis.append(repoui) |
20650
e811b93f2cb1
cmdserver: allow to start server without repository
Yuya Nishihara <yuya@tcha.org>
parents:
20631
diff
changeset
|
236 self.repo.ui = self.repo.dirstate._ui = repoui |
e811b93f2cb1
cmdserver: allow to start server without repository
Yuya Nishihara <yuya@tcha.org>
parents:
20631
diff
changeset
|
237 self.repo.invalidateall() |
14751
712954a67be3
cmdserver: assign repo.baseui before running commands
Idan Kamara <idankk86@gmail.com>
parents:
14750
diff
changeset
|
238 |
21195
9336bc7dca8e
cmdserver: forcibly use L channel to read password input (issue3161)
Yuya Nishihara <yuya@tcha.org>
parents:
20650
diff
changeset
|
239 for ui in uis: |
29366
d269e7db2f55
ui: provide official way to reset internal state per command
Yuya Nishihara <yuya@tcha.org>
parents:
28511
diff
changeset
|
240 ui.resetstate() |
27565
e7937438e3f7
commandserver: do not set nontty flag if channel is replaced by a real file
Yuya Nishihara <yuya@tcha.org>
parents:
27415
diff
changeset
|
241 # any kind of interaction must use server channels, but chg may |
e7937438e3f7
commandserver: do not set nontty flag if channel is replaced by a real file
Yuya Nishihara <yuya@tcha.org>
parents:
27415
diff
changeset
|
242 # replace channels by fully functional tty files. so nontty is |
e7937438e3f7
commandserver: do not set nontty flag if channel is replaced by a real file
Yuya Nishihara <yuya@tcha.org>
parents:
27415
diff
changeset
|
243 # enforced only if cin is a channel. |
e7937438e3f7
commandserver: do not set nontty flag if channel is replaced by a real file
Yuya Nishihara <yuya@tcha.org>
parents:
27415
diff
changeset
|
244 if not util.safehasattr(self.cin, 'fileno'): |
e7937438e3f7
commandserver: do not set nontty flag if channel is replaced by a real file
Yuya Nishihara <yuya@tcha.org>
parents:
27415
diff
changeset
|
245 ui.setconfig('ui', 'nontty', 'true', 'commandserver') |
21195
9336bc7dca8e
cmdserver: forcibly use L channel to read password input (issue3161)
Yuya Nishihara <yuya@tcha.org>
parents:
20650
diff
changeset
|
246 |
14864
1b872599f39f
cmdserver: restore old working dir after dispatch when we have --cwd
Idan Kamara <idankk86@gmail.com>
parents:
14751
diff
changeset
|
247 req = dispatch.request(args[:], copiedui, self.repo, self.cin, |
14647
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
248 self.cout, self.cerr) |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
249 |
20631
5d4606bec54c
cmdserver: mask return code of runcommand in the same way as dispatch.run
Yuya Nishihara <yuya@tcha.org>
parents:
20627
diff
changeset
|
250 ret = (dispatch.dispatch(req) or 0) & 255 # might return None |
14647
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
251 |
14864
1b872599f39f
cmdserver: restore old working dir after dispatch when we have --cwd
Idan Kamara <idankk86@gmail.com>
parents:
14751
diff
changeset
|
252 # restore old cwd |
1b872599f39f
cmdserver: restore old working dir after dispatch when we have --cwd
Idan Kamara <idankk86@gmail.com>
parents:
14751
diff
changeset
|
253 if '--cwd' in args: |
1b872599f39f
cmdserver: restore old working dir after dispatch when we have --cwd
Idan Kamara <idankk86@gmail.com>
parents:
14751
diff
changeset
|
254 os.chdir(self.cwd) |
1b872599f39f
cmdserver: restore old working dir after dispatch when we have --cwd
Idan Kamara <idankk86@gmail.com>
parents:
14751
diff
changeset
|
255 |
14647
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
256 self.cresult.write(struct.pack('>i', int(ret))) |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
257 |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
258 def getencoding(self): |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
259 """ writes the current encoding to the result channel """ |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
260 self.cresult.write(encoding.encoding) |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
261 |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
262 def serveone(self): |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
263 cmd = self.client.readline()[:-1] |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
264 if cmd: |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
265 handler = self.capabilities.get(cmd) |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
266 if handler: |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
267 handler(self) |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
268 else: |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
269 # clients are expected to check what commands are supported by |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
270 # looking at the servers capabilities |
26587
56b2bcea2529
error: get Abort from 'error' instead of 'util'
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
25832
diff
changeset
|
271 raise error.Abort(_('unknown command %s') % cmd) |
14647
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
272 |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
273 return cmd != '' |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
274 |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
275 capabilities = {'runcommand' : runcommand, |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
276 'getencoding' : getencoding} |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
277 |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
278 def serve(self): |
18359
4b09e6f7d7de
commandserver: report capabilities sorted
Mads Kiilerich <mads@kiilerich.com>
parents:
18174
diff
changeset
|
279 hellomsg = 'capabilities: ' + ' '.join(sorted(self.capabilities)) |
14719
c19de7f32961
cmdserver: write the hello message as one chunk on the 'o' channel
Idan Kamara <idankk86@gmail.com>
parents:
14707
diff
changeset
|
280 hellomsg += '\n' |
c19de7f32961
cmdserver: write the hello message as one chunk on the 'o' channel
Idan Kamara <idankk86@gmail.com>
parents:
14707
diff
changeset
|
281 hellomsg += 'encoding: ' + encoding.encoding |
23036
19f5273c9f3e
cmdserver: include pid of server handling requests in hello message
Yuya Nishihara <yuya@tcha.org>
parents:
22994
diff
changeset
|
282 hellomsg += '\n' |
28027
14033c5dd261
util: enable getpid to be replaced
timeless <timeless@mozdev.org>
parents:
27915
diff
changeset
|
283 hellomsg += 'pid: %d' % util.getpid() |
29580
ee8186457516
commandserver: send pgid in hello message
Jun Wu <quark@fb.com>
parents:
29548
diff
changeset
|
284 if util.safehasattr(os, 'getpgid'): |
ee8186457516
commandserver: send pgid in hello message
Jun Wu <quark@fb.com>
parents:
29548
diff
changeset
|
285 hellomsg += '\n' |
ee8186457516
commandserver: send pgid in hello message
Jun Wu <quark@fb.com>
parents:
29548
diff
changeset
|
286 hellomsg += 'pgid: %d' % os.getpgid(0) |
14719
c19de7f32961
cmdserver: write the hello message as one chunk on the 'o' channel
Idan Kamara <idankk86@gmail.com>
parents:
14707
diff
changeset
|
287 |
c19de7f32961
cmdserver: write the hello message as one chunk on the 'o' channel
Idan Kamara <idankk86@gmail.com>
parents:
14707
diff
changeset
|
288 # write the hello msg in -one- chunk |
c19de7f32961
cmdserver: write the hello message as one chunk on the 'o' channel
Idan Kamara <idankk86@gmail.com>
parents:
14707
diff
changeset
|
289 self.cout.write(hellomsg) |
14647
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
290 |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
291 try: |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
292 while self.serveone(): |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
293 pass |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
294 except EOFError: |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
295 # we'll get here if the client disconnected while we were reading |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
296 # its request |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
297 return 1 |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
298 |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
299 return 0 |
22988
32b77aba2772
cmdserver: wrap 'pipe' mode server by service object
Yuya Nishihara <yuya@tcha.org>
parents:
22563
diff
changeset
|
300 |
23324
69f86b937035
cmdserver: protect pipe server streams against corruption caused by direct io
Yuya Nishihara <yuya@tcha.org>
parents:
23323
diff
changeset
|
301 def _protectio(ui): |
69f86b937035
cmdserver: protect pipe server streams against corruption caused by direct io
Yuya Nishihara <yuya@tcha.org>
parents:
23323
diff
changeset
|
302 """ duplicates streams and redirect original to null if ui uses stdio """ |
69f86b937035
cmdserver: protect pipe server streams against corruption caused by direct io
Yuya Nishihara <yuya@tcha.org>
parents:
23323
diff
changeset
|
303 ui.flush() |
69f86b937035
cmdserver: protect pipe server streams against corruption caused by direct io
Yuya Nishihara <yuya@tcha.org>
parents:
23323
diff
changeset
|
304 newfiles = [] |
69f86b937035
cmdserver: protect pipe server streams against corruption caused by direct io
Yuya Nishihara <yuya@tcha.org>
parents:
23323
diff
changeset
|
305 nullfd = os.open(os.devnull, os.O_RDWR) |
30482
39d13b8c101d
py3: bulk replace sys.stdin/out/err by util's
Yuya Nishihara <yuya@tcha.org>
parents:
30277
diff
changeset
|
306 for f, sysf, mode in [(ui.fin, util.stdin, 'rb'), |
39d13b8c101d
py3: bulk replace sys.stdin/out/err by util's
Yuya Nishihara <yuya@tcha.org>
parents:
30277
diff
changeset
|
307 (ui.fout, util.stdout, 'wb')]: |
23324
69f86b937035
cmdserver: protect pipe server streams against corruption caused by direct io
Yuya Nishihara <yuya@tcha.org>
parents:
23323
diff
changeset
|
308 if f is sysf: |
69f86b937035
cmdserver: protect pipe server streams against corruption caused by direct io
Yuya Nishihara <yuya@tcha.org>
parents:
23323
diff
changeset
|
309 newfd = os.dup(f.fileno()) |
69f86b937035
cmdserver: protect pipe server streams against corruption caused by direct io
Yuya Nishihara <yuya@tcha.org>
parents:
23323
diff
changeset
|
310 os.dup2(nullfd, f.fileno()) |
69f86b937035
cmdserver: protect pipe server streams against corruption caused by direct io
Yuya Nishihara <yuya@tcha.org>
parents:
23323
diff
changeset
|
311 f = os.fdopen(newfd, mode) |
69f86b937035
cmdserver: protect pipe server streams against corruption caused by direct io
Yuya Nishihara <yuya@tcha.org>
parents:
23323
diff
changeset
|
312 newfiles.append(f) |
69f86b937035
cmdserver: protect pipe server streams against corruption caused by direct io
Yuya Nishihara <yuya@tcha.org>
parents:
23323
diff
changeset
|
313 os.close(nullfd) |
69f86b937035
cmdserver: protect pipe server streams against corruption caused by direct io
Yuya Nishihara <yuya@tcha.org>
parents:
23323
diff
changeset
|
314 return tuple(newfiles) |
69f86b937035
cmdserver: protect pipe server streams against corruption caused by direct io
Yuya Nishihara <yuya@tcha.org>
parents:
23323
diff
changeset
|
315 |
69f86b937035
cmdserver: protect pipe server streams against corruption caused by direct io
Yuya Nishihara <yuya@tcha.org>
parents:
23323
diff
changeset
|
316 def _restoreio(ui, fin, fout): |
69f86b937035
cmdserver: protect pipe server streams against corruption caused by direct io
Yuya Nishihara <yuya@tcha.org>
parents:
23323
diff
changeset
|
317 """ restores streams from duplicated ones """ |
69f86b937035
cmdserver: protect pipe server streams against corruption caused by direct io
Yuya Nishihara <yuya@tcha.org>
parents:
23323
diff
changeset
|
318 ui.flush() |
69f86b937035
cmdserver: protect pipe server streams against corruption caused by direct io
Yuya Nishihara <yuya@tcha.org>
parents:
23323
diff
changeset
|
319 for f, uif in [(fin, ui.fin), (fout, ui.fout)]: |
69f86b937035
cmdserver: protect pipe server streams against corruption caused by direct io
Yuya Nishihara <yuya@tcha.org>
parents:
23323
diff
changeset
|
320 if f is not uif: |
69f86b937035
cmdserver: protect pipe server streams against corruption caused by direct io
Yuya Nishihara <yuya@tcha.org>
parents:
23323
diff
changeset
|
321 os.dup2(f.fileno(), uif.fileno()) |
69f86b937035
cmdserver: protect pipe server streams against corruption caused by direct io
Yuya Nishihara <yuya@tcha.org>
parents:
23323
diff
changeset
|
322 f.close() |
69f86b937035
cmdserver: protect pipe server streams against corruption caused by direct io
Yuya Nishihara <yuya@tcha.org>
parents:
23323
diff
changeset
|
323 |
22988
32b77aba2772
cmdserver: wrap 'pipe' mode server by service object
Yuya Nishihara <yuya@tcha.org>
parents:
22563
diff
changeset
|
324 class pipeservice(object): |
32b77aba2772
cmdserver: wrap 'pipe' mode server by service object
Yuya Nishihara <yuya@tcha.org>
parents:
22563
diff
changeset
|
325 def __init__(self, ui, repo, opts): |
23323
bc374458688b
cmdserver: postpone creation of pipe server until run()
Yuya Nishihara <yuya@tcha.org>
parents:
23322
diff
changeset
|
326 self.ui = ui |
bc374458688b
cmdserver: postpone creation of pipe server until run()
Yuya Nishihara <yuya@tcha.org>
parents:
23322
diff
changeset
|
327 self.repo = repo |
22988
32b77aba2772
cmdserver: wrap 'pipe' mode server by service object
Yuya Nishihara <yuya@tcha.org>
parents:
22563
diff
changeset
|
328 |
32b77aba2772
cmdserver: wrap 'pipe' mode server by service object
Yuya Nishihara <yuya@tcha.org>
parents:
22563
diff
changeset
|
329 def init(self): |
32b77aba2772
cmdserver: wrap 'pipe' mode server by service object
Yuya Nishihara <yuya@tcha.org>
parents:
22563
diff
changeset
|
330 pass |
32b77aba2772
cmdserver: wrap 'pipe' mode server by service object
Yuya Nishihara <yuya@tcha.org>
parents:
22563
diff
changeset
|
331 |
32b77aba2772
cmdserver: wrap 'pipe' mode server by service object
Yuya Nishihara <yuya@tcha.org>
parents:
22563
diff
changeset
|
332 def run(self): |
23323
bc374458688b
cmdserver: postpone creation of pipe server until run()
Yuya Nishihara <yuya@tcha.org>
parents:
23322
diff
changeset
|
333 ui = self.ui |
23324
69f86b937035
cmdserver: protect pipe server streams against corruption caused by direct io
Yuya Nishihara <yuya@tcha.org>
parents:
23323
diff
changeset
|
334 # redirect stdio to null device so that broken extensions or in-process |
69f86b937035
cmdserver: protect pipe server streams against corruption caused by direct io
Yuya Nishihara <yuya@tcha.org>
parents:
23323
diff
changeset
|
335 # hooks will never cause corruption of channel protocol. |
69f86b937035
cmdserver: protect pipe server streams against corruption caused by direct io
Yuya Nishihara <yuya@tcha.org>
parents:
23323
diff
changeset
|
336 fin, fout = _protectio(ui) |
69f86b937035
cmdserver: protect pipe server streams against corruption caused by direct io
Yuya Nishihara <yuya@tcha.org>
parents:
23323
diff
changeset
|
337 try: |
69f86b937035
cmdserver: protect pipe server streams against corruption caused by direct io
Yuya Nishihara <yuya@tcha.org>
parents:
23323
diff
changeset
|
338 sv = server(ui, self.repo, fin, fout) |
69f86b937035
cmdserver: protect pipe server streams against corruption caused by direct io
Yuya Nishihara <yuya@tcha.org>
parents:
23323
diff
changeset
|
339 return sv.serve() |
69f86b937035
cmdserver: protect pipe server streams against corruption caused by direct io
Yuya Nishihara <yuya@tcha.org>
parents:
23323
diff
changeset
|
340 finally: |
29512
538d0003c9e0
commandserver: promote .cleanup() hook from chgserver
Yuya Nishihara <yuya@tcha.org>
parents:
29511
diff
changeset
|
341 sv.cleanup() |
23324
69f86b937035
cmdserver: protect pipe server streams against corruption caused by direct io
Yuya Nishihara <yuya@tcha.org>
parents:
23323
diff
changeset
|
342 _restoreio(ui, fin, fout) |
22989
dc8803ce3dfe
cmdserver: switch service objects by mode
Yuya Nishihara <yuya@tcha.org>
parents:
22988
diff
changeset
|
343 |
29586
42cdba9cfee4
commandserver: separate initialization and cleanup of forked process
Yuya Nishihara <yuya@tcha.org>
parents:
29585
diff
changeset
|
344 def _initworkerprocess(): |
29609
591c3badff2e
commandserver: update comment about setpgid
Jun Wu <quark@fb.com>
parents:
29588
diff
changeset
|
345 # use a different process group from the master process, in order to: |
591c3badff2e
commandserver: update comment about setpgid
Jun Wu <quark@fb.com>
parents:
29588
diff
changeset
|
346 # 1. make the current process group no longer "orphaned" (because the |
591c3badff2e
commandserver: update comment about setpgid
Jun Wu <quark@fb.com>
parents:
29588
diff
changeset
|
347 # parent of this process is in a different process group while |
591c3badff2e
commandserver: update comment about setpgid
Jun Wu <quark@fb.com>
parents:
29588
diff
changeset
|
348 # remains in a same session) |
591c3badff2e
commandserver: update comment about setpgid
Jun Wu <quark@fb.com>
parents:
29588
diff
changeset
|
349 # according to POSIX 2.2.2.52, orphaned process group will ignore |
591c3badff2e
commandserver: update comment about setpgid
Jun Wu <quark@fb.com>
parents:
29588
diff
changeset
|
350 # terminal-generated stop signals like SIGTSTP (Ctrl+Z), which will |
591c3badff2e
commandserver: update comment about setpgid
Jun Wu <quark@fb.com>
parents:
29588
diff
changeset
|
351 # cause trouble for things like ncurses. |
591c3badff2e
commandserver: update comment about setpgid
Jun Wu <quark@fb.com>
parents:
29588
diff
changeset
|
352 # 2. the client can use kill(-pgid, sig) to simulate terminal-generated |
591c3badff2e
commandserver: update comment about setpgid
Jun Wu <quark@fb.com>
parents:
29588
diff
changeset
|
353 # SIGINT (Ctrl+C) and process-exit-generated SIGHUP. our child |
591c3badff2e
commandserver: update comment about setpgid
Jun Wu <quark@fb.com>
parents:
29588
diff
changeset
|
354 # processes like ssh will be killed properly, without affecting |
591c3badff2e
commandserver: update comment about setpgid
Jun Wu <quark@fb.com>
parents:
29588
diff
changeset
|
355 # unrelated processes. |
29585
6ed452d0f1f1
commandserver: unindent superfluous "if True" blocks
Yuya Nishihara <yuya@tcha.org>
parents:
29580
diff
changeset
|
356 os.setpgid(0, 0) |
6ed452d0f1f1
commandserver: unindent superfluous "if True" blocks
Yuya Nishihara <yuya@tcha.org>
parents:
29580
diff
changeset
|
357 # change random state otherwise forked request handlers would have a |
6ed452d0f1f1
commandserver: unindent superfluous "if True" blocks
Yuya Nishihara <yuya@tcha.org>
parents:
29580
diff
changeset
|
358 # same state inherited from parent. |
6ed452d0f1f1
commandserver: unindent superfluous "if True" blocks
Yuya Nishihara <yuya@tcha.org>
parents:
29580
diff
changeset
|
359 random.seed() |
29542
6011ad3b0a42
commandserver: manually create file objects from socket
Yuya Nishihara <yuya@tcha.org>
parents:
29532
diff
changeset
|
360 |
29586
42cdba9cfee4
commandserver: separate initialization and cleanup of forked process
Yuya Nishihara <yuya@tcha.org>
parents:
29585
diff
changeset
|
361 def _serverequest(ui, repo, conn, createcmdserver): |
29585
6ed452d0f1f1
commandserver: unindent superfluous "if True" blocks
Yuya Nishihara <yuya@tcha.org>
parents:
29580
diff
changeset
|
362 fin = conn.makefile('rb') |
6ed452d0f1f1
commandserver: unindent superfluous "if True" blocks
Yuya Nishihara <yuya@tcha.org>
parents:
29580
diff
changeset
|
363 fout = conn.makefile('wb') |
6ed452d0f1f1
commandserver: unindent superfluous "if True" blocks
Yuya Nishihara <yuya@tcha.org>
parents:
29580
diff
changeset
|
364 sv = None |
6ed452d0f1f1
commandserver: unindent superfluous "if True" blocks
Yuya Nishihara <yuya@tcha.org>
parents:
29580
diff
changeset
|
365 try: |
6ed452d0f1f1
commandserver: unindent superfluous "if True" blocks
Yuya Nishihara <yuya@tcha.org>
parents:
29580
diff
changeset
|
366 sv = createcmdserver(repo, conn, fin, fout) |
22994
840be5ca03e1
cmdserver: add service that listens on unix domain socket and forks process
Yuya Nishihara <yuya@tcha.org>
parents:
22990
diff
changeset
|
367 try: |
29585
6ed452d0f1f1
commandserver: unindent superfluous "if True" blocks
Yuya Nishihara <yuya@tcha.org>
parents:
29580
diff
changeset
|
368 sv.serve() |
6ed452d0f1f1
commandserver: unindent superfluous "if True" blocks
Yuya Nishihara <yuya@tcha.org>
parents:
29580
diff
changeset
|
369 # handle exceptions that may be raised by command server. most of |
6ed452d0f1f1
commandserver: unindent superfluous "if True" blocks
Yuya Nishihara <yuya@tcha.org>
parents:
29580
diff
changeset
|
370 # known exceptions are caught by dispatch. |
6ed452d0f1f1
commandserver: unindent superfluous "if True" blocks
Yuya Nishihara <yuya@tcha.org>
parents:
29580
diff
changeset
|
371 except error.Abort as inst: |
6ed452d0f1f1
commandserver: unindent superfluous "if True" blocks
Yuya Nishihara <yuya@tcha.org>
parents:
29580
diff
changeset
|
372 ui.warn(_('abort: %s\n') % inst) |
6ed452d0f1f1
commandserver: unindent superfluous "if True" blocks
Yuya Nishihara <yuya@tcha.org>
parents:
29580
diff
changeset
|
373 except IOError as inst: |
6ed452d0f1f1
commandserver: unindent superfluous "if True" blocks
Yuya Nishihara <yuya@tcha.org>
parents:
29580
diff
changeset
|
374 if inst.errno != errno.EPIPE: |
6ed452d0f1f1
commandserver: unindent superfluous "if True" blocks
Yuya Nishihara <yuya@tcha.org>
parents:
29580
diff
changeset
|
375 raise |
6ed452d0f1f1
commandserver: unindent superfluous "if True" blocks
Yuya Nishihara <yuya@tcha.org>
parents:
29580
diff
changeset
|
376 except KeyboardInterrupt: |
6ed452d0f1f1
commandserver: unindent superfluous "if True" blocks
Yuya Nishihara <yuya@tcha.org>
parents:
29580
diff
changeset
|
377 pass |
29513
e5b4d79a9140
commandserver: backport handling of forking server from chgserver
Yuya Nishihara <yuya@tcha.org>
parents:
29512
diff
changeset
|
378 finally: |
29585
6ed452d0f1f1
commandserver: unindent superfluous "if True" blocks
Yuya Nishihara <yuya@tcha.org>
parents:
29580
diff
changeset
|
379 sv.cleanup() |
6ed452d0f1f1
commandserver: unindent superfluous "if True" blocks
Yuya Nishihara <yuya@tcha.org>
parents:
29580
diff
changeset
|
380 except: # re-raises |
6ed452d0f1f1
commandserver: unindent superfluous "if True" blocks
Yuya Nishihara <yuya@tcha.org>
parents:
29580
diff
changeset
|
381 # also write traceback to error channel. otherwise client cannot |
6ed452d0f1f1
commandserver: unindent superfluous "if True" blocks
Yuya Nishihara <yuya@tcha.org>
parents:
29580
diff
changeset
|
382 # see it because it is written to server's stderr by default. |
6ed452d0f1f1
commandserver: unindent superfluous "if True" blocks
Yuya Nishihara <yuya@tcha.org>
parents:
29580
diff
changeset
|
383 if sv: |
6ed452d0f1f1
commandserver: unindent superfluous "if True" blocks
Yuya Nishihara <yuya@tcha.org>
parents:
29580
diff
changeset
|
384 cerr = sv.cerr |
6ed452d0f1f1
commandserver: unindent superfluous "if True" blocks
Yuya Nishihara <yuya@tcha.org>
parents:
29580
diff
changeset
|
385 else: |
6ed452d0f1f1
commandserver: unindent superfluous "if True" blocks
Yuya Nishihara <yuya@tcha.org>
parents:
29580
diff
changeset
|
386 cerr = channeledoutput(fout, 'e') |
6ed452d0f1f1
commandserver: unindent superfluous "if True" blocks
Yuya Nishihara <yuya@tcha.org>
parents:
29580
diff
changeset
|
387 traceback.print_exc(file=cerr) |
6ed452d0f1f1
commandserver: unindent superfluous "if True" blocks
Yuya Nishihara <yuya@tcha.org>
parents:
29580
diff
changeset
|
388 raise |
6ed452d0f1f1
commandserver: unindent superfluous "if True" blocks
Yuya Nishihara <yuya@tcha.org>
parents:
29580
diff
changeset
|
389 finally: |
6ed452d0f1f1
commandserver: unindent superfluous "if True" blocks
Yuya Nishihara <yuya@tcha.org>
parents:
29580
diff
changeset
|
390 fin.close() |
6ed452d0f1f1
commandserver: unindent superfluous "if True" blocks
Yuya Nishihara <yuya@tcha.org>
parents:
29580
diff
changeset
|
391 try: |
6ed452d0f1f1
commandserver: unindent superfluous "if True" blocks
Yuya Nishihara <yuya@tcha.org>
parents:
29580
diff
changeset
|
392 fout.close() # implicit flush() may cause another EPIPE |
6ed452d0f1f1
commandserver: unindent superfluous "if True" blocks
Yuya Nishihara <yuya@tcha.org>
parents:
29580
diff
changeset
|
393 except IOError as inst: |
6ed452d0f1f1
commandserver: unindent superfluous "if True" blocks
Yuya Nishihara <yuya@tcha.org>
parents:
29580
diff
changeset
|
394 if inst.errno != errno.EPIPE: |
6ed452d0f1f1
commandserver: unindent superfluous "if True" blocks
Yuya Nishihara <yuya@tcha.org>
parents:
29580
diff
changeset
|
395 raise |
22994
840be5ca03e1
cmdserver: add service that listens on unix domain socket and forks process
Yuya Nishihara <yuya@tcha.org>
parents:
22990
diff
changeset
|
396 |
29544
024e8f82f3de
commandserver: add new forking server implemented without using SocketServer
Yuya Nishihara <yuya@tcha.org>
parents:
29543
diff
changeset
|
397 class unixservicehandler(object): |
024e8f82f3de
commandserver: add new forking server implemented without using SocketServer
Yuya Nishihara <yuya@tcha.org>
parents:
29543
diff
changeset
|
398 """Set of pluggable operations for unix-mode services |
024e8f82f3de
commandserver: add new forking server implemented without using SocketServer
Yuya Nishihara <yuya@tcha.org>
parents:
29543
diff
changeset
|
399 |
024e8f82f3de
commandserver: add new forking server implemented without using SocketServer
Yuya Nishihara <yuya@tcha.org>
parents:
29543
diff
changeset
|
400 Almost all methods except for createcmdserver() are called in the main |
024e8f82f3de
commandserver: add new forking server implemented without using SocketServer
Yuya Nishihara <yuya@tcha.org>
parents:
29543
diff
changeset
|
401 process. You can't pass mutable resource back from createcmdserver(). |
024e8f82f3de
commandserver: add new forking server implemented without using SocketServer
Yuya Nishihara <yuya@tcha.org>
parents:
29543
diff
changeset
|
402 """ |
024e8f82f3de
commandserver: add new forking server implemented without using SocketServer
Yuya Nishihara <yuya@tcha.org>
parents:
29543
diff
changeset
|
403 |
024e8f82f3de
commandserver: add new forking server implemented without using SocketServer
Yuya Nishihara <yuya@tcha.org>
parents:
29543
diff
changeset
|
404 pollinterval = None |
024e8f82f3de
commandserver: add new forking server implemented without using SocketServer
Yuya Nishihara <yuya@tcha.org>
parents:
29543
diff
changeset
|
405 |
024e8f82f3de
commandserver: add new forking server implemented without using SocketServer
Yuya Nishihara <yuya@tcha.org>
parents:
29543
diff
changeset
|
406 def __init__(self, ui): |
024e8f82f3de
commandserver: add new forking server implemented without using SocketServer
Yuya Nishihara <yuya@tcha.org>
parents:
29543
diff
changeset
|
407 self.ui = ui |
024e8f82f3de
commandserver: add new forking server implemented without using SocketServer
Yuya Nishihara <yuya@tcha.org>
parents:
29543
diff
changeset
|
408 |
024e8f82f3de
commandserver: add new forking server implemented without using SocketServer
Yuya Nishihara <yuya@tcha.org>
parents:
29543
diff
changeset
|
409 def bindsocket(self, sock, address): |
024e8f82f3de
commandserver: add new forking server implemented without using SocketServer
Yuya Nishihara <yuya@tcha.org>
parents:
29543
diff
changeset
|
410 util.bindunixsocket(sock, address) |
024e8f82f3de
commandserver: add new forking server implemented without using SocketServer
Yuya Nishihara <yuya@tcha.org>
parents:
29543
diff
changeset
|
411 |
024e8f82f3de
commandserver: add new forking server implemented without using SocketServer
Yuya Nishihara <yuya@tcha.org>
parents:
29543
diff
changeset
|
412 def unlinksocket(self, address): |
024e8f82f3de
commandserver: add new forking server implemented without using SocketServer
Yuya Nishihara <yuya@tcha.org>
parents:
29543
diff
changeset
|
413 os.unlink(address) |
024e8f82f3de
commandserver: add new forking server implemented without using SocketServer
Yuya Nishihara <yuya@tcha.org>
parents:
29543
diff
changeset
|
414 |
024e8f82f3de
commandserver: add new forking server implemented without using SocketServer
Yuya Nishihara <yuya@tcha.org>
parents:
29543
diff
changeset
|
415 def printbanner(self, address): |
024e8f82f3de
commandserver: add new forking server implemented without using SocketServer
Yuya Nishihara <yuya@tcha.org>
parents:
29543
diff
changeset
|
416 self.ui.status(_('listening at %s\n') % address) |
024e8f82f3de
commandserver: add new forking server implemented without using SocketServer
Yuya Nishihara <yuya@tcha.org>
parents:
29543
diff
changeset
|
417 self.ui.flush() # avoid buffering of status message |
024e8f82f3de
commandserver: add new forking server implemented without using SocketServer
Yuya Nishihara <yuya@tcha.org>
parents:
29543
diff
changeset
|
418 |
024e8f82f3de
commandserver: add new forking server implemented without using SocketServer
Yuya Nishihara <yuya@tcha.org>
parents:
29543
diff
changeset
|
419 def shouldexit(self): |
024e8f82f3de
commandserver: add new forking server implemented without using SocketServer
Yuya Nishihara <yuya@tcha.org>
parents:
29543
diff
changeset
|
420 """True if server should shut down; checked per pollinterval""" |
024e8f82f3de
commandserver: add new forking server implemented without using SocketServer
Yuya Nishihara <yuya@tcha.org>
parents:
29543
diff
changeset
|
421 return False |
024e8f82f3de
commandserver: add new forking server implemented without using SocketServer
Yuya Nishihara <yuya@tcha.org>
parents:
29543
diff
changeset
|
422 |
024e8f82f3de
commandserver: add new forking server implemented without using SocketServer
Yuya Nishihara <yuya@tcha.org>
parents:
29543
diff
changeset
|
423 def newconnection(self): |
024e8f82f3de
commandserver: add new forking server implemented without using SocketServer
Yuya Nishihara <yuya@tcha.org>
parents:
29543
diff
changeset
|
424 """Called when main process notices new connection""" |
024e8f82f3de
commandserver: add new forking server implemented without using SocketServer
Yuya Nishihara <yuya@tcha.org>
parents:
29543
diff
changeset
|
425 pass |
024e8f82f3de
commandserver: add new forking server implemented without using SocketServer
Yuya Nishihara <yuya@tcha.org>
parents:
29543
diff
changeset
|
426 |
024e8f82f3de
commandserver: add new forking server implemented without using SocketServer
Yuya Nishihara <yuya@tcha.org>
parents:
29543
diff
changeset
|
427 def createcmdserver(self, repo, conn, fin, fout): |
024e8f82f3de
commandserver: add new forking server implemented without using SocketServer
Yuya Nishihara <yuya@tcha.org>
parents:
29543
diff
changeset
|
428 """Create new command server instance; called in the process that |
024e8f82f3de
commandserver: add new forking server implemented without using SocketServer
Yuya Nishihara <yuya@tcha.org>
parents:
29543
diff
changeset
|
429 serves for the current connection""" |
024e8f82f3de
commandserver: add new forking server implemented without using SocketServer
Yuya Nishihara <yuya@tcha.org>
parents:
29543
diff
changeset
|
430 return server(self.ui, repo, fin, fout) |
024e8f82f3de
commandserver: add new forking server implemented without using SocketServer
Yuya Nishihara <yuya@tcha.org>
parents:
29543
diff
changeset
|
431 |
29548
9da1adc18639
commandserver: drop old unixservice implementation
Yuya Nishihara <yuya@tcha.org>
parents:
29544
diff
changeset
|
432 class unixforkingservice(object): |
22994
840be5ca03e1
cmdserver: add service that listens on unix domain socket and forks process
Yuya Nishihara <yuya@tcha.org>
parents:
22990
diff
changeset
|
433 """ |
840be5ca03e1
cmdserver: add service that listens on unix domain socket and forks process
Yuya Nishihara <yuya@tcha.org>
parents:
22990
diff
changeset
|
434 Listens on unix domain socket and forks server per connection |
840be5ca03e1
cmdserver: add service that listens on unix domain socket and forks process
Yuya Nishihara <yuya@tcha.org>
parents:
22990
diff
changeset
|
435 """ |
29548
9da1adc18639
commandserver: drop old unixservice implementation
Yuya Nishihara <yuya@tcha.org>
parents:
29544
diff
changeset
|
436 |
9da1adc18639
commandserver: drop old unixservice implementation
Yuya Nishihara <yuya@tcha.org>
parents:
29544
diff
changeset
|
437 def __init__(self, ui, repo, opts, handler=None): |
22994
840be5ca03e1
cmdserver: add service that listens on unix domain socket and forks process
Yuya Nishihara <yuya@tcha.org>
parents:
22990
diff
changeset
|
438 self.ui = ui |
840be5ca03e1
cmdserver: add service that listens on unix domain socket and forks process
Yuya Nishihara <yuya@tcha.org>
parents:
22990
diff
changeset
|
439 self.repo = repo |
840be5ca03e1
cmdserver: add service that listens on unix domain socket and forks process
Yuya Nishihara <yuya@tcha.org>
parents:
22990
diff
changeset
|
440 self.address = opts['address'] |
29548
9da1adc18639
commandserver: drop old unixservice implementation
Yuya Nishihara <yuya@tcha.org>
parents:
29544
diff
changeset
|
441 if not util.safehasattr(socket, 'AF_UNIX'): |
26587
56b2bcea2529
error: get Abort from 'error' instead of 'util'
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
25832
diff
changeset
|
442 raise error.Abort(_('unsupported platform')) |
22994
840be5ca03e1
cmdserver: add service that listens on unix domain socket and forks process
Yuya Nishihara <yuya@tcha.org>
parents:
22990
diff
changeset
|
443 if not self.address: |
26587
56b2bcea2529
error: get Abort from 'error' instead of 'util'
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
25832
diff
changeset
|
444 raise error.Abort(_('no socket path specified with --address')) |
29544
024e8f82f3de
commandserver: add new forking server implemented without using SocketServer
Yuya Nishihara <yuya@tcha.org>
parents:
29543
diff
changeset
|
445 self._servicehandler = handler or unixservicehandler(ui) |
024e8f82f3de
commandserver: add new forking server implemented without using SocketServer
Yuya Nishihara <yuya@tcha.org>
parents:
29543
diff
changeset
|
446 self._sock = None |
024e8f82f3de
commandserver: add new forking server implemented without using SocketServer
Yuya Nishihara <yuya@tcha.org>
parents:
29543
diff
changeset
|
447 self._oldsigchldhandler = None |
024e8f82f3de
commandserver: add new forking server implemented without using SocketServer
Yuya Nishihara <yuya@tcha.org>
parents:
29543
diff
changeset
|
448 self._workerpids = set() # updated by signal handler; do not iterate |
024e8f82f3de
commandserver: add new forking server implemented without using SocketServer
Yuya Nishihara <yuya@tcha.org>
parents:
29543
diff
changeset
|
449 |
024e8f82f3de
commandserver: add new forking server implemented without using SocketServer
Yuya Nishihara <yuya@tcha.org>
parents:
29543
diff
changeset
|
450 def init(self): |
024e8f82f3de
commandserver: add new forking server implemented without using SocketServer
Yuya Nishihara <yuya@tcha.org>
parents:
29543
diff
changeset
|
451 self._sock = socket.socket(socket.AF_UNIX) |
024e8f82f3de
commandserver: add new forking server implemented without using SocketServer
Yuya Nishihara <yuya@tcha.org>
parents:
29543
diff
changeset
|
452 self._servicehandler.bindsocket(self._sock, self.address) |
29588
1bb94666b9fc
commandserver: use SOMAXCONN as queue size of pending connections
Yuya Nishihara <yuya@tcha.org>
parents:
29587
diff
changeset
|
453 self._sock.listen(socket.SOMAXCONN) |
29544
024e8f82f3de
commandserver: add new forking server implemented without using SocketServer
Yuya Nishihara <yuya@tcha.org>
parents:
29543
diff
changeset
|
454 o = signal.signal(signal.SIGCHLD, self._sigchldhandler) |
024e8f82f3de
commandserver: add new forking server implemented without using SocketServer
Yuya Nishihara <yuya@tcha.org>
parents:
29543
diff
changeset
|
455 self._oldsigchldhandler = o |
024e8f82f3de
commandserver: add new forking server implemented without using SocketServer
Yuya Nishihara <yuya@tcha.org>
parents:
29543
diff
changeset
|
456 self._servicehandler.printbanner(self.address) |
024e8f82f3de
commandserver: add new forking server implemented without using SocketServer
Yuya Nishihara <yuya@tcha.org>
parents:
29543
diff
changeset
|
457 |
024e8f82f3de
commandserver: add new forking server implemented without using SocketServer
Yuya Nishihara <yuya@tcha.org>
parents:
29543
diff
changeset
|
458 def _cleanup(self): |
024e8f82f3de
commandserver: add new forking server implemented without using SocketServer
Yuya Nishihara <yuya@tcha.org>
parents:
29543
diff
changeset
|
459 signal.signal(signal.SIGCHLD, self._oldsigchldhandler) |
024e8f82f3de
commandserver: add new forking server implemented without using SocketServer
Yuya Nishihara <yuya@tcha.org>
parents:
29543
diff
changeset
|
460 self._sock.close() |
024e8f82f3de
commandserver: add new forking server implemented without using SocketServer
Yuya Nishihara <yuya@tcha.org>
parents:
29543
diff
changeset
|
461 self._servicehandler.unlinksocket(self.address) |
024e8f82f3de
commandserver: add new forking server implemented without using SocketServer
Yuya Nishihara <yuya@tcha.org>
parents:
29543
diff
changeset
|
462 # don't kill child processes as they have active clients, just wait |
024e8f82f3de
commandserver: add new forking server implemented without using SocketServer
Yuya Nishihara <yuya@tcha.org>
parents:
29543
diff
changeset
|
463 self._reapworkers(0) |
024e8f82f3de
commandserver: add new forking server implemented without using SocketServer
Yuya Nishihara <yuya@tcha.org>
parents:
29543
diff
changeset
|
464 |
024e8f82f3de
commandserver: add new forking server implemented without using SocketServer
Yuya Nishihara <yuya@tcha.org>
parents:
29543
diff
changeset
|
465 def run(self): |
024e8f82f3de
commandserver: add new forking server implemented without using SocketServer
Yuya Nishihara <yuya@tcha.org>
parents:
29543
diff
changeset
|
466 try: |
024e8f82f3de
commandserver: add new forking server implemented without using SocketServer
Yuya Nishihara <yuya@tcha.org>
parents:
29543
diff
changeset
|
467 self._mainloop() |
024e8f82f3de
commandserver: add new forking server implemented without using SocketServer
Yuya Nishihara <yuya@tcha.org>
parents:
29543
diff
changeset
|
468 finally: |
024e8f82f3de
commandserver: add new forking server implemented without using SocketServer
Yuya Nishihara <yuya@tcha.org>
parents:
29543
diff
changeset
|
469 self._cleanup() |
024e8f82f3de
commandserver: add new forking server implemented without using SocketServer
Yuya Nishihara <yuya@tcha.org>
parents:
29543
diff
changeset
|
470 |
024e8f82f3de
commandserver: add new forking server implemented without using SocketServer
Yuya Nishihara <yuya@tcha.org>
parents:
29543
diff
changeset
|
471 def _mainloop(self): |
024e8f82f3de
commandserver: add new forking server implemented without using SocketServer
Yuya Nishihara <yuya@tcha.org>
parents:
29543
diff
changeset
|
472 h = self._servicehandler |
024e8f82f3de
commandserver: add new forking server implemented without using SocketServer
Yuya Nishihara <yuya@tcha.org>
parents:
29543
diff
changeset
|
473 while not h.shouldexit(): |
024e8f82f3de
commandserver: add new forking server implemented without using SocketServer
Yuya Nishihara <yuya@tcha.org>
parents:
29543
diff
changeset
|
474 try: |
024e8f82f3de
commandserver: add new forking server implemented without using SocketServer
Yuya Nishihara <yuya@tcha.org>
parents:
29543
diff
changeset
|
475 ready = select.select([self._sock], [], [], h.pollinterval)[0] |
024e8f82f3de
commandserver: add new forking server implemented without using SocketServer
Yuya Nishihara <yuya@tcha.org>
parents:
29543
diff
changeset
|
476 if not ready: |
024e8f82f3de
commandserver: add new forking server implemented without using SocketServer
Yuya Nishihara <yuya@tcha.org>
parents:
29543
diff
changeset
|
477 continue |
024e8f82f3de
commandserver: add new forking server implemented without using SocketServer
Yuya Nishihara <yuya@tcha.org>
parents:
29543
diff
changeset
|
478 conn, _addr = self._sock.accept() |
024e8f82f3de
commandserver: add new forking server implemented without using SocketServer
Yuya Nishihara <yuya@tcha.org>
parents:
29543
diff
changeset
|
479 except (select.error, socket.error) as inst: |
024e8f82f3de
commandserver: add new forking server implemented without using SocketServer
Yuya Nishihara <yuya@tcha.org>
parents:
29543
diff
changeset
|
480 if inst.args[0] == errno.EINTR: |
024e8f82f3de
commandserver: add new forking server implemented without using SocketServer
Yuya Nishihara <yuya@tcha.org>
parents:
29543
diff
changeset
|
481 continue |
024e8f82f3de
commandserver: add new forking server implemented without using SocketServer
Yuya Nishihara <yuya@tcha.org>
parents:
29543
diff
changeset
|
482 raise |
024e8f82f3de
commandserver: add new forking server implemented without using SocketServer
Yuya Nishihara <yuya@tcha.org>
parents:
29543
diff
changeset
|
483 |
024e8f82f3de
commandserver: add new forking server implemented without using SocketServer
Yuya Nishihara <yuya@tcha.org>
parents:
29543
diff
changeset
|
484 pid = os.fork() |
024e8f82f3de
commandserver: add new forking server implemented without using SocketServer
Yuya Nishihara <yuya@tcha.org>
parents:
29543
diff
changeset
|
485 if pid: |
024e8f82f3de
commandserver: add new forking server implemented without using SocketServer
Yuya Nishihara <yuya@tcha.org>
parents:
29543
diff
changeset
|
486 try: |
024e8f82f3de
commandserver: add new forking server implemented without using SocketServer
Yuya Nishihara <yuya@tcha.org>
parents:
29543
diff
changeset
|
487 self.ui.debug('forked worker process (pid=%d)\n' % pid) |
024e8f82f3de
commandserver: add new forking server implemented without using SocketServer
Yuya Nishihara <yuya@tcha.org>
parents:
29543
diff
changeset
|
488 self._workerpids.add(pid) |
024e8f82f3de
commandserver: add new forking server implemented without using SocketServer
Yuya Nishihara <yuya@tcha.org>
parents:
29543
diff
changeset
|
489 h.newconnection() |
024e8f82f3de
commandserver: add new forking server implemented without using SocketServer
Yuya Nishihara <yuya@tcha.org>
parents:
29543
diff
changeset
|
490 finally: |
024e8f82f3de
commandserver: add new forking server implemented without using SocketServer
Yuya Nishihara <yuya@tcha.org>
parents:
29543
diff
changeset
|
491 conn.close() # release handle in parent process |
024e8f82f3de
commandserver: add new forking server implemented without using SocketServer
Yuya Nishihara <yuya@tcha.org>
parents:
29543
diff
changeset
|
492 else: |
024e8f82f3de
commandserver: add new forking server implemented without using SocketServer
Yuya Nishihara <yuya@tcha.org>
parents:
29543
diff
changeset
|
493 try: |
29587
536eec443b4a
commandserver: rename _serveworker() to _runworker()
Yuya Nishihara <yuya@tcha.org>
parents:
29586
diff
changeset
|
494 self._runworker(conn) |
29544
024e8f82f3de
commandserver: add new forking server implemented without using SocketServer
Yuya Nishihara <yuya@tcha.org>
parents:
29543
diff
changeset
|
495 conn.close() |
024e8f82f3de
commandserver: add new forking server implemented without using SocketServer
Yuya Nishihara <yuya@tcha.org>
parents:
29543
diff
changeset
|
496 os._exit(0) |
024e8f82f3de
commandserver: add new forking server implemented without using SocketServer
Yuya Nishihara <yuya@tcha.org>
parents:
29543
diff
changeset
|
497 except: # never return, hence no re-raises |
024e8f82f3de
commandserver: add new forking server implemented without using SocketServer
Yuya Nishihara <yuya@tcha.org>
parents:
29543
diff
changeset
|
498 try: |
024e8f82f3de
commandserver: add new forking server implemented without using SocketServer
Yuya Nishihara <yuya@tcha.org>
parents:
29543
diff
changeset
|
499 self.ui.traceback(force=True) |
024e8f82f3de
commandserver: add new forking server implemented without using SocketServer
Yuya Nishihara <yuya@tcha.org>
parents:
29543
diff
changeset
|
500 finally: |
024e8f82f3de
commandserver: add new forking server implemented without using SocketServer
Yuya Nishihara <yuya@tcha.org>
parents:
29543
diff
changeset
|
501 os._exit(255) |
024e8f82f3de
commandserver: add new forking server implemented without using SocketServer
Yuya Nishihara <yuya@tcha.org>
parents:
29543
diff
changeset
|
502 |
024e8f82f3de
commandserver: add new forking server implemented without using SocketServer
Yuya Nishihara <yuya@tcha.org>
parents:
29543
diff
changeset
|
503 def _sigchldhandler(self, signal, frame): |
024e8f82f3de
commandserver: add new forking server implemented without using SocketServer
Yuya Nishihara <yuya@tcha.org>
parents:
29543
diff
changeset
|
504 self._reapworkers(os.WNOHANG) |
024e8f82f3de
commandserver: add new forking server implemented without using SocketServer
Yuya Nishihara <yuya@tcha.org>
parents:
29543
diff
changeset
|
505 |
024e8f82f3de
commandserver: add new forking server implemented without using SocketServer
Yuya Nishihara <yuya@tcha.org>
parents:
29543
diff
changeset
|
506 def _reapworkers(self, options): |
024e8f82f3de
commandserver: add new forking server implemented without using SocketServer
Yuya Nishihara <yuya@tcha.org>
parents:
29543
diff
changeset
|
507 while self._workerpids: |
024e8f82f3de
commandserver: add new forking server implemented without using SocketServer
Yuya Nishihara <yuya@tcha.org>
parents:
29543
diff
changeset
|
508 try: |
024e8f82f3de
commandserver: add new forking server implemented without using SocketServer
Yuya Nishihara <yuya@tcha.org>
parents:
29543
diff
changeset
|
509 pid, _status = os.waitpid(-1, options) |
024e8f82f3de
commandserver: add new forking server implemented without using SocketServer
Yuya Nishihara <yuya@tcha.org>
parents:
29543
diff
changeset
|
510 except OSError as inst: |
024e8f82f3de
commandserver: add new forking server implemented without using SocketServer
Yuya Nishihara <yuya@tcha.org>
parents:
29543
diff
changeset
|
511 if inst.errno == errno.EINTR: |
024e8f82f3de
commandserver: add new forking server implemented without using SocketServer
Yuya Nishihara <yuya@tcha.org>
parents:
29543
diff
changeset
|
512 continue |
024e8f82f3de
commandserver: add new forking server implemented without using SocketServer
Yuya Nishihara <yuya@tcha.org>
parents:
29543
diff
changeset
|
513 if inst.errno != errno.ECHILD: |
024e8f82f3de
commandserver: add new forking server implemented without using SocketServer
Yuya Nishihara <yuya@tcha.org>
parents:
29543
diff
changeset
|
514 raise |
024e8f82f3de
commandserver: add new forking server implemented without using SocketServer
Yuya Nishihara <yuya@tcha.org>
parents:
29543
diff
changeset
|
515 # no child processes at all (reaped by other waitpid()?) |
024e8f82f3de
commandserver: add new forking server implemented without using SocketServer
Yuya Nishihara <yuya@tcha.org>
parents:
29543
diff
changeset
|
516 self._workerpids.clear() |
024e8f82f3de
commandserver: add new forking server implemented without using SocketServer
Yuya Nishihara <yuya@tcha.org>
parents:
29543
diff
changeset
|
517 return |
024e8f82f3de
commandserver: add new forking server implemented without using SocketServer
Yuya Nishihara <yuya@tcha.org>
parents:
29543
diff
changeset
|
518 if pid == 0: |
024e8f82f3de
commandserver: add new forking server implemented without using SocketServer
Yuya Nishihara <yuya@tcha.org>
parents:
29543
diff
changeset
|
519 # no waitable child processes |
024e8f82f3de
commandserver: add new forking server implemented without using SocketServer
Yuya Nishihara <yuya@tcha.org>
parents:
29543
diff
changeset
|
520 return |
024e8f82f3de
commandserver: add new forking server implemented without using SocketServer
Yuya Nishihara <yuya@tcha.org>
parents:
29543
diff
changeset
|
521 self.ui.debug('worker process exited (pid=%d)\n' % pid) |
024e8f82f3de
commandserver: add new forking server implemented without using SocketServer
Yuya Nishihara <yuya@tcha.org>
parents:
29543
diff
changeset
|
522 self._workerpids.discard(pid) |
024e8f82f3de
commandserver: add new forking server implemented without using SocketServer
Yuya Nishihara <yuya@tcha.org>
parents:
29543
diff
changeset
|
523 |
29587
536eec443b4a
commandserver: rename _serveworker() to _runworker()
Yuya Nishihara <yuya@tcha.org>
parents:
29586
diff
changeset
|
524 def _runworker(self, conn): |
29544
024e8f82f3de
commandserver: add new forking server implemented without using SocketServer
Yuya Nishihara <yuya@tcha.org>
parents:
29543
diff
changeset
|
525 signal.signal(signal.SIGCHLD, self._oldsigchldhandler) |
29586
42cdba9cfee4
commandserver: separate initialization and cleanup of forked process
Yuya Nishihara <yuya@tcha.org>
parents:
29585
diff
changeset
|
526 _initworkerprocess() |
29544
024e8f82f3de
commandserver: add new forking server implemented without using SocketServer
Yuya Nishihara <yuya@tcha.org>
parents:
29543
diff
changeset
|
527 h = self._servicehandler |
29586
42cdba9cfee4
commandserver: separate initialization and cleanup of forked process
Yuya Nishihara <yuya@tcha.org>
parents:
29585
diff
changeset
|
528 try: |
42cdba9cfee4
commandserver: separate initialization and cleanup of forked process
Yuya Nishihara <yuya@tcha.org>
parents:
29585
diff
changeset
|
529 _serverequest(self.ui, self.repo, conn, h.createcmdserver) |
42cdba9cfee4
commandserver: separate initialization and cleanup of forked process
Yuya Nishihara <yuya@tcha.org>
parents:
29585
diff
changeset
|
530 finally: |
42cdba9cfee4
commandserver: separate initialization and cleanup of forked process
Yuya Nishihara <yuya@tcha.org>
parents:
29585
diff
changeset
|
531 gc.collect() # trigger __del__ since worker process uses os._exit |