mirror of
https://github.com/kovidgoyal/kitty
synced 2026-07-18 06:25:13 +02:00
Make various goroutines panic-safe
This commit is contained in:
@@ -321,7 +321,7 @@ func (self *Context) run_paste(src Scanner, background image.Image, pos image.Po
|
||||
default:
|
||||
panic(fmt.Sprintf("Unsupported image type: %v", v))
|
||||
}
|
||||
self.Parallel(interRect.Min.Y, interRect.Max.Y, func(ys <-chan int) {
|
||||
if err := self.SafeParallel(interRect.Min.Y, interRect.Max.Y, func(ys <-chan int) {
|
||||
for y := range ys {
|
||||
x1 := interRect.Min.X - pasteRect.Min.X
|
||||
x2 := interRect.Max.X - pasteRect.Min.X
|
||||
@@ -333,7 +333,9 @@ func (self *Context) run_paste(src Scanner, background image.Image, pos image.Po
|
||||
src.scan(x1, y1, x2, y2, dst)
|
||||
postprocess(dst)
|
||||
}
|
||||
})
|
||||
}); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -27,18 +27,20 @@ func reverse_row(bytes_per_pixel int, pix []uint8) {
|
||||
|
||||
func (self *Context) FlipPixelsH(bytes_per_pixel, width, height int, pix []uint8) {
|
||||
stride := bytes_per_pixel * width
|
||||
self.Parallel(0, height, func(ys <-chan int) {
|
||||
if err := self.SafeParallel(0, height, func(ys <-chan int) {
|
||||
for y := range ys {
|
||||
i := y * stride
|
||||
reverse_row(bytes_per_pixel, pix[i:i+stride])
|
||||
}
|
||||
})
|
||||
}); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
func (self *Context) FlipPixelsV(bytes_per_pixel, width, height int, pix []uint8) {
|
||||
stride := bytes_per_pixel * width
|
||||
num := height / 2
|
||||
self.Parallel(0, num, func(ys <-chan int) {
|
||||
if err := self.SafeParallel(0, num, func(ys <-chan int) {
|
||||
for y := range ys {
|
||||
upper := y
|
||||
lower := height - 1 - y
|
||||
@@ -50,6 +52,7 @@ func (self *Context) FlipPixelsV(bytes_per_pixel, width, height int, pix []uint8
|
||||
as[i], bs[i] = bs[i], as[i]
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
}); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,6 +7,8 @@ import (
|
||||
"runtime"
|
||||
"sync"
|
||||
"sync/atomic"
|
||||
|
||||
"github.com/kovidgoyal/kitty/tools/utils"
|
||||
)
|
||||
|
||||
var _ = fmt.Print
|
||||
@@ -31,8 +33,10 @@ func (self *Context) EffectiveNumberOfThreads() int {
|
||||
return ans
|
||||
}
|
||||
|
||||
// parallel processes the data in separate goroutines.
|
||||
func (self *Context) Parallel(start, stop int, fn func(<-chan int)) {
|
||||
// parallel processes the data in separate goroutines. If any of them panics,
|
||||
// returns an error. Note that if multiple goroutines panic, only one error is
|
||||
// returned.
|
||||
func (self *Context) SafeParallel(start, stop int, fn func(<-chan int)) (err error) {
|
||||
count := stop - start
|
||||
if count < 1 {
|
||||
return
|
||||
@@ -49,9 +53,16 @@ func (self *Context) Parallel(start, stop int, fn func(<-chan int)) {
|
||||
for range procs {
|
||||
wg.Add(1)
|
||||
go func() {
|
||||
defer wg.Done()
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
text, _ := utils.Format_stacktrace_on_panic(r)
|
||||
err = fmt.Errorf("%s", text)
|
||||
}
|
||||
wg.Done()
|
||||
}()
|
||||
fn(c)
|
||||
}()
|
||||
}
|
||||
wg.Wait()
|
||||
return
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user