Commit graph

96 commits

Author SHA1 Message Date
Daniel Eklöf
60c3ff8737
selection: send primary/clipboard data asynchronously
TODO: try writing synchronously first
2019-11-04 13:11:15 +01:00
Daniel Eklöf
a706c1e804
terminal: add comments describing the sync/async writing modes 2019-11-04 12:36:43 +01:00
Daniel Eklöf
78cd93f030
terminal: malloc_trim() is a GNU extension 2019-11-03 12:57:47 +01:00
Daniel Eklöf
2195e2cf71
terminal: trim memory after free:ing a terminal
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.
2019-11-03 12:48:18 +01:00
Daniel Eklöf
e76357eabb
terminal: ptmx fdm handler: tag unlikely branches 2019-11-03 12:14:09 +01:00
Daniel Eklöf
79945419eb
terminal: comments and cleanup 2019-11-03 12:13:51 +01:00
Daniel Eklöf
cba1551b03
terminal: cleanup asynchronous ptmx output handling
Break out actual writing to a separate function, and call this
function both from the synchronous and the asynchronous code paths.
2019-11-03 01:25:41 +01:00
Daniel Eklöf
f00c5fdac6
term: asynchronous writes to slave
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)
2019-11-03 01:03:52 +01:00
Daniel Eklöf
9f1525aef7
Rename: vt_to_slave() -> term_to_slave() 2019-11-03 00:52:24 +01:00
Daniel Eklöf
79c3121aa3
misc: fdm already logs failures 2019-11-03 00:52:24 +01:00
Daniel Eklöf
965d8a3a8e
terminal: don't get stuck waiting for misbehaving slaves to terminate
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).
2019-11-02 12:09:32 +01:00
Daniel Eklöf
563c910127
terminal: 'child_ret' variables isn't needed 2019-11-02 11:30:32 +01:00
Daniel Eklöf
f28fb6c039
timerfd: read() returns -1 with errno == EAGAIN, not 0
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.
2019-11-02 01:44:01 +01:00
Daniel Eklöf
b27cd9cedf
timerfd: use non-blocking mode, fixes dead lock
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.
2019-11-02 01:14:40 +01:00
Daniel Eklöf
0bd2ddd8ad
term_init(): initialize slave TERM from term_init() argument 2019-11-01 21:03:08 +01:00
Daniel Eklöf
69d62d3cd2
slave: set TERM environment variable in slave process 2019-11-01 21:01:15 +01:00
Daniel Eklöf
1e41a25f00
terminal: call user-defined callback when destroying terminal
main uses this to get the exit code of the terminal.
2019-11-01 20:34:32 +01:00
Daniel Eklöf
70b236d66d
term_shutdown(): cleanup
* Close FDs, then delay destruction to next epoll() call
* Destroy window before destroying terminal
2019-11-01 20:30:58 +01:00
Daniel Eklöf
c824aa2ef5
terminal: fdm_del() closes the FD 2019-11-01 20:29:16 +01:00
Daniel Eklöf
fb0801fa56
terminal: delayed rendering: fdm_delayed_render() may be called with is_armged==false
This would happen if *both* timers triggered in the same epoll() call.
2019-11-01 20:28:11 +01:00
Daniel Eklöf
2286bcf23d
terminal: no need to check for EAGAIN - we don't use non-blocking 2019-11-01 20:27:45 +01:00
Daniel Eklöf
2e78dcc5e5
Don't use non-blocking FDs
We use epoll() to determine when we can read/write FDs so there's
absolutely no need for non-blocking.
2019-11-01 20:24:13 +01:00
Daniel Eklöf
4ae22b72a1
term: fdm_shutdown(): remove debug output 2019-10-30 20:28:21 +01:00
Daniel Eklöf
644585a3e5
term: term_shutdown(): set exit value in wayland 2019-10-30 20:25:45 +01:00
Daniel Eklöf
c7238ef7f3
term: assign client PID to term->slave 2019-10-30 20:24:54 +01:00
Daniel Eklöf
58e31728a0
term: term_init(): create wayland window *last*
* Configure all FDs *completely* before moving on
* Start client before creating the wayland window
2019-10-30 20:22:01 +01:00
Daniel Eklöf
9d5926ce12
term: add term_shutdown()
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.
2019-10-30 20:03:11 +01:00
Daniel Eklöf
445bbe3469
wayland: track multiple terminals
The wayland 'term' member is gone and replaced by a list,
'terms'. This list contains all currently running terminal (windows).
2019-10-30 20:02:06 +01:00
Daniel Eklöf
18921f7f45
term: move client startup to a new function, slave_spawn() 2019-10-30 18:05:03 +01:00
Daniel Eklöf
348f3738da
term: break out font initialization to a separate function 2019-10-30 17:50:12 +01:00
Daniel Eklöf
7dcd6b7d55
term: break out render worker threads initialization to a separate function 2019-10-30 17:45:59 +01:00
Daniel Eklöf
54accd8060
term: break out color cube initialization to a separate function 2019-10-30 17:40:09 +01:00
Daniel Eklöf
8d6817a999
term: require all font variants to load 2019-10-30 17:37:30 +01:00
Daniel Eklöf
ce5f5e4d51
slave: rename slave_spawn() -> slave_exec() 2019-10-30 17:30:58 +01:00
Daniel Eklöf
4ec9db8e18
term: no need to stack-allocate an array of worker contexts 2019-10-28 19:23:41 +01:00
Daniel Eklöf
8e6f87eb17
render worker context: allocate, and let worker threads free
Since we now initialize the worker threads from term_init(), which
returns before the threads terminate, we can no longer use
stack-allocated worker contexts.

