hrtools/server/queue.go

77 lines
1.1 KiB
Go
Raw Normal View History

2021-04-28 06:11:24 +00:00
package main
import (
"container/list"
"sync"
"github.com/474420502/focus/compare"
pqueuekey "github.com/474420502/focus/priority_queuekey"
)
type Task struct {
Value int
}
type Queue struct {
lock sync.Mutex
count uint64
waitChans *list.List
queue *pqueuekey.PriorityQueue
}
func NewQueue() *Queue {
return &Queue{
waitChans: list.New(),
queue: pqueuekey.New(compare.UInt64),
}
}
func (q *Queue) Push(task *Task) {
q.lock.Lock()
defer q.lock.Unlock()
if q.waitChans.Len() != 0 {
element := q.waitChans.Front()
ctask := element.Value.(chan *Task)
ctask <- task
q.waitChans.Remove(element)
return
}
q.count++
q.queue.Push(q.count, task)
}
func (q *Queue) Pop() (task *Task) {
q.lock.Lock()
defer q.lock.Unlock()
q.count++
if itask, ok := q.queue.Pop(); ok {
return itask.(*Task)
}
return nil
}
func (q *Queue) popBlock(task chan *Task) {
q.lock.Lock()
defer q.lock.Unlock()
if q.queue.Size() != 0 {
itask, _ := q.queue.Pop()
go func() { task <- itask.(*Task) }()
return
}
q.waitChans.PushBack(task)
}
func (q *Queue) PopBlock() *Task {
task := make(chan *Task)
q.popBlock(task)
return (<-task)
}