v0.3.0 cf370a0

seat_disable.go RawHistoryFolder

1package drm
2
3import "time"
4
5// A seat disable revokes this process as DRM master. The planes keep what
6// was last committed, and a client without DRM_CLIENT_CAP_PLANE_COLOR_PIPELINE
7// cannot clear COLOR_PIPELINE (amdgpu applies it regardless): the next master
8// would inherit the pipeline. So before the disable is acked, every output
9// that applies one commits Bypass. (A crash cannot do that: see docs/config.md.)
10
11// PrepareSeatDisable asks the output's goroutine to leave its planes on
12// Bypass and waits for it, at most timeout. It reports false on timeout (the
13// output is busy or not running): the caller goes on. It is safe to call
14// from any goroutine.
15func (o *Output) PrepareSeatDisable(timeout time.Duration) bool {
16	timer := time.NewTimer(timeout)
17	defer timer.Stop()
18	ack := make(chan struct{}, 1) // buffered: Run never waits for us
19	select {
20	case o.seatDisable <- ack:
21	case <-timer.C:
22		return false
23	}
24	select {
25	case <-ack:
26		return true
27	case <-timer.C:
28		return false
29	}
30}
31
32// pipelineApplied reports whether a plane applies the colour pipeline.
33func (o *Output) pipelineApplied() bool {
34	for _, p := range [...]*plane{o.primary, o.overlay} {
35		if p.hasColor() && p.colorKnown && p.colorApplied != colorBypass {
36			return true
37		}
38	}
39	return false
40}
41
42// bypassForSeatDisable commits Bypass on the planes when one applies the
43// pipeline, synchronously. It is a no-op (no commit) otherwise. A failure is
44// only logged: the seat is disabled anyway. The commit blocks, and the kernel
45// may make it wait for a flip in flight: a Bypass that finishes after
46// PrepareSeatDisable's bound is lost, since the seat is disabled meanwhile.
47// The caller logs the timeout.
48func (o *Output) bypassForSeatDisable() {
49	if !o.pipelineApplied() {
50		return
51	}
52	req := &o.stateReq
53	req.reset()
54	o.forceBypass(req)
55	if err := o.k.commit(req, 0, 0); err != nil {
56		o.log.Warn().Err(err).Str("connector", o.conn.name).Msg("colour pipeline not reset before seat disable")
57		return
58	}
59	o.colorBypassed()
60	o.log.Info().Str("connector", o.conn.name).Msg("colour pipeline reset before seat disable")
61}

Keyboard shortcuts

Single-key shortcuts are on. ctrl k and esc work whatever this says.

ctrl k :
go to a section, branch, tag, file or repository
?
this list
j k
move the row cursor down / up
enter
open the row under the cursor; on Files, a directory opens or closes in place
↑ ↓ ← → home end
in the file tree (focus on a row): previous / next row, close / open a directory or go to its parent / first entry, first / last row. They never open a file
l h
on Files: open a directory or a file / close a directory or go up to its parent, then to the parent page. Elsewhere: into the side panel (on a merge request, its files) / back to the content; there j k move between its controls
g g G
first / last row
/
filter the list; on Files, find a file anywhere in the repository (esc clears, enter opens the best match)
b
switch branch or tag
g s g f g c g b g m g i g r g a
tabs: summary, files, commits, branches & tags, merge requests, issues, releases, actions (when available)
g h
home
w
wide mode: use the whole width of the screen, or not (remembered)
y
copy a permalink pinned to the commit
d u x
diff: split / unified / collapse or expand all
e E
diff: the whole file in view / every file, with the lines the hunks hide
n
merge request: next note in the diff
esc
close a dialog, leave a field

Branches 25

Tags 10

↑↓ moveenter openesc close