diff --git a/connection.go b/connection.go index 2d83372..cd07ae0 100644 --- a/connection.go +++ b/connection.go @@ -79,7 +79,8 @@ type Connection struct { cancelFuncs map[uint64]func() // Freelists, serviced by freelists.go. - inMessages freelist.Freelist // GUARDED_BY(mu) + inMessages freelist.Freelist // GUARDED_BY(mu) + outMessages freelist.Freelist // GUARDED_BY(mu) } // State that is maintained for each in-flight op. This is stuffed into the diff --git a/conversions.go b/conversions.go index ee3b97d..6682487 100644 --- a/conversions.go +++ b/conversions.go @@ -387,35 +387,31 @@ func convertInMessage( // Outgoing messages //////////////////////////////////////////////////////////////////////// -// Return the response that should be sent to the kernel. If the op requires no -// response, return a nil response. -func kernelResponse( +// Return the response that should be sent to the kernel, or nil if the op +// requires no response. +func (c *Connection) kernelResponse( fuseID uint64, op interface{}, - opErr error, - protocol fusekernel.Protocol) (msg []byte) { - // If the user replied with an error, create room enough just for the result - // header and fill it in with an error. Otherwise create an appropriate + opErr error) (m *buffer.OutMessage) { + // If the user replied with an error, create a response containing just the + // result header with the error filled in. Otherwise create an appropriate // response. - var b buffer.OutMessage if opErr != nil { - b = buffer.NewOutMessage(0) + m = c.getOutMessage() if errno, ok := opErr.(syscall.Errno); ok { - b.OutHeader().Error = -int32(errno) + m.OutHeader().Error = -int32(errno) } else { - b.OutHeader().Error = -int32(syscall.EIO) + m.OutHeader().Error = -int32(syscall.EIO) } } else { - b = kernelResponseForOp(op, protocol) + m = c.kernelResponseForOp(op) } - msg = b.Bytes() - // Fill in the rest of the header, if a response is required. - if msg != nil { - h := b.OutHeader() + if m != nil { + h := m.OutHeader() h.Unique = fuseID - h.Len = uint32(len(msg)) + h.Len = uint32(m.Len()) } return diff --git a/freelists.go b/freelists.go index cae6eee..368a618 100644 --- a/freelists.go +++ b/freelists.go @@ -20,14 +20,20 @@ import ( "github.com/jacobsa/fuse/internal/buffer" ) +//////////////////////////////////////////////////////////////////////// +// buffer.InMessage +//////////////////////////////////////////////////////////////////////// + // LOCKS_EXCLUDED(c.mu) -func (c *Connection) getInMessage() (m *buffer.InMessage) { +func (c *Connection) getInMessage() (x *buffer.InMessage) { c.mu.Lock() - m = (*buffer.InMessage)(c.inMessages.Get()) - if m == nil { - m = new(buffer.InMessage) - } + x = (*buffer.InMessage)(c.inMessages.Get()) c.mu.Unlock() + + if x == nil { + x = new(buffer.InMessage) + } + return } @@ -37,3 +43,28 @@ func (c *Connection) putInMessage(x *buffer.InMessage) { c.inMessages.Put(unsafe.Pointer(x)) c.mu.Unlock() } + +//////////////////////////////////////////////////////////////////////// +// buffer.OutMessage +//////////////////////////////////////////////////////////////////////// + +// LOCKS_EXCLUDED(c.mu) +func (c *Connection) getOutMessage() (x *buffer.OutMessage) { + c.mu.Lock() + x = (*buffer.OutMessage)(c.outMessages.Get()) + c.mu.Unlock() + + if x == nil { + x = new(buffer.OutMessage) + } + x.Reset() + + return +} + +// LOCKS_EXCLUDED(c.mu) +func (c *Connection) putOutMessage(x *buffer.OutMessage) { + c.mu.Lock() + c.outMessages.Put(unsafe.Pointer(x)) + c.mu.Unlock() +}