diff options
author | Kevin Kuehler <keur@ocf.berkeley.edu> | 2019-05-25 02:06:15 -0700 |
---|---|---|
committer | Drew DeVault <sir@cmpwn.com> | 2019-06-01 11:09:14 -0400 |
commit | 3445b80d7a710edf72088d6faea1f640988b1766 (patch) | |
tree | ea8e4feca11d26b07a26e6331441baa0b9dd80ca | |
parent | 0bfb90baedbde0bb5a862e6a8fe9ec7e56d664e5 (diff) |
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>
-rw-r--r-- | widgets/terminal.go | 25 |
1 files changed, 15 insertions, 10 deletions
diff --git a/widgets/terminal.go b/widgets/terminal.go index ecb26aa..82190cc 100644 --- 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 } |