Commit 0ac019a
authored
fix: terminal.close() blocks when pump thread is reading stdin (#1911)
* fix: terminal.close() blocks when pump thread is reading stdin (#1909)
On macOS, a pump thread blocked in a native read() on a tty can prevent
tcsetattr() from completing, causing terminal.close() to hang until the
user presses ENTER. Fix by switching to non-canonical mode with
VMIN=0/VTIME=1 before shutdown, which forces the blocked read() to time
out within 100 ms so the pump thread can exit cleanly before original
terminal attributes are restored.
Also improve NonBlockingInputStreamImpl and NonBlockingReaderImpl
shutdown: set threadIsReading=false, interrupt the thread, and join
with a timeout so close() reliably stops the pump thread.
* fix: ensure pump thread shutdown is robust on close
- AbstractUnixSysTerminal: wrap VMIN/VTIME unblock sequence in
try-finally so input.shutdown() runs even if doGetAttributes()
or doSetAttributes() throws
- NonBlockingInputStreamImpl/ReaderImpl: close the wrapped stream
before shutdown/join so the native read() is unblocked before
we wait for the pump thread to exit
* refactor: extract NonCloseable stream wrappers and add lifecycle tests
Extract NonCloseableInputStream and NonCloseableOutputStream from
DumbTerminalProvider into org.jline.utils for reuse. Apply them in
AbstractUnixSysTerminal to prevent closing shared FileDescriptors
(stdin/stdout/stderr) when the terminal is closed.
Add timeout logging to pump thread shutdown in NonBlockingInputStreamImpl
and NonBlockingReaderImpl. Add comprehensive tests for stream wrapper
behavior and pump thread lifecycle.
* fix: wrap ExecPty system streams with NonCloseable wrappers
ExecPty.doGetSlaveInput() and getSlaveOutput() returned raw
FileInputStream/FileOutputStream on shared FileDescriptors when used
as a system terminal. Closing the terminal would close the shared
FDs, breaking System.in/out/err for the rest of the JVM.
Wrap the system stream cases with NonCloseableInputStream and
NonCloseableOutputStream, matching AbstractUnixSysTerminal and
DumbTerminalProvider. Device-file paths are left unwrapped since
those are non-shared FDs.
* refactor: remove VMIN/VTIME unblock sequence from doClose()
The VMIN/VTIME trick cannot reliably unblock a native read() that is
already in progress — tcsetattr only affects the next read call, not
the current one. The NonCloseable wrappers are the actual fix: they
prevent FileDescriptor.close0() from being called, which eliminates
the macOS deadlock. The pump thread exits on its next iteration once
the current read completes naturally.
* fix: reduce shutdown join timeout and prevent double-wait
Reduce the thread join timeout from 500ms to 50ms — the thread either
exits promptly (when waiting) or is stuck in a native read (where no
timeout helps). Setting thread = null after join prevents the second
shutdown() call in the close chain from waiting again.
* refactor: extract PumpThread to deduplicate thread lifecycle management
NonBlockingInputStreamImpl and NonBlockingReaderImpl had identical
startReadingThreadIfNeeded(), shutdown(), and thread management fields.
Extract into a shared PumpThread helper that both classes delegate to.
* refactor: move run loop into PumpThread to further reduce duplication
The run() method was still duplicated between NonBlockingInputStreamImpl
and NonBlockingReaderImpl. Move the loop into PumpThread.runLoop() with
IoReader and ResultHandler callbacks. Each Impl class now has a one-liner
run() that delegates to pump.runLoop().
* fix: address SonarCloud issues in PumpThread
Store lock as a field instead of passing as method parameter (S2445).
Use notifyAll instead of notify (S2446). Re-interrupt on
InterruptedException in runLoop (S2142).1 parent 1d63740 commit 0ac019a
10 files changed
Lines changed: 571 additions & 229 deletions
File tree
- terminal/src
- main/java/org/jline
- terminal/impl
- exec
- utils
- test/java/org/jline/utils
Lines changed: 17 additions & 4 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
31 | 31 | | |
32 | 32 | | |
33 | 33 | | |
| 34 | + | |
| 35 | + | |
34 | 36 | | |
35 | 37 | | |
36 | 38 | | |
| |||
50 | 52 | | |
51 | 53 | | |
52 | 54 | | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
53 | 61 | | |
54 | 62 | | |
55 | 63 | | |
| |||
87 | 95 | | |
88 | 96 | | |
89 | 97 | | |
90 | | - | |
| 98 | + | |
| 99 | + | |
91 | 100 | | |
92 | 101 | | |
93 | 102 | | |
| |||
96 | 105 | | |
97 | 106 | | |
98 | 107 | | |
99 | | - | |
| 108 | + | |
100 | 109 | | |
101 | 110 | | |
102 | 111 | | |
| |||
231 | 240 | | |
232 | 241 | | |
233 | 242 | | |
234 | | - | |
| 243 | + | |
235 | 244 | | |
236 | | - | |
| 245 | + | |
| 246 | + | |
| 247 | + | |
| 248 | + | |
| 249 | + | |
237 | 250 | | |
238 | 251 | | |
239 | 252 | | |
| |||
Lines changed: 2 additions & 33 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
11 | 11 | | |
12 | 12 | | |
13 | 13 | | |
14 | | - | |
15 | | - | |
16 | 14 | | |
17 | 15 | | |
18 | 16 | | |
| |||
24 | 22 | | |
25 | 23 | | |
26 | 24 | | |
| 25 | + | |
| 26 | + | |
27 | 27 | | |
28 | 28 | | |
29 | 29 | | |
| |||
127 | 127 | | |
128 | 128 | | |
129 | 129 | | |
130 | | - | |
131 | | - | |
132 | | - | |
133 | | - | |
134 | | - | |
135 | | - | |
136 | | - | |
137 | | - | |
138 | | - | |
139 | | - | |
140 | | - | |
141 | | - | |
142 | | - | |
143 | | - | |
144 | | - | |
145 | | - | |
146 | | - | |
147 | | - | |
148 | | - | |
149 | | - | |
150 | | - | |
151 | | - | |
152 | | - | |
153 | | - | |
154 | | - | |
155 | | - | |
156 | | - | |
157 | | - | |
158 | | - | |
159 | | - | |
160 | | - | |
161 | 130 | | |
Lines changed: 7 additions & 3 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
31 | 31 | | |
32 | 32 | | |
33 | 33 | | |
| 34 | + | |
| 35 | + | |
34 | 36 | | |
35 | 37 | | |
36 | 38 | | |
| |||
154 | 156 | | |
155 | 157 | | |
156 | 158 | | |
157 | | - | |
| 159 | + | |
| 160 | + | |
| 161 | + | |
158 | 162 | | |
159 | 163 | | |
160 | 164 | | |
161 | 165 | | |
162 | 166 | | |
163 | | - | |
| 167 | + | |
164 | 168 | | |
165 | | - | |
| 169 | + | |
166 | 170 | | |
167 | 171 | | |
168 | 172 | | |
| |||
Lines changed: 21 additions & 92 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
31 | 31 | | |
32 | 32 | | |
33 | 33 | | |
34 | | - | |
35 | 34 | | |
36 | | - | |
37 | | - | |
| 35 | + | |
38 | 36 | | |
39 | 37 | | |
40 | 38 | | |
| |||
44 | 42 | | |
45 | 43 | | |
46 | 44 | | |
| 45 | + | |
47 | 46 | | |
48 | 47 | | |
49 | 48 | | |
| 49 | + | |
50 | 50 | | |
51 | 51 | | |
52 | | - | |
53 | | - | |
54 | | - | |
55 | | - | |
56 | | - | |
57 | | - | |
58 | | - | |
59 | | - | |
60 | | - | |
61 | | - | |
62 | | - | |
63 | | - | |
64 | | - | |
65 | | - | |
66 | | - | |
67 | | - | |
68 | | - | |
69 | | - | |
| 52 | + | |
| 53 | + | |
70 | 54 | | |
71 | 55 | | |
72 | 56 | | |
73 | 57 | | |
74 | | - | |
75 | | - | |
76 | | - | |
77 | | - | |
78 | | - | |
79 | | - | |
80 | | - | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
81 | 64 | | |
82 | 65 | | |
83 | 66 | | |
| |||
110 | 93 | | |
111 | 94 | | |
112 | 95 | | |
113 | | - | |
| 96 | + | |
114 | 97 | | |
115 | 98 | | |
116 | 99 | | |
117 | 100 | | |
118 | 101 | | |
119 | | - | |
120 | | - | |
121 | | - | |
| 102 | + | |
| 103 | + | |
| 104 | + | |
122 | 105 | | |
123 | 106 | | |
124 | 107 | | |
| |||
166 | 149 | | |
167 | 150 | | |
168 | 151 | | |
169 | | - | |
170 | | - | |
171 | | - | |
172 | | - | |
173 | | - | |
174 | | - | |
175 | | - | |
176 | | - | |
177 | | - | |
178 | | - | |
179 | | - | |
180 | | - | |
181 | | - | |
182 | | - | |
183 | | - | |
184 | | - | |
185 | | - | |
186 | | - | |
187 | | - | |
188 | | - | |
189 | | - | |
190 | | - | |
191 | | - | |
192 | | - | |
193 | | - | |
194 | | - | |
195 | | - | |
196 | | - | |
197 | | - | |
198 | | - | |
199 | | - | |
200 | | - | |
201 | | - | |
202 | | - | |
203 | | - | |
204 | | - | |
205 | | - | |
206 | | - | |
207 | | - | |
208 | | - | |
209 | | - | |
210 | | - | |
211 | | - | |
212 | | - | |
213 | | - | |
214 | | - | |
| 152 | + | |
| 153 | + | |
| 154 | + | |
215 | 155 | | |
216 | | - | |
217 | | - | |
218 | | - | |
219 | | - | |
220 | | - | |
221 | | - | |
222 | | - | |
223 | | - | |
224 | | - | |
225 | | - | |
226 | | - | |
227 | | - | |
228 | | - | |
229 | | - | |
| 156 | + | |
| 157 | + | |
| 158 | + | |
230 | 159 | | |
231 | 160 | | |
0 commit comments