2026-05-30
notes
tech
hchan struct at channel creation. A heap allocated circular buffer protected by a mutex. sendx and recvx. The reference to this hchan struct is maintained in the goroutine stacksendq and a recvq that are doubly linked lists. The data type is a waitq. The buffer points to a circular queue. The each data type in this LL is a sudog type and has an unsafe pointer to an element. This is the memory address of a variable. This also holds g type which is a reference object or the identity of the go routine holding data about waiting, the status of the routineBuffered channel
buf where we write to the circular queuech <- 3 we push a value into the channel. In the case when its full, we create a sudog object as we cannot write to the channel buffer. This sudog object is placed in the sendq DLL and this is our queue for items that are trying to be written to the buffer.gopark and the go scheduler changes the state of the go routine to waiting.result <- ch will read from the buf circular queue.ch <- 1
ch <- 2
ch <- 3 // this is pushed to sendq
res <- ch // 1
// sendq value of 3 pushed into queue
res <- ch // 2
res <- ch // 3
res <- ch // we now call gopark as there is nothign in the buf. We have a sudog allocated and puhsed into the recvq
buf we directly do a memcopy() to the recv. We directly copy to goroutine stack and we do not touch the circular queue buffunc recv(c *hchan, sg *sudog, ep unsafe.Pointer, unlockf func(), skip int) {
// snip
if c.dataqsiz == 0 {
if raceenabled {
racesync(c, sg)
}
if ep != nil {
// copy data from sender
recvDirect(c.elemtype, sg, ep)
}
// snip
}
// snip
}
func recvDirect(t *_type, sg *sudog, dst unsafe.Pointer) {
// dst is on our stack or the heap, src is on another stack.
// The channel is locked, so src will not move during this
// operation.
src := sg.elem.get()
typeBitsBulkBarrier(t, uintptr(dst), uintptr(src), t.Size_)
memmove(dst, src, t.Size_)
}
Unbuffered channel flow
Select statement
select {
case <-ch1:
case <-ch2:
default: // default non blocking exit
}
select { // blocking multi-select
case <-ch1:
case <-ch2:
}
Patterns
dbw by hashicorp (https://github.com/hashicorp/go-dbw) as a database wrapper in boundary
io.Copy in goroutine to prevent blocking stackoverflow.com