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.
This commit is contained in:
Ayke van Laethem
2023-02-22 17:44:34 +01:00
committed by Ron Evans
parent 488174767b
commit 8bf94b9231
+7 -1
View File
@@ -2,7 +2,10 @@
package task
import "unsafe"
import (
"runtime/interrupt"
"unsafe"
)
//go:linkname runtimePanic runtime.runtimePanic
func runtimePanic(str string)
@@ -45,6 +48,9 @@ func Pause() {
if *currentTask.state.canaryPtr != stackCanary {
runtimePanic("goroutine stack overflow")
}
if interrupt.In() {
runtimePanic("blocked inside interrupt")
}
currentTask.state.pause()
}