Skip to content

Instantly share code, notes, and snippets.

@joetIO
Last active January 31, 2022 10:32
Show Gist options
  • Save joetIO/ca0cfcf9dc87905d37a4fee7beb253c2 to your computer and use it in GitHub Desktop.
Save joetIO/ca0cfcf9dc87905d37a4fee7beb253c2 to your computer and use it in GitHub Desktop.
Checks if a Go channel is closed without touching/reading it (a very bad idea please do not use :) i was like 16 years old when i wrote this hacking go runtime, it's just a nice hack but def not memory safe lmao)
package main
import (
"fmt"
"unsafe"
"reflect"
)
func isChanClosed(ch interface{}) bool {
if reflect.TypeOf(ch).Kind() != reflect.Chan {
panic("only channels!")
}
// get interface value pointer, from cgo_export
// typedef struct { void *t; void *v; } GoInterface;
// then get channel real pointer
cptr := *(*uintptr)(unsafe.Pointer(
unsafe.Pointer(uintptr(unsafe.Pointer(&ch)) + unsafe.Sizeof(uint(0))),
))
// this function will return true if chan.closed > 0
// see hchan on https://github.com/golang/go/blob/master/src/runtime/chan.go
// type hchan struct {
// qcount uint // total data in the queue
// dataqsiz uint // size of the circular queue
// buf unsafe.Pointer // points to an array of dataqsiz elements
// elemsize uint16
// closed uint32
// **
cptr += unsafe.Sizeof(uint(0))*2
cptr += unsafe.Sizeof(unsafe.Pointer(uintptr(0)))
cptr += unsafe.Sizeof(uint16(0))
return *(*uint32)(unsafe.Pointer(cptr)) > 0
}
func main() {
ch := make(chan int64)
fmt.Println(isChanClosed(ch)) // -> false
close(ch)
fmt.Println(isChanClosed(ch)) // -> true
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment