commit 17a641b963ac6b11c897f1d84621cfee74b602ed
parent 27938facf38b31090b0292c7495e811e3d9cde1a
Author: Matsuda Kenji <info@mtkn.jp>
Date: Wed, 4 Oct 2023 11:09:56 +0900
mv chatty option into server struct
Diffstat:
6 files changed, 84 insertions(+), 65 deletions(-)
diff --git a/client.go b/client.go
@@ -4,6 +4,7 @@ import (
"context"
"fmt"
"io"
+ "log"
"sync"
)
@@ -14,7 +15,6 @@ type Client struct {
fPool *FidPool
rPool *clientReqPool
tmsgc chan<- Msg
- terrc <-chan error
rerrc <-chan error
}
@@ -26,7 +26,7 @@ func NewClient(mSize uint32, uname string, r io.Reader, w io.Writer) *Client {
fPool: allocFidPool(),
rPool: newClientReqPool(),
}
- c.tmsgc, c.terrc = c.runSpeaker(context.TODO(), w)
+ c.tmsgc = c.runSpeaker(context.TODO(), w)
c.rerrc = c.runListener(context.TODO(), r)
return c
}
@@ -77,27 +77,29 @@ func (c *Client) runListener(ctx context.Context, r io.Reader) <-chan error {
return ec
}
-func (c *Client) runSpeaker(ctx context.Context, w io.Writer) (chan<- Msg, <-chan error) {
+func (c *Client) runSpeaker(ctx context.Context, w io.Writer) chan<- Msg {
mc := make(chan Msg)
- ec := make(chan error)
go func() {
defer close(mc)
- defer close(ec)
for {
select {
case <-ctx.Done():
return
case msg := <-mc:
if err := send(msg, w); err != nil {
- ec <- err
+ req, ok := c.rPool.lookup(msg.Tag())
+ if !ok {
+ log.Printf("speaker: req not found. err: %v", err)
+ }
+ req.errc <- err
}
}
}
}()
- return mc, ec
+ return mc
}
-// tag of tmsg is managed by this function.
+// tag of tmsg is managed by the library.
func (c *Client) transact(ctx context.Context, tmsg Msg) (<-chan Msg, <-chan error) {
req, err := c.rPool.add(tmsg)
if err != nil {
@@ -115,39 +117,47 @@ func (c *Client) transact(ctx context.Context, tmsg Msg) (<-chan Msg, <-chan err
return req.rmsgc, req.errc
}
-func (c *Client) Version(ctx context.Context, mSize uint32, version string) (<-chan *RVersion, <-chan error) {
+func (c *Client) Version(ctx context.Context, mSize uint32, version string) (*RVersion, error) {
tmsg := &TVersion{
- mSize: mSize,
+ mSize: mSize,
version: version,
}
rmsgc, errc := c.transact(ctx, tmsg)
- rmsgc1 := make(chan *RVersion, 1)
- errc1 := make(chan error, 1)
- go func() {
- defer close(rmsgc1)
- defer close(errc1)
- select {
- case rmsg := <-rmsgc:
- switch rmsg := rmsg.(type) {
- case *RVersion:
- rmsgc1<- rmsg
- case *RError:
- errc1<- rmsg.ename
- default:
- panic(fmt.Errorf("invalid R message: %v", rmsg))
- }
- case err := <- errc:
- errc1 <- err
- case <- ctx.Done():
- errc1 <- fmt.Errorf("wait transact: %w", ctx.Err())
+ select {
+ case rmsg := <-rmsgc:
+ switch rmsg := rmsg.(type) {
+ case *RVersion:
+ return rmsg, nil
+ case *RError:
+ return nil, rmsg.ename
+ default:
+ return nil, fmt.Errorf("invalid R message: %v", rmsg)
}
- }()
- return rmsgc1, errc1
+ case err := <-errc:
+ return nil, err
+ case <-ctx.Done():
+ return nil, fmt.Errorf("wait transaction: %w", ctx.Err())
+ }
}
-/*
-func (c *Client) Auth(ctx context.Context, afid uint32, uname, aname string) (<-chan *RAuth, <-chan error) {
-// tmsg := &TAuth{afid: afid, uname: uname}
- return nil, nil
+
+
+func (c *Client) Auth(ctx context.Context, afid uint32, uname, aname string) (*RAuth, error) {
+ tmsg := &TAuth{afid: afid, uname: uname}
+ rmsgc, errc := c.transact(ctx, tmsg)
+ select {
+ case rmsg := <-rmsgc:
+ switch rmsg := rmsg.(type) {
+ case *RAuth:
+ return rmsg, nil
+ case *RError:
+ return nil, rmsg.ename
+ default:
+ return nil, fmt.Errorf("invalid R message: %v", rmsg)
+ }
+ case err := <-errc:
+ return nil, err
+ case <-ctx.Done():
+ return nil, fmt.Errorf("wait transaction: %w", ctx.Err())
+ }
}
-*/
diff --git a/client_test.go b/client_test.go
@@ -7,7 +7,24 @@ import (
"testing"
)
-func TestServerVersion(t *testing.T) {
+func TestTransaction(t *testing.T) {
+ const (
+ mSize = 8192
+ noTag = ^uint16(0)
+ )
+ cr, sw := io.Pipe()
+ sr, cw := io.Pipe()
+
+ server := NewServer(fsys, mSize, sr, sw)
+ Chatty()
+ client := NewClient(mSize, "kenji", cr, cw)
+ bg := context.Background()
+ go server.Serve()
+
+ client.Version(bg, mSize, "9P2000")
+}
+
+func TestClientVersion(t *testing.T) {
const (
mSize = 8192
noTag = ^uint16(0)
@@ -33,15 +50,10 @@ func TestServerVersion(t *testing.T) {
server := NewServer(fsys, mSize, sr, sw)
client := NewClient(mSize, "kenji", cr, cw)
go server.Serve()
- rvc, ec := client.Version(context.TODO(), test.mSize, test.version)
-
- var got *RVersion
- select {
- case got = <-rvc:
- case err := <-ec:
- t.Error(err)
- }
- if !reflect.DeepEqual(got, test.want) {
+ got, err := client.Version(context.TODO(), test.mSize, test.version)
+ if err != nil {
+ t.Errorf("%s: %v", test.name, err)
+ } else if !reflect.DeepEqual(got, test.want) {
t.Errorf("%s: want %v, get %v\n", test.name, test.want, got)
}
}
diff --git a/cmd/disk.go b/cmd/disk.go
@@ -16,9 +16,6 @@ var dFlag = flag.Bool("D", false, "Prints chatty message to the stderr.")
func main() {
flag.Parse()
- if *dFlag {
- lib9p.Chatty()
- }
if flag.NArg() != 1 {
fmt.Fprintf(os.Stderr, "usage: %s [-D] <root>\n", os.Args[0])
@@ -46,5 +43,8 @@ func main() {
func handle(conn net.Conn, disk *diskfs.FS) {
srv := lib9p.NewServer(disk, 8*1024, conn, conn)
+ if *dFlag {
+ srv.Chatty()
+ }
srv.Serve()
}
diff --git a/cmd/iofs.go b/cmd/iofs.go
@@ -16,9 +16,6 @@ var dFlag = flag.Bool("D", false, "Prints chatty message to the stderr.")
func main() {
flag.Parse()
- if *dFlag {
- lib9p.Chatty()
- }
if flag.NArg() != 1 {
fmt.Fprintf(os.Stderr, "usage: %s [-D] <root>\n", os.Args[0])
@@ -44,5 +41,8 @@ func main() {
func handle(conn net.Conn, disk *iofs.FS) {
srv := lib9p.NewServer(disk, 8*1024, conn, conn)
+ if *dFlag {
+ srv.Chatty()
+ }
srv.Serve()
}
diff --git a/cmd/numfs.go b/cmd/numfs.go
@@ -149,9 +149,6 @@ var dFlag = flag.Bool("D", false, "Prints chatty message to the stderr.")
func main() {
flag.Parse()
- if *dFlag {
- lib9p.Chatty()
- }
if flag.NArg() != 0 {
fmt.Fprintf(os.Stderr, "usage: %s [-D]\n", os.Args[0])
@@ -176,5 +173,8 @@ func main() {
func handle(conn net.Conn, fs *numFS) {
srv := lib9p.NewServer(fs, 8*1024, conn, conn)
+ if *dFlag {
+ srv.Chatty()
+ }
srv.Serve()
}
diff --git a/server.go b/server.go
@@ -10,12 +10,6 @@ import (
"sync"
)
-var chatty9P = false
-
-func Chatty() {
- chatty9P = true
-}
-
var (
ErrBotch = fmt.Errorf("bocchi")
ErrPerm = fmt.Errorf("permission denied")
@@ -33,6 +27,7 @@ func setError(r *Req, err error) {
}
type Server struct {
+ chatty9P bool
fs FS
msize uint32
mSizeLock *sync.Mutex
@@ -60,6 +55,8 @@ func NewServer(fsys FS, mSize uint32, r io.Reader, w io.Writer) *Server {
return s
}
+func (s *Server) Chatty() { s.chatty9P = true }
+
func (s *Server) mSize() uint32 {
s.mSizeLock.Lock()
defer s.mSizeLock.Unlock()
@@ -121,7 +118,7 @@ func getReq(r io.Reader, s *Server) (*Req, error) {
log.Printf("unmarshal: %v", err)
req.ifcall = bufMsg(buf)
}
- if chatty9P {
+ if s.chatty9P {
fmt.Fprintf(os.Stderr, "<-- %v\n", req.ifcall)
}
return req, ErrDupTag
@@ -132,14 +129,14 @@ func getReq(r io.Reader, s *Server) (*Req, error) {
req.ifcall, err = unmarshal(buf)
if err != nil {
log.Printf("unmarshal: %v", err)
- if chatty9P {
+ if s.chatty9P {
fmt.Fprintf(os.Stderr, "<-- %v\n", bufMsg(buf))
}
req.ifcall = bufMsg(buf)
return req, err
}
- if chatty9P {
+ if s.chatty9P {
fmt.Fprintf(os.Stderr, "<-- %v\n", req.ifcall)
}
return req, nil
@@ -875,7 +872,7 @@ func respond(r *Req, err error) {
log.Fatalf("speak: %v", err)
}()
- if chatty9P {
+ if r.srv.chatty9P {
fmt.Fprintf(os.Stderr, "--> %s\n", r.ofcall)
}
}