Fail loudly on a touch read, stop the workers before their sockets close, and file down the small edges

This commit is contained in:
flamingcow
2026-08-04 22:26:07 -07:00
parent 12cef6a89b
commit 7b2601a02e
5 changed files with 38 additions and 20 deletions
+8 -12
View File
@@ -170,23 +170,24 @@ func findDisplay(fd int) (connID, crtcID uint32, err error) {
}
// The card number is not stable across machines, so the card driving a
// connected display is the one we want.
func openCard() (int, error) {
// connected display is the one we want, and the display it found comes back
// with it.
func openCard() (fd int, connID, crtcID uint32, err error) {
paths, err := filepath.Glob("/dev/dri/card*")
if err != nil {
return -1, err
return -1, 0, 0, err
}
for _, p := range paths {
fd, err := unix.Open(p, unix.O_RDWR|unix.O_CLOEXEC, 0)
if err != nil {
continue
}
if _, _, err := findDisplay(fd); err == nil {
return fd, nil
if connID, crtcID, err := findDisplay(fd); err == nil {
return fd, connID, crtcID, nil
}
unix.Close(fd)
}
return -1, fmt.Errorf("no drm device with a connected display")
return -1, 0, 0, fmt.Errorf("no drm device with a connected display")
}
func (fb *framebuffer) addScanout(i int) error {
@@ -223,7 +224,7 @@ func (fb *framebuffer) addScanout(i int) error {
}
func openFramebuffer() (*framebuffer, error) {
fd, err := openCard()
fd, connID, crtcID, err := openCard()
if err != nil {
return nil, err
}
@@ -236,11 +237,6 @@ func openFramebuffer() (*framebuffer, error) {
return nil, fmt.Errorf("take drm master: %w", err)
}
connID, crtcID, err := findDisplay(fd)
if err != nil {
fb.close()
return nil, err
}
mode, err := preferredMode(fd, connID)
if err != nil {
fb.close()
+8 -3
View File
@@ -119,8 +119,11 @@ func watchTouch(w, h int) (*touchState, error) {
var down bool
for {
n, err := f.Read(buf)
// Nothing else feeds this state, so returning here would freeze the
// last touch in place and leave the reset button dead while the panel
// goes on looking alive.
if err != nil {
return
panic(fmt.Sprintf("reading touchscreen events: %v", err))
}
for o := 0; o+sizeofInputEvent <= n; o += sizeofInputEvent {
typ := *(*uint16)(unsafe.Pointer(&buf[o+16]))
@@ -142,9 +145,11 @@ func watchTouch(w, h int) (*touchState, error) {
if code != synReport {
break
}
// Scaled onto [0, w-1], so full deflection is the last pixel
// rather than one past it.
state.set(
int(int64(rawX-minX)*int64(w)/int64(maxX-minX)),
int(int64(rawY-minY)*int64(h)/int64(maxY-minY)),
int(int64(rawX-minX)*int64(w-1)/int64(maxX-minX)),
int(int64(rawY-minY)*int64(h-1)/int64(maxY-minY)),
down)
}
}
+14 -2
View File
@@ -640,6 +640,20 @@ func run(aName, bName string, nsPerM float64) error {
defer wg.Done()
samp.run(&done, startTx)
}()
// Every return from here on stops the workers before the deferred closes
// pull their sockets out from under them: otherwise the sampler panics on a
// closed fd and can mask the error that actually ended the run. An error
// before the gate opens closes it here, or the wait would hang on
// goroutines still parked at startTx.
defer func() {
done.Store(true)
select {
case <-startTx:
default:
close(startTx)
}
wg.Wait()
}()
rxReady.Wait()
sig := make(chan os.Signal, 1)
@@ -674,8 +688,6 @@ func run(aName, bName string, nsPerM float64) error {
for {
select {
case <-sig:
done.Store(true)
wg.Wait()
return nil
case <-space:
start = resetAll(dirs, stats)
+5 -2
View File
@@ -170,10 +170,13 @@ func (p *probeSender) awaitTx(scratch, oob []byte) (int64, bool) {
fds := []unix.PollFd{{Fd: int32(p.fd), Events: unix.POLLERR}}
deadline := time.Now().Add(probeTimeout)
for {
ms := int(time.Until(deadline).Milliseconds())
if ms <= 0 {
left := time.Until(deadline)
if left <= 0 {
return 0, false
}
// Rounded up, since truncating would give up with time still on the
// clock and shave the last fraction of a millisecond off every wait.
ms := int((left + time.Millisecond - 1) / time.Millisecond)
n, err := unix.Poll(fds, ms)
if err == unix.EINTR {
continue
+3 -1
View File
@@ -75,8 +75,10 @@ func commas(v uint64) string {
// on the label. Below a thousand no letter is left dangling, since a trailing
// space would push the figure off centre.
func scaleSI(v float64) string {
// %.2f rounds 999.995 and up to a fourth digit, so the magnitude rolls over
// where the rounding does rather than at the bare thousand.
for _, mag := range []string{"", "k", "M", "G", "T"} {
if v < 1000 {
if v < 999.995 {
if mag == "" {
return fmt.Sprintf("%.2f", v)
}