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  }