github.com/insolar/vanilla@v0.0.0-20201023172447-248fdf805322/synckit/sync_queue.go (about)

     1  // Copyright 2020 Insolar Network Ltd.
     2  // All rights reserved.
     3  // This material is licensed under the Insolar License version 1.0,
     4  // available at https://github.com/insolar/assured-ledger/blob/master/LICENSE.md.
     5  
     6  package synckit
     7  
     8  import (
     9  	"sync"
    10  )
    11  
    12  func NewSyncQueue(locker sync.Locker) SyncQueue {
    13  	if locker == nil {
    14  		panic("illegal value")
    15  	}
    16  	return SyncQueue{locker: locker}
    17  }
    18  
    19  func NewSignalCondQueue(signal *sync.Cond) SyncQueue {
    20  	if signal == nil {
    21  		panic("illegal value")
    22  	}
    23  	return SyncQueue{locker: signal.L, signalFn: signal.Broadcast}
    24  }
    25  
    26  func NewSignalFuncQueue(locker sync.Locker, signalFn func()) SyncQueue {
    27  	if locker == nil {
    28  		panic("illegal value")
    29  	}
    30  	return SyncQueue{locker: locker, signalFn: signalFn}
    31  }
    32  
    33  func NewNoSyncQueue() SyncQueue {
    34  	return SyncQueue{locker: DummyLocker()}
    35  }
    36  
    37  type SyncFunc func(interface{})
    38  type SyncFuncList []SyncFunc
    39  
    40  type SyncQueue struct {
    41  	locker   sync.Locker
    42  	signalFn func()
    43  	queue    SyncFuncList
    44  }
    45  
    46  func (p *SyncQueue) Locker() sync.Locker {
    47  	return p.locker
    48  }
    49  
    50  func (p *SyncQueue) IsZero() bool {
    51  	return p.locker == nil
    52  }
    53  
    54  func (p *SyncQueue) Add(fn SyncFunc) {
    55  	if fn == nil {
    56  		panic("illegal value")
    57  	}
    58  	p.locker.Lock()
    59  	defer p.locker.Unlock()
    60  
    61  	p.queue = append(p.queue, fn)
    62  	if p.signalFn != nil {
    63  		p.signalFn()
    64  	}
    65  }
    66  
    67  func (p *SyncQueue) Flush() SyncFuncList {
    68  	p.locker.Lock()
    69  	defer p.locker.Unlock()
    70  
    71  	if len(p.queue) == 0 {
    72  		return nil
    73  	}
    74  
    75  	nextCap := cap(p.queue)
    76  	if nextCap > 128 && len(p.queue)<<1 < nextCap {
    77  		nextCap >>= 1
    78  	}
    79  	queue := p.queue
    80  	p.queue = make(SyncFuncList, 0, nextCap)
    81  
    82  	return queue
    83  }
    84  
    85  func (p *SyncQueue) AddAll(list SyncFuncList) {
    86  	if len(list) == 0 {
    87  		return
    88  	}
    89  
    90  	p.locker.Lock()
    91  	defer p.locker.Unlock()
    92  
    93  	p.queue = append(p.queue, list...)
    94  }