|
|
@@ -7,6 +7,7 @@ import (
|
|
|
"sync/atomic"
|
|
|
"time"
|
|
|
|
|
|
+ "v2ray.com/core/common"
|
|
|
"v2ray.com/core/common/buf"
|
|
|
"v2ray.com/core/common/signal"
|
|
|
"v2ray.com/core/common/signal/semaphore"
|
|
|
@@ -342,43 +343,12 @@ func (c *Connection) waitForDataOutput() error {
|
|
|
|
|
|
// Write implements io.Writer.
|
|
|
func (c *Connection) Write(b []byte) (int, error) {
|
|
|
- updatePending := false
|
|
|
- defer func() {
|
|
|
- if updatePending {
|
|
|
- c.dataUpdater.WakeUp()
|
|
|
- }
|
|
|
- }()
|
|
|
-
|
|
|
- for {
|
|
|
- totalWritten := 0
|
|
|
- for {
|
|
|
- if c == nil || c.State() != StateActive {
|
|
|
- return totalWritten, io.ErrClosedPipe
|
|
|
- }
|
|
|
- if !c.sendingWorker.Push(func(bb []byte) (int, error) {
|
|
|
- n := copy(bb[:c.mss], b[totalWritten:])
|
|
|
- totalWritten += n
|
|
|
- return n, nil
|
|
|
- }) {
|
|
|
- break
|
|
|
- }
|
|
|
-
|
|
|
- updatePending = true
|
|
|
-
|
|
|
- if totalWritten == len(b) {
|
|
|
- return totalWritten, nil
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- if updatePending {
|
|
|
- c.dataUpdater.WakeUp()
|
|
|
- updatePending = false
|
|
|
- }
|
|
|
-
|
|
|
- if err := c.waitForDataOutput(); err != nil {
|
|
|
- return totalWritten, err
|
|
|
- }
|
|
|
+ var mb buf.MultiBuffer
|
|
|
+ common.Must2(mb.Write(b))
|
|
|
+ if err := c.WriteMultiBuffer(mb); err != nil {
|
|
|
+ return 0, err
|
|
|
}
|
|
|
+ return len(b), nil
|
|
|
}
|
|
|
|
|
|
// WriteMultiBuffer implements buf.Writer.
|
|
|
@@ -392,19 +362,13 @@ func (c *Connection) WriteMultiBuffer(mb buf.MultiBuffer) error {
|
|
|
}
|
|
|
}()
|
|
|
|
|
|
- f := func(x *buf.MultiBuffer) buf.Supplier {
|
|
|
- return func(bb []byte) (int, error) {
|
|
|
- return x.Read(bb[:c.mss])
|
|
|
- }
|
|
|
- }(&mb)
|
|
|
-
|
|
|
for {
|
|
|
for {
|
|
|
if c == nil || c.State() != StateActive {
|
|
|
return io.ErrClosedPipe
|
|
|
}
|
|
|
|
|
|
- if !c.sendingWorker.Push(f) {
|
|
|
+ if !c.sendingWorker.Push(&mb) {
|
|
|
break
|
|
|
}
|
|
|
updatePending = true
|