2018-04-16 08:57:13 -04:00
|
|
|
package pipe
|
|
|
|
|
|
|
|
import (
|
2018-05-25 06:08:28 -04:00
|
|
|
"context"
|
|
|
|
|
|
|
|
"v2ray.com/core"
|
2018-04-16 08:57:13 -04:00
|
|
|
"v2ray.com/core/common/signal"
|
2018-06-08 22:47:37 -04:00
|
|
|
"v2ray.com/core/common/signal/done"
|
2018-04-16 08:57:13 -04:00
|
|
|
)
|
|
|
|
|
2018-05-25 17:20:24 -04:00
|
|
|
// Option for creating new Pipes.
|
2018-04-16 08:57:13 -04:00
|
|
|
type Option func(*pipe)
|
|
|
|
|
|
|
|
func WithoutSizeLimit() Option {
|
|
|
|
return func(p *pipe) {
|
|
|
|
p.limit = -1
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func WithSizeLimit(limit int32) Option {
|
|
|
|
return func(p *pipe) {
|
|
|
|
p.limit = limit
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-05-25 06:08:28 -04:00
|
|
|
func OptionsFromContext(ctx context.Context) []Option {
|
|
|
|
var opt []Option
|
|
|
|
|
|
|
|
bp := core.BufferPolicyFromContext(ctx)
|
2018-05-25 07:12:00 -04:00
|
|
|
if bp.PerConnection >= 0 {
|
|
|
|
opt = append(opt, WithSizeLimit(bp.PerConnection))
|
2018-05-25 06:08:28 -04:00
|
|
|
} else {
|
|
|
|
opt = append(opt, WithoutSizeLimit())
|
|
|
|
}
|
|
|
|
|
|
|
|
return opt
|
|
|
|
}
|
|
|
|
|
2018-04-16 18:45:38 -04:00
|
|
|
// New creates a new Reader and Writer that connects to each other.
|
2018-04-16 08:57:13 -04:00
|
|
|
func New(opts ...Option) (*Reader, *Writer) {
|
|
|
|
p := &pipe{
|
2018-05-25 07:12:00 -04:00
|
|
|
limit: -1,
|
2018-04-16 08:57:13 -04:00
|
|
|
readSignal: signal.NewNotifier(),
|
|
|
|
writeSignal: signal.NewNotifier(),
|
2018-06-08 22:47:37 -04:00
|
|
|
done: done.New(),
|
2018-04-16 08:57:13 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
for _, opt := range opts {
|
|
|
|
opt(p)
|
|
|
|
}
|
|
|
|
|
|
|
|
return &Reader{
|
|
|
|
pipe: p,
|
|
|
|
}, &Writer{
|
|
|
|
pipe: p,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-04-16 18:31:10 -04:00
|
|
|
type closeError interface {
|
|
|
|
CloseError()
|
|
|
|
}
|
|
|
|
|
2018-04-18 09:40:43 -04:00
|
|
|
// CloseError invokes CloseError() method if the object is either Reader or Writer.
|
2018-04-16 18:31:10 -04:00
|
|
|
func CloseError(v interface{}) {
|
|
|
|
if c, ok := v.(closeError); ok {
|
|
|
|
c.CloseError()
|
|
|
|
}
|
|
|
|
}
|