use buffer pool and disable mutex

Signed-off-by: Vasiliy Tolstov <v.tolstov@selfip.ru>
This commit is contained in:
Василий Толстов 2017-06-18 22:38:59 +03:00
parent c8905c0ea9
commit ff60108c41
4 changed files with 44 additions and 18 deletions

View File

@ -71,8 +71,8 @@ func (c *ClientConn) UnreadByte() error {
} }
func (c *ClientConn) Flush() error { func (c *ClientConn) Flush() error {
c.m.Lock() // c.m.Lock()
defer c.m.Unlock() // defer c.m.Unlock()
return c.bw.Flush() return c.bw.Flush()
} }
@ -85,8 +85,8 @@ func (c *ClientConn) Read(buf []byte) (int, error) {
} }
func (c *ClientConn) Write(buf []byte) (int, error) { func (c *ClientConn) Write(buf []byte) (int, error) {
c.m.Lock() // c.m.Lock()
defer c.m.Unlock() // defer c.m.Unlock()
return c.bw.Write(buf) return c.bw.Write(buf)
} }

View File

@ -9,6 +9,7 @@ import (
"image/draw" "image/draw"
"image/png" "image/png"
"io" "io"
"sync"
) )
// EncodingType represents a known VNC encoding type. // EncodingType represents a known VNC encoding type.
@ -85,6 +86,15 @@ const (
TightFilterGradient TightFilter = 2 TightFilterGradient TightFilter = 2
) )
var bPool = sync.Pool{
New: func() interface{} {
// The Pool's New function should generally only return pointer
// types, since a pointer can be put into the return interface
// value without an allocation:
return new(bytes.Buffer)
},
}
type Encoding interface { type Encoding interface {
Type() EncodingType Type() EncodingType
Read(Conn, *Rectangle) error Read(Conn, *Rectangle) error
@ -197,14 +207,18 @@ func (enc *TightPngEncoding) Write(c Conn, rect *Rectangle) error {
cmp := enc.TightCC.Compression cmp := enc.TightCC.Compression
switch cmp { switch cmp {
case TightCompressionPNG: case TightCompressionPNG:
buf := bytes.NewBuffer(nil) buf := bPool.Get().(*bytes.Buffer)
if err := png.Encode(buf, enc.Image); err != nil { buf.Reset()
defer bPool.Put(buf)
pngEnc := &png.Encoder{CompressionLevel: png.BestSpeed}
if err := pngEnc.Encode(buf, enc.Image); err != nil {
return err return err
} }
if err := writeTightLength(c, buf.Len()); err != nil { if err := writeTightLength(c, buf.Len()); err != nil {
return err return err
} }
if _, err := io.Copy(c, buf); err != nil {
if _, err := buf.WriteTo(c); err != nil {
return err return err
} }
case TightCompressionFill: case TightCompressionFill:
@ -311,8 +325,9 @@ func readTightLength(c Conn) (int, error) {
} }
func (enc *RawEncoding) Write(c Conn, rect *Rectangle) error { func (enc *RawEncoding) Write(c Conn, rect *Rectangle) error {
buf := bytes.NewBuffer(nil) buf := bPool.Get().(*bytes.Buffer)
defer buf.Reset() buf.Reset()
defer bPool.Put(buf)
n := 0 n := 0
for _, c := range enc.Colors { for _, c := range enc.Colors {
bytes, err := c.Marshal() bytes, err := c.Marshal()
@ -325,13 +340,16 @@ func (enc *RawEncoding) Write(c Conn, rect *Rectangle) error {
return err return err
} }
} }
_, err := c.Write(buf.Bytes())
_, err := buf.WriteTo(c)
return err return err
} }
// Read implements the Encoding interface. // Read implements the Encoding interface.
func (enc *RawEncoding) Read(c Conn, rect *Rectangle) error { func (enc *RawEncoding) Read(c Conn, rect *Rectangle) error {
buf := bytes.NewBuffer(nil) buf := bPool.Get().(*bytes.Buffer)
buf.Reset()
defer bPool.Put(buf)
pf := c.PixelFormat() pf := c.PixelFormat()
cm := c.ColorMap() cm := c.ColorMap()
bytesPerPixel := int(pf.BPP / 8) bytesPerPixel := int(pf.BPP / 8)
@ -341,7 +359,6 @@ func (enc *RawEncoding) Read(c Conn, rect *Rectangle) error {
return err return err
} }
buf.Write(data) buf.Write(data)
defer buf.Reset()
colors := make([]Color, rect.Area()) colors := make([]Color, rect.Area())
for y := uint16(0); y < rect.Height; y++ { for y := uint16(0); y < rect.Height; y++ {
for x := uint16(0); x < rect.Width; x++ { for x := uint16(0); x < rect.Width; x++ {

View File

@ -93,7 +93,10 @@ func (pf *PixelFormat) Marshal() ([]byte, error) {
} }
// Create the slice of bytes // Create the slice of bytes
buf := bytes.NewBuffer(nil) buf := bPool.Get().(*bytes.Buffer)
buf.Reset()
defer bPool.Put(buf)
if err := binary.Write(buf, binary.BigEndian, &pf); err != nil { if err := binary.Write(buf, binary.BigEndian, &pf); err != nil {
return nil, err return nil, err
} }
@ -112,7 +115,13 @@ func (pf *PixelFormat) Read(r io.Reader) error {
// Unmarshal implements the Unmarshaler interface. // Unmarshal implements the Unmarshaler interface.
func (pf *PixelFormat) Unmarshal(data []byte) error { func (pf *PixelFormat) Unmarshal(data []byte) error {
buf := bytes.NewBuffer(data) buf := bPool.Get().(*bytes.Buffer)
buf.Reset()
defer bPool.Put(buf)
if _, err := buf.Write(data); err != nil {
return err
}
var msg PixelFormat var msg PixelFormat
if err := binary.Read(buf, binary.BigEndian, &msg); err != nil { if err := binary.Read(buf, binary.BigEndian, &msg); err != nil {

View File

@ -53,8 +53,8 @@ func (c *ServerConn) SetProtoVersion(pv string) {
} }
func (c *ServerConn) Flush() error { func (c *ServerConn) Flush() error {
c.m.Lock() // c.m.Lock()
defer c.m.Unlock() // defer c.m.Unlock()
return c.bw.Flush() return c.bw.Flush()
} }
@ -76,8 +76,8 @@ func (c *ServerConn) Read(buf []byte) (int, error) {
} }
func (c *ServerConn) Write(buf []byte) (int, error) { func (c *ServerConn) Write(buf []byte) (int, error) {
c.m.Lock() // c.m.Lock()
defer c.m.Unlock() // defer c.m.Unlock()
return c.bw.Write(buf) return c.bw.Write(buf)
} }