aerc

Working clone of aerc-mail.org
git clone git://git.danielmoch.com/aerc.git
Log | Files | Refs | README | LICENSE

commit 3445b80d7a710edf72088d6faea1f640988b1766
parent 0bfb90baedbde0bb5a862e6a8fe9ec7e56d664e5
Author: Kevin Kuehler <keur@ocf.berkeley.edu>
Date:   Sat, 25 May 2019 02:06:15 -0700

widgets/terminal: Don't segfault on resize

vterm.Write and vterm.SetSize race when the window resizes, which
causing the underlying library to segfault.

Signed-off-by: Kevin Kuehler <keur@ocf.berkeley.edu>

Diffstat:
Mwidgets/terminal.go | 25+++++++++++++++----------
1 file changed, 15 insertions(+), 10 deletions(-)

diff --git a/widgets/terminal.go b/widgets/terminal.go @@ -101,8 +101,9 @@ type Terminal struct { start chan interface{} vterm *vterm.VTerm - damage []vterm.Rect // protected by mutex - mutex sync.Mutex + damage []vterm.Rect // protected by damageMutex + damageMutex sync.Mutex + writeMutex sync.Mutex OnClose func(err error) OnEvent func(event tcell.Event) bool @@ -129,7 +130,9 @@ func NewTerminal(cmd *exec.Cmd) (*Terminal, error) { term.Close(nil) return } + term.writeMutex.Lock() n, err = term.vterm.Write(buf[:n]) + term.writeMutex.Unlock() if err != nil { term.Close(err) return @@ -204,9 +207,9 @@ func (term *Terminal) Invalidate() { if term.vterm != nil { width, height := term.vterm.Size() rect := vterm.NewRect(0, width, 0, height) - term.mutex.Lock() + term.damageMutex.Lock() term.damage = append(term.damage, *rect) - term.mutex.Unlock() + term.damageMutex.Unlock() } term.invalidate() } @@ -247,12 +250,14 @@ func (term *Terminal) Draw(ctx *ui.Context) { return } if ctx.Width() != cols || ctx.Height() != rows { + term.writeMutex.Lock() pty.Setsize(term.pty, &winsize) term.vterm.SetSize(ctx.Height(), ctx.Width()) + term.writeMutex.Unlock() rect := vterm.NewRect(0, ctx.Width(), 0, ctx.Height()) - term.mutex.Lock() + term.damageMutex.Lock() term.damage = append(term.damage, *rect) - term.mutex.Unlock() + term.damageMutex.Unlock() return } } @@ -267,7 +272,7 @@ func (term *Terminal) Draw(ctx *ui.Context) { // naive optimization visited := make(map[coords]interface{}) - term.mutex.Lock() + term.damageMutex.Lock() for _, rect := range term.damage { for x := rect.StartCol(); x < rect.EndCol() && x < ctx.Width(); x += 1 { @@ -290,7 +295,7 @@ func (term *Terminal) Draw(ctx *ui.Context) { } term.damage = nil - term.mutex.Unlock() + term.damageMutex.Unlock() if term.focus && !term.closed { if !term.cursorShown { @@ -414,9 +419,9 @@ func (term *Terminal) styleFromCell(cell *vterm.ScreenCell) tcell.Style { } func (term *Terminal) onDamage(rect *vterm.Rect) int { - term.mutex.Lock() + term.damageMutex.Lock() term.damage = append(term.damage, *rect) - term.mutex.Unlock() + term.damageMutex.Unlock() term.invalidate() return 1 }