github.com/Finschia/finschia-sdk@v0.48.1/baseapp/accountwgs.go (about)

     1  package baseapp
     2  
     3  import (
     4  	"sync"
     5  
     6  	sdk "github.com/Finschia/finschia-sdk/types"
     7  )
     8  
     9  type AccountWGs struct {
    10  	mtx sync.Mutex
    11  	wgs map[string]*sync.WaitGroup
    12  }
    13  
    14  func NewAccountWGs() *AccountWGs {
    15  	return &AccountWGs{
    16  		wgs: make(map[string]*sync.WaitGroup),
    17  	}
    18  }
    19  
    20  func (aw *AccountWGs) Register(tx sdk.Tx) (waits []*sync.WaitGroup, signals []*AccountWG) {
    21  	signers := getUniqSigners(tx)
    22  
    23  	aw.mtx.Lock()
    24  	defer aw.mtx.Unlock()
    25  	for _, signer := range signers {
    26  		if wg := aw.wgs[signer]; wg != nil {
    27  			waits = append(waits, wg)
    28  		}
    29  		sig := waitGroup1()
    30  		aw.wgs[signer] = sig
    31  		signals = append(signals, NewAccountWG(signer, sig))
    32  	}
    33  
    34  	return waits, signals
    35  }
    36  
    37  func (aw *AccountWGs) Wait(waits []*sync.WaitGroup) {
    38  	for _, wait := range waits {
    39  		wait.Wait()
    40  	}
    41  }
    42  
    43  func (aw *AccountWGs) Done(signals []*AccountWG) {
    44  	aw.mtx.Lock()
    45  	defer aw.mtx.Unlock()
    46  
    47  	for _, signal := range signals {
    48  		signal.wg.Done()
    49  		if aw.wgs[signal.acc] == signal.wg {
    50  			delete(aw.wgs, signal.acc)
    51  		}
    52  	}
    53  }
    54  
    55  func getUniqSigners(tx sdk.Tx) []string {
    56  	seen := map[string]bool{}
    57  	var signers []string
    58  	for _, msg := range tx.GetMsgs() {
    59  		for _, addr := range msg.GetSigners() {
    60  			if !seen[addr.String()] {
    61  				signers = append(signers, string(addr))
    62  				seen[addr.String()] = true
    63  			}
    64  		}
    65  	}
    66  	return signers
    67  }
    68  
    69  type AccountWG struct {
    70  	acc string
    71  	wg  *sync.WaitGroup
    72  }
    73  
    74  func NewAccountWG(acc string, wg *sync.WaitGroup) *AccountWG {
    75  	return &AccountWG{
    76  		acc: acc,
    77  		wg:  wg,
    78  	}
    79  }
    80  
    81  func waitGroup1() (wg *sync.WaitGroup) {
    82  	wg = &sync.WaitGroup{}
    83  	wg.Add(1)
    84  	return wg
    85  }