I guess a more correct impl would be:
func (c *Channel[M]) Receive() M {
c.sizeSema.Acquire()
c.mutex.Lock()
v := c.buffer.Remove(c.buffer.Front()).(M)
c.mutex.Unlock()
c.capacitySema.Release()
return v
}
In the original implementation, if 100 goroutines call Receive() on an empty channel, all of them execute the first line capacitySema.Release() but then block at sizeSema.Acquire(). If then 100 Send() calls occur, they would all fill the buffer unchecked. Right?