Move where out messages are created.

geesefs-0-30-9
Aaron Jacobs 2015-07-29 10:51:24 +10:00
parent d903c709d3
commit 2e422a1305
1 changed files with 19 additions and 16 deletions

View File

@ -86,9 +86,10 @@ type Connection struct {
// State that is maintained for each in-flight op. This is stuffed into the // State that is maintained for each in-flight op. This is stuffed into the
// context that the user uses to reply to the op. // context that the user uses to reply to the op.
type opState struct { type opState struct {
inMsg *buffer.InMessage inMsg *buffer.InMessage
op interface{} outMsg *buffer.OutMessage
opID uint32 // For logging op interface{}
opID uint32 // For logging
} }
// Create a connection wrapping the supplied file descriptor connected to the // Create a connection wrapping the supplied file descriptor connected to the
@ -370,14 +371,14 @@ func (c *Connection) ReadOp() (ctx context.Context, op interface{}, err error) {
// Keep going until we find a request we know how to convert. // Keep going until we find a request we know how to convert.
for { for {
// Read the next message from the kernel. // Read the next message from the kernel.
var m *buffer.InMessage var inMsg *buffer.InMessage
m, err = c.readMessage() inMsg, err = c.readMessage()
if err != nil { if err != nil {
return return
} }
// Convert the message to an op. // Convert the message to an op.
op, err = convertInMessage(m, c.protocol) op, err = convertInMessage(inMsg, c.protocol)
if err != nil { if err != nil {
err = fmt.Errorf("convertInMessage: %v", err) err = fmt.Errorf("convertInMessage: %v", err)
return return
@ -395,9 +396,12 @@ func (c *Connection) ReadOp() (ctx context.Context, op interface{}, err error) {
continue continue
} }
// Allocate an output message up front, to be used later when replying.
outMsg := c.getOutMessage()
// Set up a context that remembers information about this op. // Set up a context that remembers information about this op.
ctx = c.beginOp(m.Header().Opcode, m.Header().Unique) ctx = c.beginOp(inMsg.Header().Opcode, inMsg.Header().Unique)
ctx = context.WithValue(ctx, contextKey, opState{m, op, opID}) ctx = context.WithValue(ctx, contextKey, opState{inMsg, outMsg, op, opID})
// Special case: responding to statfs is required to make mounting work on // Special case: responding to statfs is required to make mounting work on
// OS X. We don't currently expose the capability for the file system to // OS X. We don't currently expose the capability for the file system to
@ -426,14 +430,16 @@ func (c *Connection) Reply(ctx context.Context, opErr error) {
} }
op := state.op op := state.op
m := state.inMsg inMsg := state.inMsg
outMsg := state.outMsg
opID := state.opID opID := state.opID
// Make sure we destroy the message when we're done. // Make sure we destroy the messages when we're done.
defer c.putInMessage(m) defer c.putInMessage(inMsg)
defer c.putOutMessage(outMsg)
// Clean up state for this op. // Clean up state for this op.
c.finishOp(m.Header().Opcode, m.Header().Unique) c.finishOp(inMsg.Header().Opcode, inMsg.Header().Unique)
// Debug logging // Debug logging
if c.debugLogger != nil { if c.debugLogger != nil {
@ -450,8 +456,7 @@ func (c *Connection) Reply(ctx context.Context, opErr error) {
} }
// Send the reply to the kernel, if one is required. // Send the reply to the kernel, if one is required.
outMsg := c.getOutMessage() noResponse := c.kernelResponse(outMsg, inMsg.Header().Unique, op, opErr)
noResponse := c.kernelResponse(outMsg, m.Header().Unique, op, opErr)
if !noResponse { if !noResponse {
err := c.writeMessage(outMsg.Bytes()) err := c.writeMessage(outMsg.Bytes())
@ -459,8 +464,6 @@ func (c *Connection) Reply(ctx context.Context, opErr error) {
c.errorLogger.Printf("writeMessage: %v", err) c.errorLogger.Printf("writeMessage: %v", err)
} }
} }
c.putOutMessage(outMsg)
} }
// Close the connection. Must not be called until operations that were read // Close the connection. Must not be called until operations that were read