commit 95998a18c96f7235502e685c39d9f2bee90f94ae
parent 892e8c38583540354f083ef33f839661b04040f7
Author: Matsuda Kenji <info@mtkn.jp>
Date: Mon, 30 Oct 2023 07:30:48 +0900
add error in Req
Diffstat:
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() {