When support was added for DECOM (absolute/relative row addressing), a
small but noticeable (~3.5%) performance regression was introduced.
Try to improve the situation by simplifying the relative-to-absolute
conversion; only the row needs to be transformed.
The default is absolute mode, where 0,0 is the upper left corner of
the screen.
In relative mode, the origin is relative the top scroll margin.
Internally, we always track the current cursor position in absolute
mode. Every time we the client *sets* or *queries* the cursor position
in relative mode, we translate it to absolute.
A terminal with lots of scrollback history will have allocated a lot
of memory.
Normally, free() wont return this memory to the OS, and we don't seem
to trigger the automatic trim calls.
This means the server would accumulate quite a lot of memory over
time, as terminals come and go.
Now we explicitly trim the memory every time a terminal is destroyed.
Make ptmx non-blocking. Then, when writing data to the slave would
have blocked, use the FDM to asynchronously write the remaining data.
This is done by enabling EPOLLOUT on ptmx, and enqueueing all outgoing
data. The FDM handler will go through the enqueued data, and once all
of it has been written, we turn off EPOLLOUT again (thus switching
back to synchronous writes)
While unusual, it *is* possible for a client *not* to terminate when
we close ptmx.
We need to handle this *somehow*. Since it is so unusual, we'll go
with a fairly easy, but synchronous method:
* Register a signal handler for SIGALRM, and setup a 2 second alarm
* Wait for slave to die
* If it didn't die, sent SIGTERM, then re-set the alarm for another 2
seconds.
* If it still hasn't died, send SIGKILL (this time without an alarm).
When there hasn't been a timeout (or in our case, there was a timeout,
but we reset the timer before we got to the read()), read() returns,
not 0, but -1 with errno == EAGAIN.
Since we cancel the timers every now and then, there's a (small)
chance that one handler cancels a timer that has triggered in the same
epoll() iteration.
When this happens, read() blocks.
Fix by making the timer FDs non-blocking, and simply returning when we
read 0 bytes.
This function unmaps the terminal window, removes itself from the
wayland list of terminals and then finally destroys itself.
We ensure we don't get any callbacks/events referring to a free:d
terminal struct, we close all terminal related FDs and unmap the
wayland window.
Then, to be really really sure there aren't any (by the FDM) queued up
events, we delay the self-destruction to the next FDM poll iteration,
by opening an event FD and adding it to the FDM.
The callback for the event FD removes the FD from the FDM again, and
closes it. And then proceeds to destroy the terminal.