lock(&c.lock)
- if c.closed != 0 && c.qcount == 0 {
- if raceenabled {
- raceacquire(c.raceaddr())
+ if c.closed != 0 {
+ if c.qcount == 0 {
+ if raceenabled {
+ raceacquire(c.raceaddr())
+ }
+ unlock(&c.lock)
+ if ep != nil {
+ typedmemclr(c.elemtype, ep)
+ }
+ return true, false
}
- unlock(&c.lock)
- if ep != nil {
- typedmemclr(c.elemtype, ep)
+ // The channel has been closed, but the channel's buffer have data.
+ } else {
+ // Just found waiting sender with not closed.
+ if sg := c.sendq.dequeue(); sg != nil {
+ // Found a waiting sender. If buffer is size 0, receive value
+ // directly from sender. Otherwise, receive from head of queue
+ // and add sender's value to the tail of the queue (both map to
+ // the same buffer slot because the queue is full).
+ recv(c, sg, ep, func() { unlock(&c.lock) }, 3)
+ return true, true
}
- return true, false
- }
-
- if sg := c.sendq.dequeue(); sg != nil {
- // Found a waiting sender. If buffer is size 0, receive value
- // directly from sender. Otherwise, receive from head of queue
- // and add sender's value to the tail of the queue (both map to
- // the same buffer slot because the queue is full).
- recv(c, sg, ep, func() { unlock(&c.lock) }, 3)
- return true, true
}
if c.qcount > 0 {
}
}
+func BenchmarkReceiveDataFromClosedChan(b *testing.B) {
+ count := b.N
+ ch := make(chan struct{}, count)
+ for i := 0; i < count; i++ {
+ ch <- struct{}{}
+ }
+ close(ch)
+
+ b.ResetTimer()
+ for range ch {
+ }
+}
+
func BenchmarkChanCreation(b *testing.B) {
b.RunParallel(func(pb *testing.PB) {
for pb.Next() {