Merge pull request #457 from xushiwei/q

fix #453 (select recv))
This commit is contained in:
xushiwei
2024-07-07 16:21:45 +08:00
committed by GitHub
2 changed files with 43 additions and 4 deletions

21
_demo/chandemo/chan.go Normal file
View File

@@ -0,0 +1,21 @@
package main
func main() {
c1 := make(chan string)
c2 := make(chan string, 1)
go func() {
c1 <- "ch1"
}()
go func() {
c2 <- "ch2"
}()
for i := 0; i < 2; i++ {
select {
case msg1 := <-c1:
println(msg1)
case msg2 := <-c2:
println(msg2)
}
}
}

View File

@@ -38,6 +38,7 @@ type Chan struct {
len int len int
cap int cap int
sops *selectOp sops *selectOp
sends uint16
close bool close bool
} }
@@ -108,7 +109,9 @@ func ChanSend(p *Chan, v unsafe.Pointer, eltSize int) bool {
p.mutex.Lock() p.mutex.Lock()
if n == 0 { if n == 0 {
for p.getp != chanHasRecv && !p.close { for p.getp != chanHasRecv && !p.close {
p.sends++
p.cond.Wait(&p.mutex) p.cond.Wait(&p.mutex)
p.sends--
} }
if p.close { if p.close {
p.mutex.Unlock() p.mutex.Unlock()
@@ -140,9 +143,13 @@ func ChanTryRecv(p *Chan, v unsafe.Pointer, eltSize int) (recvOK bool, tryOK boo
n := p.cap n := p.cap
p.mutex.Lock() p.mutex.Lock()
if n == 0 { if n == 0 {
if p.sends == 0 || p.getp == chanHasRecv || p.close {
tryOK = p.close tryOK = p.close
p.mutex.Unlock() p.mutex.Unlock()
return return
}
p.getp = chanHasRecv
p.data = v
} else { } else {
if p.len == 0 { if p.len == 0 {
tryOK = p.close tryOK = p.close
@@ -158,7 +165,18 @@ func ChanTryRecv(p *Chan, v unsafe.Pointer, eltSize int) (recvOK bool, tryOK boo
notifyOps(p) notifyOps(p)
p.mutex.Unlock() p.mutex.Unlock()
p.cond.Broadcast() p.cond.Broadcast()
return true, true if n == 0 {
p.mutex.Lock()
if p.getp == chanHasRecv {
p.cond.Wait(&p.mutex)
}
recvOK = (p.getp != chanHasRecv)
tryOK = recvOK
p.mutex.Unlock()
} else {
recvOK, tryOK = true, true
}
return
} }
func ChanRecv(p *Chan, v unsafe.Pointer, eltSize int) (recvOK bool) { func ChanRecv(p *Chan, v unsafe.Pointer, eltSize int) (recvOK bool) {