@@ -6,101 +6,79 @@ package splithttp
66import (
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
1515type Packet struct {
16- Reader io. ReadCloser
16+ Reader * httpServerConn
1717 Payload []byte
1818 Seq uint64
1919}
2020
2121type 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
3230func 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
4240func (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
5955func (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
8563func (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