lib9p

Go 9P library.
Log | Files | Refs | LICENSE

commit 95998a18c96f7235502e685c39d9f2bee90f94ae
parent 892e8c38583540354f083ef33f839661b04040f7
Author: Matsuda Kenji <info@mtkn.jp>
Date:   Mon, 30 Oct 2023 07:30:48 +0900

add error in Req

Diffstat:
Mreq.go | 1+
Mserver.go | 41+++++++++++++++++++----------------------
2 files changed, 20 insertions(+), 22 deletions(-)

diff --git a/req.go b/req.go @@ -16,6 +16,7 @@ type Req struct { Oldreq *Req pool *ReqPool Cancel context.CancelFunc + err error } // flush cancels the Req by calling r.cancel. diff --git a/server.go b/server.go @@ -53,7 +53,7 @@ type Server struct { // listener goroutine. listenChan <-chan *Req // The error channel the listener goroutine reports any error. - listenErrChan <-chan error + //listenErrChan <-chan error // The channel to which outgoing replies are sent to the speaker // goroutine. @@ -79,7 +79,7 @@ func NewServer(fsys FS, mSize uint32, r io.Reader, w io.Writer) *Server { fPool: newFidPool(), rPool: newReqPool(), } - s.listenChan, s.listenErrChan = s.runListener(r) + s.listenChan = s.runListener(r) s.speakChan, s.speakErrChan = s.runSpeaker(w) return s } @@ -107,21 +107,15 @@ func (s *Server) setMSize(mSize uint32) { // It reports any error to the returned chan of error. // TODO: pass context.Context and stop the goroutine with the Context being // canceled. -func (s *Server) runListener(r io.Reader) (<-chan *Req, <-chan error) { +func (s *Server) runListener(r io.Reader) <-chan *Req { rc := make(chan *Req) - ec := make(chan error) go func() { defer close(rc) - defer close(ec) for { - req, err := getReq(r, s) - if err != nil { - ec <- err - } - rc <- req + rc <- getReq(r, s) } }() - return rc, ec + return rc } // runSpeaker runs the speaker goroutine. @@ -147,15 +141,16 @@ func (s *Server) runSpeaker(w io.Writer) (chan<- *Req, <-chan error) { } // GetReq reads 9P message from r, allocates Req and returns it. +// Any error it encounters is embedded into the Req struct. // This function is called only by the server's listener goroutine, // and does not need to lock r. -func getReq(r io.Reader, s *Server) (*Req, error) { +func getReq(r io.Reader, s *Server) *Req { ifcall, err := RecvMsg(r) if err != nil { if err == io.EOF { - return nil, err + return &Req{err: err} } - return nil, fmt.Errorf("readMsg: %v", err) + return &Req{err: fmt.Errorf("readMsg: %v", err)} } req, err := s.rPool.add(ifcall.GetTag()) if err != nil { @@ -163,10 +158,11 @@ func getReq(r io.Reader, s *Server) (*Req, error) { req := new(Req) req.Srv = s req.Ifcall = ifcall + req.err = ErrDupTag if s.chatty9P { fmt.Fprintf(os.Stderr, "<-- %v\n", req.Ifcall) } - return req, ErrDupTag + return req } req.Srv = s req.Tag = ifcall.GetTag() @@ -177,7 +173,7 @@ func getReq(r io.Reader, s *Server) (*Req, error) { if s.chatty9P { fmt.Fprintf(os.Stderr, "<-- %v\n", req.Ifcall) } - return req, nil + return req } // sVersion processes Tversion message. @@ -904,13 +900,14 @@ L: // TODO: handle error log.Printf("speak: %v", err) continue L - case err := <-s.listenErrChan: - log.Printf("listen: %v", err) - if err == io.EOF { - break L - } - continue L case r := <-s.listenChan: + if r.err != nil { + log.Printf("listen: %v", r.err) + if r.err == io.EOF { + break L + } + continue L + } ctx1, cancel := context.WithCancel(ctx) r.Cancel = cancel go func() {