github.com/Schaudge/grailbase@v0.0.0-20240223061707-44c758a471c0/syncqueue/lifo.go (about) 1 // Copyright 2018 GRAIL, Inc. All rights reserved. 2 // Use of this source code is governed by the Apache-2.0 3 // license that can be found in the LICENSE file. 4 5 package syncqueue 6 7 import ( 8 "sync" 9 ) 10 11 // LIFO implements a last-in, first-out producer-consumer queue. Thread safe. 12 type LIFO struct { 13 mu sync.Mutex 14 cond *sync.Cond 15 queue []interface{} 16 closed bool 17 } 18 19 // NewFIFO creates an empty FIFO queue. 20 func NewLIFO() *LIFO { 21 q := &LIFO{} 22 q.cond = sync.NewCond(&q.mu) 23 return q 24 } 25 26 // Put adds the object in the queue. 27 func (q *LIFO) Put(v interface{}) { 28 q.mu.Lock() 29 q.queue = append(q.queue, v) 30 q.cond.Signal() 31 q.mu.Unlock() 32 } 33 34 // Close informs the queue that no more objects will be added via Put(). 35 func (q *LIFO) Close() { 36 q.closed = true 37 q.cond.Broadcast() 38 } 39 40 // Get removes the newest object added to the queue. It blocks the caller if 41 // the queue is empty. 42 func (q *LIFO) Get() (interface{}, bool) { 43 q.mu.Lock() 44 for !q.closed && len(q.queue) == 0 { 45 q.cond.Wait() 46 } 47 var v interface{} 48 var ok bool 49 if n := len(q.queue); n > 0 { 50 v = q.queue[n-1] 51 q.queue = q.queue[:n-1] 52 ok = true 53 } 54 q.mu.Unlock() 55 return v, ok 56 }