We _could_ put them in the terminal struct. But a simpler solution is
to allocate them in term_init(), and let the threads free them when
they don't need them anymore.
2019-10-28 18:51:04 +01:00
Daniel Eklöf
720d0df067
term: open FDs before allocating terminal struct 2019-10-28 18:46:03 +01:00
Daniel Eklöf
fe974956b0
term: integrate directly with FDM 2019-10-28 18:35:16 +01:00
Daniel Eklöf
0979a0e2e5
terminal: implement term_init() and term_destroy() 2019-10-28 18:25:19 +01:00
Daniel Eklöf
1adab32906
term: wayland struct is now not a part of the terminal struct
We do however need access to it, so provide a pointer. The difference
is that now we can have a *single* wayland instance, but multiple
terminal instances.
2019-10-27 18:51:14 +01:00
Daniel Eklöf
c9455d5f21
kbd: move into wayland 2019-10-27 17:10:32 +01:00
Daniel Eklöf
777863ac3e
term: add term_reset_view() - make view follow end-of-output again 2019-08-28 17:27:42 +02:00
Daniel Eklöf
0a40a5b6a2
term: remove commented out code 2019-08-23 20:07:05 +02:00
Daniel Eklöf
7c7720a3ab
scrolling: optimize row access by assuming number of rows is a power of 2
With this assumption, we can replace 'a % b' with 'a & (b - 1)'. In
terms of instructions, this means a fast 'and' instead of a slow
'div'.

Further optimize scrolling by:

* not double-initializing empty rows. Previously, grid_row_alloc()
  called calloc(), which was then followed by a memset() when
  scrolling. This is of course unnecessary.

* Don't loop the entire set of visible rows (this was done to ensure
  all visible rows had been allocated, and to prefetch the cell
  contents).

  This isn't necessary; only newly pulled in rows can be NULL. For
  now, don't prefetch at all.
2019-08-22 17:33:23 +02:00
Daniel Eklöf
d8fb80ea32
term: rename colors256 -> table 2019-08-21 18:50:24 +02:00
Daniel Eklöf
631e0c0870
term: use colors256 array for *all* colors
That is, remove the 'regular' and 'bright' color arrays. This is
possible since the 256-color array is defined such that the first 16
colors map to the regular and bright colors.
2019-08-21 18:47:48 +02:00
Daniel Eklöf
d7aaeaedee
csi: move 256-color table into the terminal struct 2019-08-21 17:56:21 +02:00
Daniel Eklöf
776432ded3
erase-cells: don't memset when keeping background color 2019-08-20 21:11:09 +02:00
Daniel Eklöf
14d4a0a1c6
term: don't send mouse events if shift is being pressed 2019-08-08 17:58:50 +02:00
Daniel Eklöf
c06f141189
term: cancel selection when scrolling wraps
If we scroll enough, we'll eventually end up wrapping around the
entire scrollback buffer. At this point, a selection is no longer
valid, so cancel it.

Note: this was very obvious when scrolling in the alt screen, since
its scrollback buffer is what you see on the screen (i.e. it has no
scrollback).
2019-08-05 20:16:17 +02:00