|
|
|
@ -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 |
|
|
|
|