Commit graph

802 commits

Author SHA1 Message Date
Daniel Eklöf
c6c75298f3
shm: automatic buffer purging is now delayed one cycle
This ensures we don't purge a buffer that a user is holding a
reference to.
2019-11-02 01:27:05 +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
035ace33b6
server: purge shm buffers when terminal is destroyed 2019-11-02 00:49:25 +01:00
Daniel Eklöf
8e5d386afc
shm: add shm_purge()
Destroys *all* buffers associated with the specified cookie.
2019-11-02 00:49:00 +01:00
Daniel Eklöf
4d3251a93b
render: last_buf may point to a free:d buffer
So, store last buf's width/height separately
2019-11-02 00:48:07 +01:00
Daniel Eklöf
5812242405
shm: purge unused buffers
When we need to create a new buffer (because the cache doesn't have
any buffers of correct size, or because they're all busy), purge
buffers with a size mismatch.
2019-11-02 00:35:02 +01:00
Daniel Eklöf
00b46455a0
shm: associate a 'cookie' with each buffer
When re-using a buffer from cache, only re-use ones with a matching
cookie.

This prevents contention between multiple terminal windows.
2019-11-02 00:33:37 +01:00
Daniel Eklöf
8df82938b0
shm: get_buffer(): remove 'copies' argument; it's not used 2019-11-02 00:23:51 +01:00
Daniel Eklöf
632b6ee0ea
shm: add debug logging of how large the allocated memory buffer is 2019-11-02 00:23:23 +01:00
Daniel Eklöf
f884f77d99
shm: fix name of memfd 2019-11-02 00:05:07 +01:00
Daniel Eklöf
17024b4431
client: bug: verify argv was sent correctly
We checked we had written 2 bytes (sizeof(len)), not <len> bytes.
2019-11-02 00:01:16 +01:00
Daniel Eklöf
570b3ac25a
client: add debug logging of argc/argv 2019-11-02 00:01:08 +01:00
Daniel Eklöf
19c099236b
server: add debug logging of client argc/argv 2019-11-02 00:00:31 +01:00
Daniel Eklöf
25311fc4eb
Merge branch 'multi-window' 2019-11-01 23:49:54 +01:00
Daniel Eklöf
2544e93c0e
client: register signal handler for SIGTERM too 2019-11-01 21:13:37 +01:00
Daniel Eklöf
438d6eaff0
client/server: add -t,--term to footclient 2019-11-01 21:10:47 +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
d2b395bd43
PKGBUILD: need to execute footclient, to generate profiling data 2019-11-01 20:51:09 +01:00
Daniel Eklöf
77ea7fc61c
client: add long options for --verbose and --help 2019-11-01 20:50:00 +01:00
Daniel Eklöf
8b4ef78f7a
wayland: wayl_win_destroy(): looks like we need another roundtrip 2019-11-01 20:45:57 +01:00
Daniel Eklöf
43462b24f3
font: cache loaded fonts globally
Each font instance has a ref-counter. Whenever we want to instantiate
a font that has already been loaded, we instead return the
already-loaded instance, and bump the ref counter.

When the last font instance is destroyed, it is also removed from the
cache.
2019-11-01 20:40:42 +01:00
Daniel Eklöf
3032ac33da
completions: zsh: add --server and --term to completions 2019-11-01 20:40:10 +01:00
Daniel Eklöf
6637c8aeda
client: a standalone binary that connects to a foot --server 2019-11-01 20:39:34 +01:00
Daniel Eklöf
a1efd65746
server: implement a --server mode
In this mode, foot listens on a UNIX socket and creates terminal
windows when clients connect.

A connecting client sends argc/argv to the server, and the server
instantiates a new terminal window.

When the terminal window is closed, the exit code is sent back to the
client.
2019-11-01 20:39:09 +01:00
Daniel Eklöf
32c6ed7069
main: register signal handlers for SIGINT and SIGTERM 2019-11-01 20:36:55 +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
dac1ba18c8
render: limit length of title in call to xdg_toplevel_set_title()
Trying to pass a too long title (not sure what "too long" is
though...) will trigger a call to abort() inside the wayland-client
library.
2019-11-01 20:25:44 +01:00
Daniel Eklöf
bc815a33db
wayland: wayl_destroy(): destroy any remaining terminals 2019-11-01 20:25:08 +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
95b7c405d4
wayland: wayl_win_destroy(): unmap windows before destroying
This will trigger e.d. keyboard_leave() and wl_pointer_leave() events,
which ensures there aren't any references to the destroyed window from
the global wayland struct.

Call wl_display_roundtrip() to trigger those events *before* we
destroy the window.
2019-11-01 20:19:53 +01:00
Daniel Eklöf
66b2097275
wayland: wayl_init(): call wl_display_roundtrip() when done 2019-11-01 20:04:40 +01:00
Daniel Eklöf
291a928a49
render: call wl_display_flush() after rendering
This allows us to remove that call from the main event loop.
2019-11-01 20:01:36 +01:00
Daniel Eklöf
b793919aba
wayland: fdm_del() now closes the FD 2019-11-01 19:59:39 +01:00
Daniel Eklöf
80c4721e57
fdm: don't free FD data that may be referenced by epoll return data
It is perfectly possible, and legal, for a FDM handler to delete
another handler. The problem however is when the epoll returned array
of FD events contain the removed FD handler *after* the handler that
removed it.

That is, if the epoll returned array is:

  [FD=13, FD=37]

and the handler for FD=13 removes FD=37, then given the current
implementation, the FD user data (our handler callback etc) will point
to a free:d address.

Add support for this situation by deferring FD handler removal *when
called from another handler*.

This is done by "locking" the FDM struct before looping the handlers
for FDs with events (and unlocking afterwards).

In fdm_del(), we check if the FDM has been locked, in which case the
FD is marked as deleted, and put on a deferred list. But
not *actually* deleted.

Meanwhile, in the FDM poll function, we skip calling handlers for
marked-for-deletion FDs.

Then, when all FDs have been processed, we loop the deferred list and
finally deletes the FDs for real.
2019-11-01 19:51:33 +01:00
Daniel Eklöf
4ae22b72a1
term: fdm_shutdown(): remove debug output 2019-10-30 20:28:21 +01:00
Daniel Eklöf
b7546abca9
main: get exit value from wayland struct 2019-10-30 20:26:08 +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
1ed78ab443
wayland: temporary: track last terminal's exit value 2019-10-30 20:25:31 +01:00
Daniel Eklöf
883354ffb1
wayland: wayl_win_destroy(): return early if win == NULL 2019-10-30 20:25:16 +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
54039c1fb4
slave: log child's errno, not parents 2019-10-30 20:21:19 +01:00
Daniel Eklöf
98ccd01c1b
slave: fix debug logging (no 'term' variable) 2019-10-30 20:20:56 +01:00
Daniel Eklöf
2e0888bf3d
wayland: xdg_toplevel_close(): call term_shutdown() 2019-10-30 20:05:34 +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