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 }