Skip to content

Commit

Permalink
Add timeout hack
Browse files Browse the repository at this point in the history
This reimplements 058adf5 (pty: Fix indefinite wait for EOS after
child-exited, 2019-12-01).
  • Loading branch information
felipec committed Mar 19, 2023
1 parent bfac77c commit 89592f1
Show file tree
Hide file tree
Showing 3 changed files with 30 additions and 2 deletions.
4 changes: 2 additions & 2 deletions src/glib-glue.hh
Expand Up @@ -225,8 +225,8 @@ private:
vte::log_exception();
}

/* The Timer may have been re-scheduled from within the callback.
* In this case, the callback must return false!
/* The Timer may have been re-scheduled or removed from within
* the callback. In this case, the callback must return false!
* m_source_id is now different (since the old source
* ID is still associated with the main context until we return from
* this function), after which invalidate_source() will be called,
Expand Down
24 changes: 24 additions & 0 deletions src/vte.cc
Expand Up @@ -992,6 +992,23 @@ Terminal::queue_child_exited()
g_object_unref);
}

bool
Terminal::child_exited_eos_wait_callback()
{
/* If we get this callback, there has been some time elapsed
* after child-exited, but no EOS yet. This happens for example
* when the primary child started other processes in the background,
* which inherited the PTY, and thus keep it open, see
* https://gitlab.gnome.org/GNOME/vte/issues/204
*
* Force an EOS.
*/
if (pty())
pty_io_read(pty()->fd(), G_IO_HUP);

return false; // don't run again
}

/* Emit an "increase-font-size" signal. */
void
Terminal::emit_increase_font_size()
Expand Down Expand Up @@ -3299,6 +3316,8 @@ Terminal::child_watch_done(pid_t pid,
if (pty() || !m_incoming_queue.empty()) {
m_child_exit_status = status;
m_child_exited_after_eos_pending = true;

m_child_exited_eos_wait_timer.schedule_seconds(2); // FIXME: better value?
} else {
m_child_exited_after_eos_pending = false;

Expand Down Expand Up @@ -4151,6 +4170,9 @@ Terminal::pty_io_read(int const fd,
chunk->set_sealed();
chunk->set_eos();

/* Cancel wait timer */
m_child_exited_eos_wait_timer.abort();

again = false;
}

Expand Down Expand Up @@ -10143,6 +10165,8 @@ Terminal::unset_pty(bool notify_widget)
disconnect_pty_read();
disconnect_pty_write();

m_child_exited_eos_wait_timer.abort();

/* Clear incoming and outgoing queues */
m_input_bytes = 0;
m_incoming_queue = {};
Expand Down
4 changes: 4 additions & 0 deletions src/vteinternal.hh
Expand Up @@ -297,6 +297,10 @@ public:
int m_child_exit_status{-1}; /* pid's exit status, or -1 */
bool m_eos_pending{false};
bool m_child_exited_after_eos_pending{false};
bool child_exited_eos_wait_callback();
vte::glib::Timer m_child_exited_eos_wait_timer{std::bind(&Terminal::child_exited_eos_wait_callback,
this),
"child-exited-eos-wait-timer"};
VteReaper *m_reaper;

/* Queue of chunks of data read from the PTY.
Expand Down

0 comments on commit 89592f1

Please sign in to comment.