func (log *Logger) Log9p(f *g9p.Fcall) { if f == nil { http.Handle(log.path, nil) stats.mu.Lock() for e := stats.conns.Front(); e != nil; e = e.Next() { if e.Value == log { stats.conns.Remove(e) break } } stats.mu.Unlock() return } log.mu.Lock() if f.IsTmsg() { log.npend++ log.nreqs++ if log.npend > log.maxpend { log.maxpend = log.npend } log.tmsgsize += int64(f.Size) } else { log.rmsgsize += int64(f.Size) // TODO: cater for flushes log.npend-- } if log.maxHist != 0 && f.Type != 0 { nf := new(g9p.Fcall) *nf = *f if log.flags&Packets != 0 { nf.Pkt = make([]byte, len(f.Pkt)) copy(nf.Pkt, f.Pkt) } else { nf.Pkt = nil } log.history.PushFront(nf) if log.history.Len() > log.maxHist && log.maxHist != -1 { log.history.Remove(log.history.Back()) } } log.mu.Unlock() }
func (client *Client) recv() { var err error buf := make([]byte, client.msize*8) pos := 0 for { if len(buf) < int(client.msize) { resize: b := make([]byte, client.msize*8) copy(b, buf[0:pos]) buf = b b = nil } n, oerr := client.conn.Read(buf[pos:len(buf)]) if oerr != nil || n == 0 { err = &g9p.Error{oerr.String(), syscall.EIO} goto closed } pos += n for pos > 4 { sz, _ := g9p.Gint32(buf) if pos < int(sz) { if len(buf) < int(sz) { goto resize } break } fc, oerr, fcsize := g9p.Unpack(buf, client.dotu) client.mu.Lock() if oerr != nil { err = oerr client.conn.Close() client.mu.Unlock() goto closed } if client.log != nil { f := new(g9p.Fcall) *f = *fc f.Pkt = nil client.log.Log9p(f) } var r *req = nil for r = client.reqfirst; r != nil; r = r.next { if r.tc.Tag == fc.Tag { break } } if r == nil { err = errors.New("unexpected response") client.conn.Close() client.mu.Unlock() goto closed } r.rc = fc if r.prev != nil { r.prev.next = r.next } else { client.reqfirst = r.next } if r.next != nil { r.next.prev = r.prev } else { client.reqlast = r.prev } client.mu.Unlock() if r.tc.Type != r.rc.Type-1 { if r.rc.Type != g9p.Rerror { r.err = &g9p.Error{"invalid response", syscall.EINVAL} log.Printf(fmt.Sprintf("TTT %v", r.tc)) log.Printf(fmt.Sprintf("RRR %v", r.rc)) } else { if r.err != nil { r.err = &g9p.Error{r.rc.Error, int(r.rc.Errornum)} } } } r.done <- r pos -= fcsize buf = buf[fcsize:] } } closed: log.Printf("recv done\n") client.finished <- err /* send error to all pending requests */ client.mu.Lock() client.reqfirst = nil client.reqlast = nil client.mu.Unlock() }