package http2
import (
)
type roundRobinWriteScheduler struct {
control writeQueue
streams map[uint32]*writeQueue
head *writeQueue
queuePool writeQueuePool
}
func () WriteScheduler {
:= &roundRobinWriteScheduler{
streams: make(map[uint32]*writeQueue),
}
return
}
func ( *roundRobinWriteScheduler) ( uint32, OpenStreamOptions) {
if .streams[] != nil {
panic(fmt.Errorf("stream %d already opened", ))
}
:= .queuePool.get()
.streams[] =
if .head == nil {
.head =
.next =
.prev =
} else {
.prev = .head.prev
.next = .head
.prev.next =
.next.prev =
}
}
func ( *roundRobinWriteScheduler) ( uint32) {
:= .streams[]
if == nil {
return
}
if .next == {
.head = nil
} else {
.prev.next = .next
.next.prev = .prev
if .head == {
.head = .next
}
}
delete(.streams, )
.queuePool.put()
}
func ( *roundRobinWriteScheduler) ( uint32, PriorityParam) {}
func ( *roundRobinWriteScheduler) ( FrameWriteRequest) {
if .isControl() {
.control.push()
return
}
:= .streams[.StreamID()]
if == nil {
if .DataSize() > 0 {
panic("add DATA on non-open stream")
}
.control.push()
return
}
.push()
}
func ( *roundRobinWriteScheduler) () (FrameWriteRequest, bool) {
if !.control.empty() {
return .control.shift(), true
}
if .head == nil {
return FrameWriteRequest{}, false
}
:= .head
for {
if , := .consume(math.MaxInt32); {
.head = .next
return , true
}
= .next
if == .head {
break
}
}
return FrameWriteRequest{}, false
}