listing7.14 Receive early c.capacitySema.Release() call?
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?
Hi there and thank you for your feedback.
In the original implementation we wanted to implement synchronous behaviour similar to the Go channels. In the implementation, when we want synchronous behaviour we create a Channel with capacity of 0. This will enable a producer to wait on the capacitySema until there is a consumer. Once a consumer calls Receive, the c.capacitySema.Release() will unblock producer's Acquire() and the message will be exchange via the buffer.
The problem with the above implementation is that it doesn't support synchronous behaviour similar to the Go channels. The above implementation will block indefinitely when you specify a capacity of 0.