github.com/nyan233/littlerpc@v0.4.6-0.20230316182519-0c8d5c48abaf/core/server/event.go (about) 1 package server 2 3 import "sync" 4 5 type eventList struct { 6 done chan int 7 next *eventList 8 } 9 10 type event struct { 11 mu sync.Mutex 12 ev int 13 // 用于确认所有的等待已经完成 14 ackWait sync.WaitGroup 15 link *eventList 16 } 17 18 func newEvent() *event { 19 return &event{ 20 ev: -1, 21 } 22 } 23 24 // Entry 进入一个事件 25 func (e *event) Entry(ev int) bool { 26 if !e.mu.TryLock() { 27 return false 28 } 29 defer e.mu.Unlock() 30 if e.ev > 0 { 31 return false 32 } 33 e.ev = ev 34 return true 35 } 36 37 // Complete 完成一个事件, 返回时所有等待者已经完成了任务 38 func (e *event) Complete(ev int) bool { 39 if !e.mu.TryLock() { 40 return false 41 } 42 defer e.mu.Unlock() 43 if e.ev < 0 || e.ev != ev { 44 return false 45 } 46 for e.link != nil { 47 e.link.done <- ev 48 e.link = e.link.next 49 } 50 e.ev = -1 51 e.ackWait.Wait() 52 return true 53 } 54 55 // Wait 等待一个事件完成, done用于接收(*event).Complete()是否已经被调用 56 // ack用于确认一个等待者是否已经完成了操作, 未进入事件时不允许等待 57 func (e *event) Wait() (done chan int, ack func(), ok bool) { 58 e.mu.Lock() 59 if e.ev < 0 { 60 e.mu.Unlock() 61 return nil, nil, false 62 } 63 defer e.mu.Unlock() 64 e.link = &eventList{ 65 done: make(chan int, 1), 66 next: e.link, 67 } 68 done = e.link.done 69 e.ackWait.Add(1) 70 var called bool 71 ack = func() { 72 if called { 73 panic("ackWait already called") 74 } 75 called = true 76 e.ackWait.Done() 77 } 78 ok = true 79 return 80 }