Skip to content

Commit f496437

Browse files
xxntmctxFanglidingRPRX
authored
XHTTP server: Refactor upload_queue.go (#6372)
#6372 (comment) --------- Co-authored-by: 风扇滑翔翼 <Fangliding.fshxy@outlook.com> Co-authored-by: RPRX <63339210+RPRX@users.noreply.github.com>
1 parent b12bc50 commit f496437

1 file changed

Lines changed: 36 additions & 57 deletions

File tree

transport/internet/splithttp/upload_queue.go

Lines changed: 36 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -6,101 +6,79 @@ package splithttp
66
import (
77
"container/heap"
88
"io"
9-
"runtime"
10-
"sync"
9+
"sync/atomic"
1110

1211
"github.com/xtls/xray-core/common/errors"
12+
"github.com/xtls/xray-core/common/signal/done"
1313
)
1414

1515
type Packet struct {
16-
Reader io.ReadCloser
16+
Reader *httpServerConn
1717
Payload []byte
1818
Seq uint64
1919
}
2020

2121
type uploadQueue struct {
22-
reader io.ReadCloser
23-
nomore bool
24-
pushedPackets chan Packet
25-
writeCloseMutex sync.Mutex
26-
heap uploadHeap
27-
nextSeq uint64
28-
closed bool
29-
maxPackets int
22+
reader atomic.Pointer[httpServerConn]
23+
pushedPackets chan Packet
24+
heap uploadHeap
25+
nextSeq uint64
26+
maxPackets int
27+
closed *done.Instance
3028
}
3129

3230
func NewUploadQueue(maxPackets int) *uploadQueue {
3331
return &uploadQueue{
3432
pushedPackets: make(chan Packet, maxPackets),
3533
heap: uploadHeap{},
3634
nextSeq: 0,
37-
closed: false,
35+
closed: done.New(),
3836
maxPackets: maxPackets,
3937
}
4038
}
4139

4240
func (h *uploadQueue) Push(p Packet) error {
43-
h.writeCloseMutex.Lock()
44-
defer h.writeCloseMutex.Unlock()
45-
46-
if h.closed {
47-
return errors.New("packet queue closed")
48-
}
49-
if h.nomore {
41+
if h.reader.Load() != nil || (p.Reader != nil && !h.reader.CompareAndSwap(nil, p.Reader)) {
5042
return errors.New("h.reader already exists")
5143
}
52-
if p.Reader != nil {
53-
h.nomore = true
44+
select {
45+
case h.pushedPackets <- p: // no panic
46+
if h.closed.Done() {
47+
return errors.New("packet queue closed")
48+
}
49+
return nil
50+
case <-h.closed.Wait():
51+
return errors.New("packet queue closed")
5452
}
55-
h.pushedPackets <- p
56-
return nil
5753
}
5854

5955
func (h *uploadQueue) Close() error {
60-
h.writeCloseMutex.Lock()
61-
defer h.writeCloseMutex.Unlock()
62-
63-
if !h.closed {
64-
h.closed = true
65-
runtime.Gosched() // hope Read() gets the packet
66-
f:
67-
for {
68-
select {
69-
case p := <-h.pushedPackets:
70-
if p.Reader != nil {
71-
h.reader = p.Reader
72-
}
73-
default:
74-
break f
75-
}
76-
}
77-
close(h.pushedPackets)
78-
}
79-
if h.reader != nil {
80-
return h.reader.Close()
56+
h.closed.Close()
57+
if reader := h.reader.Load(); reader != nil {
58+
return reader.Close()
8159
}
8260
return nil
8361
}
8462

8563
func (h *uploadQueue) Read(b []byte) (int, error) {
86-
if h.reader != nil {
87-
return h.reader.Read(b)
64+
if reader := h.reader.Load(); reader != nil {
65+
return reader.Read(b)
8866
}
8967

90-
if h.closed {
68+
if h.closed.Done() {
9169
return 0, io.EOF
9270
}
9371

9472
if len(h.heap) == 0 {
95-
packet, more := <-h.pushedPackets
96-
if !more {
73+
select {
74+
case p := <-h.pushedPackets:
75+
if p.Reader != nil {
76+
return p.Reader.Read(b)
77+
}
78+
heap.Push(&h.heap, p)
79+
case <-h.closed.Wait():
9780
return 0, io.EOF
9881
}
99-
if packet.Reader != nil {
100-
h.reader = packet.Reader
101-
return h.reader.Read(b)
102-
}
103-
heap.Push(&h.heap, packet)
10482
}
10583

10684
for len(h.heap) > 0 {
@@ -131,11 +109,12 @@ func (h *uploadQueue) Read(b []byte) (int, error) {
131109
return 0, errors.New("packet queue is too large")
132110
}
133111
heap.Push(&h.heap, packet)
134-
packet2, more := <-h.pushedPackets
135-
if !more {
112+
select {
113+
case p := <-h.pushedPackets:
114+
heap.Push(&h.heap, p)
115+
case <-h.closed.Wait():
136116
return 0, io.EOF
137117
}
138-
heap.Push(&h.heap, packet2)
139118
}
140119
}
141120

0 commit comments

Comments
 (0)