예제 #1
0
파일: stats.go 프로젝트: zenoss/rog-go
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()
}
예제 #2
0
파일: client.go 프로젝트: zenoss/rog-go
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()
}