github.com/criyle/go-sandbox@v0.10.3/container/socket_linux.go (about) 1 package container 2 3 import ( 4 "bytes" 5 "encoding/gob" 6 "fmt" 7 8 "github.com/criyle/go-sandbox/pkg/unixsocket" 9 ) 10 11 // 16k buffer size 12 const bufferSize = 16 << 10 13 14 type socket struct { 15 *unixsocket.Socket 16 17 buff []byte 18 19 decoder *gob.Decoder 20 recvBuff bufferRotator 21 22 encoder *gob.Encoder 23 sendBuff bytes.Buffer 24 } 25 26 // bufferRotator replace the underlying Buffers to avoid allocation 27 type bufferRotator struct { 28 *bytes.Buffer 29 } 30 31 func (b *bufferRotator) Rotate(buffer *bytes.Buffer) { 32 b.Buffer = buffer 33 } 34 35 func newSocket(s *unixsocket.Socket) *socket { 36 soc := socket{ 37 Socket: s, 38 } 39 soc.buff = make([]byte, bufferSize) 40 soc.decoder = gob.NewDecoder(&soc.recvBuff) 41 soc.encoder = gob.NewEncoder(&soc.sendBuff) 42 43 return &soc 44 } 45 46 func (s *socket) RecvMsg(e interface{}) (msg unixsocket.Msg, err error) { 47 n, msg, err := s.Socket.RecvMsg(s.buff) 48 if err != nil { 49 return msg, fmt.Errorf("RecvMsg: %v", err) 50 } 51 s.recvBuff.Rotate(bytes.NewBuffer(s.buff[:n])) 52 53 if err := s.decoder.Decode(e); err != nil { 54 return msg, fmt.Errorf("RecvMsg: failed to decode %v", err) 55 } 56 return msg, nil 57 } 58 59 func (s *socket) SendMsg(e interface{}, msg unixsocket.Msg) error { 60 s.sendBuff.Reset() 61 if err := s.encoder.Encode(e); err != nil { 62 return fmt.Errorf("SendMsg: failed to encode %v", err) 63 } 64 65 if err := s.Socket.SendMsg(s.sendBuff.Bytes(), msg); err != nil { 66 return fmt.Errorf("SendMsg: failed to SendMsg %v", err) 67 } 68 return nil 69 }