internal/task: disallow blocking inside an interrupt
Blocking inside an interrupt is always unsafe and will lead to all kinds of bad behavior (even if it might appear to work sometimes). So disallow it, just like allocating heap memory inside an interrupt is not allowed. I suspect this will usually be caused by channel sends, like this: ch <- someValue The easy workaround is to make it a non-blocking send instead: select { case ch <- someValue: default: } This does mean the application might become a bit more complex to be able to deal with this case, but the alternative (undefined behavior) is IMHO much worse.
Этот коммит содержится в:
родитель
488174767b
коммит
8bf94b9231
1 изменённых файлов: 7 добавлений и 1 удалений
|
@ -2,7 +2,10 @@
|
||||||
|
|
||||||
package task
|
package task
|
||||||
|
|
||||||
import "unsafe"
|
import (
|
||||||
|
"runtime/interrupt"
|
||||||
|
"unsafe"
|
||||||
|
)
|
||||||
|
|
||||||
//go:linkname runtimePanic runtime.runtimePanic
|
//go:linkname runtimePanic runtime.runtimePanic
|
||||||
func runtimePanic(str string)
|
func runtimePanic(str string)
|
||||||
|
@ -45,6 +48,9 @@ func Pause() {
|
||||||
if *currentTask.state.canaryPtr != stackCanary {
|
if *currentTask.state.canaryPtr != stackCanary {
|
||||||
runtimePanic("goroutine stack overflow")
|
runtimePanic("goroutine stack overflow")
|
||||||
}
|
}
|
||||||
|
if interrupt.In() {
|
||||||
|
runtimePanic("blocked inside interrupt")
|
||||||
|
}
|
||||||
currentTask.state.pause()
|
currentTask.state.pause()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Загрузка…
Создание таблицы
Сослаться в новой задаче