aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/libventi/packet.c112
-rw-r--r--src/libventi/send.c15
-rw-r--r--src/libventi/server.c10
3 files changed, 116 insertions, 21 deletions
diff --git a/src/libventi/packet.c b/src/libventi/packet.c
index a10b7b45..94d3b910 100644
--- a/src/libventi/packet.c
+++ b/src/libventi/packet.c
@@ -45,13 +45,15 @@ struct Frag
Frag *next;
void (*free)(void*);
void *a;
+ Packet *p; /* parent packet, for debugging only */
};
struct Packet
{
int size;
int asize; /* allocated memory - greater than size unless foreign frags */
-
+ ulong pc;
+
Packet *next;
Frag *first;
@@ -73,6 +75,14 @@ static char EPacketSize[] = "bad packet size";
static char EPacketOffset[] = "bad packet offset";
static char EBadSize[] = "bad size";
+static void checkpacket(Packet*);
+
+/*
+ * the free list is primarily for speed, but it is
+ * also necessary for packetsplit that packets
+ * are never freed -- a packet can contain a different
+ * packet's local fragments, thanks to packetsplit!
+ */
static struct {
Lock lk;
Packet *packet;
@@ -88,7 +98,7 @@ static struct {
#define FRAGSIZE(f) ((f)->wp - (f)->rp)
#define FRAGASIZE(f) ((f)->mem ? (f)->mem->ep - (f)->mem->bp : 0)
-#define NOTFREE(p) assert((p)->size>=0)
+#define NOTFREE(p) assert((p)->size>=0)/*; checkpacket(p)*/
Packet *
packetalloc(void)
@@ -112,9 +122,11 @@ packetalloc(void)
p->first = nil;
p->last = nil;
p->next = nil;
+ p->pc = getcallerpc((char*)&p+8); /* might not work, but fine */
//if(0)fprint(2, "packetalloc %p from %08lux %08lux %08lux\n", p, *((uint*)&p+2), *((uint*)&p+3), *((uint*)&p+4));
+ NOTFREE(p);
return p;
}
@@ -123,20 +135,21 @@ packetfree(Packet *p)
{
Frag *f, *ff;
-if(0)fprint(2, "packetfree %p from %08lux\n", p, getcallerpc(&p));
+//if(1)fprint(2, "packetfree %p from %08lux\n", p, getcallerpc(&p));
if(p == nil)
return;
NOTFREE(p);
- p->size = -1;
+ p->pc = getcallerpc(&p);
for(f=p->first; f!=nil; f=ff) {
ff = f->next;
fragfree(f);
}
- p->first = nil;
- p->last = nil;
+ p->first = (void*)0xDeadBeef;
+ p->last = (void*)0xDeadBeef;
+ p->size = -1;
lock(&freelist.lk);
p->next = freelist.packet;
@@ -157,8 +170,11 @@ packetdup(Packet *p, int offset, int n)
}
pp = packetalloc();
- if(n == 0)
+ pp->pc = getcallerpc(&p);
+ if(n == 0){
+ NOTFREE(pp);
return pp;
+ }
pp->size = n;
@@ -187,6 +203,8 @@ packetdup(Packet *p, int offset, int n)
ff->next = nil;
pp->last = ff;
+ NOTFREE(pp);
+ NOTFREE(p);
return pp;
}
@@ -204,8 +222,11 @@ packetsplit(Packet *p, int n)
}
pp = packetalloc();
- if(n == 0)
+ pp->pc = getcallerpc(&p);
+ if(n == 0){
+ NOTFREE(pp);
return pp;
+ }
pp->size = n;
p->size -= n;
@@ -214,22 +235,28 @@ packetsplit(Packet *p, int n)
n -= FRAGSIZE(f);
p->asize -= FRAGASIZE(f);
pp->asize += FRAGASIZE(f);
+ f->p = pp;
ff = f;
}
/* split shared frag */
if(n > 0) {
+ f->p = pp;
ff = f;
- f = fragdup(pp, ff);
+ f = fragdup(p, ff);
pp->asize += FRAGASIZE(ff);
- ff->next = nil;
ff->wp = ff->rp + n;
f->rp += n;
}
pp->first = p->first;
pp->last = ff;
+ ff->next = nil;
p->first = f;
+ if(f == nil || f->next == nil)
+ p->last = f;
+ NOTFREE(pp);
+ NOTFREE(p);
return pp;
}
@@ -270,6 +297,7 @@ packettrim(Packet *p, int offset, int n)
}
p->first = p->last = nil;
p->asize = 0;
+ NOTFREE(p);
return 0;
}
@@ -301,6 +329,7 @@ packettrim(Packet *p, int offset, int n)
ff = f->next;
fragfree(f);
}
+ NOTFREE(p);
return 0;
}
@@ -325,6 +354,7 @@ packetheader(Packet *p, int n)
if(n <= f->rp - m->bp)
if(m->ref == 1 || memhead(m, f->rp, n) >= 0) {
f->rp -= n;
+ NOTFREE(p);
return f->rp;
}
}
@@ -335,6 +365,7 @@ packetheader(Packet *p, int n)
if(p->first == nil)
p->last = f;
p->first = f;
+ NOTFREE(p);
return f->rp;
}
@@ -360,6 +391,7 @@ packettrailer(Packet *p, int n)
if(n <= m->ep - f->wp)
if(m->ref == 1 || memtail(m, f->wp, n) >= 0) {
f->wp += n;
+ NOTFREE(p);
return f->wp - n;
}
}
@@ -372,6 +404,7 @@ packettrailer(Packet *p, int n)
else
p->last->next = f;
p->last = f;
+ NOTFREE(p);
return f->rp;
}
@@ -414,6 +447,7 @@ packetprefix(Packet *p, uchar *buf, int n)
n -= nn;
memmove(f->rp, buf+n, nn);
}
+ NOTFREE(p);
}
void
@@ -458,28 +492,35 @@ packetappend(Packet *p, uchar *buf, int n)
buf += nn;
n -= nn;
}
- return;
+ NOTFREE(p);
}
void
packetconcat(Packet *p, Packet *pp)
{
+ Frag *f;
+
NOTFREE(p);
NOTFREE(pp);
if(pp->size == 0)
return;
p->size += pp->size;
p->asize += pp->asize;
+ for(f=pp->first; f; f=f->next)
+ f->p = p;
if(p->first != nil)
p->last->next = pp->first;
else
p->first = pp->first;
+
p->last = pp->last;
pp->size = 0;
pp->asize = 0;
pp->first = nil;
pp->last = nil;
+ NOTFREE(p);
+ NOTFREE(pp);
}
uchar *
@@ -508,8 +549,10 @@ packetpeek(Packet *p, uchar *buf, int offset, int n)
offset -= FRAGSIZE(f);
/* easy case */
- if(offset + n <= FRAGSIZE(f))
+ if(offset + n <= FRAGSIZE(f)){
+ NOTFREE(p);
return f->rp + offset;
+ }
for(b=buf; n>0; n -= nn) {
nn = FRAGSIZE(f) - offset;
@@ -521,6 +564,7 @@ packetpeek(Packet *p, uchar *buf, int offset, int n)
b += nn;
}
+ NOTFREE(p);
return buf;
}
@@ -740,6 +784,7 @@ fragalloc(Packet *p, int n, int pos, Frag *next)
Found:
f->next = next;
+ f->p = p;
if(n == 0){
f->mem = 0;
@@ -764,6 +809,7 @@ packetforeign(uchar *buf, int n, void (*free)(void *a), void *a)
Frag *f;
p = packetalloc();
+ p->pc = getcallerpc(&buf);
f = fragalloc(p, 0, 0, nil);
f->free = free;
f->a = a;
@@ -772,7 +818,9 @@ packetforeign(uchar *buf, int n, void (*free)(void *a), void *a)
f->wp = buf+n;
p->first = f;
+ p->last = f;
p->size = n;
+ NOTFREE(p);
return p;
}
@@ -794,12 +842,23 @@ fragdup(Packet *p, Frag *f)
}
ff = fragalloc(p, 0, 0, nil);
- *ff = *f;
+ ff->mem = f->mem;
+ ff->rp = f->rp;
+ ff->wp = f->wp;
+ ff->next = f->next;
+
+ /*
+ * We can't duplicate these -- there's no dup function.
+ */
+ assert(f->free==nil && f->a==nil);
+
if(m){
lock(&m->lk);
m->ref++;
unlock(&m->lk);
}
+
+
return ff;
}
@@ -898,6 +957,7 @@ memfree(Mem *m)
unlock(&m->lk);
assert(m->ref == 0);
+/* memset(m->bp, 0xEF, m->ep-m->bp); */
switch(m->ep - m->bp) {
default:
assert(0);
@@ -919,6 +979,8 @@ memfree(Mem *m)
static int
memhead(Mem *m, uchar *rp, int n)
{
+ fprint(2, "memhead called\n");
+ abort();
lock(&m->lk);
if(m->rp != rp) {
unlock(&m->lk);
@@ -932,6 +994,8 @@ memhead(Mem *m, uchar *rp, int n)
static int
memtail(Mem *m, uchar *wp, int n)
{
+ fprint(2, "memtail called\n");
+ abort();
lock(&m->lk);
if(m->wp != wp) {
unlock(&m->lk);
@@ -941,3 +1005,25 @@ memtail(Mem *m, uchar *wp, int n)
unlock(&m->lk);
return 0;
}
+
+static void
+checkpacket(Packet *p)
+{
+ int s, as;
+ Frag *f;
+ Frag *ff;
+
+ s = 0;
+ as = 0;
+ ff=p->first;
+ for(f=p->first; f; ff=f,f=f->next){
+ assert(f->p == p);
+ s += FRAGSIZE(f);
+ as += FRAGASIZE(f);
+ }
+ assert(s == p->size);
+ assert(as == p->asize);
+ if(p->first)
+ assert(ff==p->last);
+}
+
diff --git a/src/libventi/send.c b/src/libventi/send.c
index fd6fa57a..726c4027 100644
--- a/src/libventi/send.c
+++ b/src/libventi/send.c
@@ -1,15 +1,20 @@
#include <u.h>
+#include <errno.h>
#include <libc.h>
#include <venti.h>
#include "queue.h"
+long ventisendbytes, ventisendpackets;
+long ventirecvbytes, ventirecvpackets;
+
static int
_vtsend(VtConn *z, Packet *p)
{
IOchunk ioc;
int n;
uchar buf[2];
-
+
+
if(z->state != VtStateConnected) {
werrstr("session not connected");
return -1;
@@ -25,6 +30,8 @@ _vtsend(VtConn *z, Packet *p)
buf[0] = n>>8;
buf[1] = n;
packetprefix(p, buf, 2);
+ ventisendbytes += n+2;
+ ventisendpackets++;
for(;;){
n = packetfragments(p, &ioc, 1, 0);
@@ -62,7 +69,7 @@ _vtrecv(VtConn *z)
if(0) fprint(2, "%d read hdr\n", getpid());
n = read(z->infd, b, MaxFragSize);
if(0) fprint(2, "%d got %d (%r)\n", getpid(), n);
- if(n <= 0)
+ if(n==0 || (n<0 && errno!=EINTR))
goto Err;
size += n;
packettrim(p, 0, size);
@@ -84,9 +91,11 @@ _vtrecv(VtConn *z)
if(n > 0)
size += n;
packettrim(p, 0, size);
- if(n <= 0)
+ if(n==0 || (n<0 && errno!=EINTR))
goto Err;
}
+ ventirecvbytes += len;
+ ventirecvpackets++;
p = packetsplit(p, len);
return p;
Err:
diff --git a/src/libventi/server.c b/src/libventi/server.c
index 8aa95798..91846446 100644
--- a/src/libventi/server.c
+++ b/src/libventi/server.c
@@ -104,14 +104,14 @@ connproc(void *v)
int fd;
static int first=1;
-if(first){
+if(first && chattyventi){
first=0;
fmtinstall('F', vtfcallfmt);
}
r = nil;
sc = v;
sc->c = nil;
- fprint(2, "new call %s on %d\n", sc->dir, sc->ctl);
+ if(0) fprint(2, "new call %s on %d\n", sc->dir, sc->ctl);
fd = accept(sc->ctl, sc->dir);
close(sc->ctl);
if(fd < 0){
@@ -130,7 +130,7 @@ if(first){
goto out;
}
- fprint(2, "new proc %s\n", sc->dir);
+ if(0) fprint(2, "new proc %s\n", sc->dir);
proccreate(vtsendproc, c, STACK);
qlock(&c->lk);
while(!c->writeq)
@@ -160,14 +160,14 @@ if(first){
r = nil;
}
- fprint(2, "eof on %s\n", sc->dir);
+ if(0) fprint(2, "eof on %s\n", sc->dir);
out:
if(r){
vtfcallclear(&r->tx);
vtfree(r);
}
- fprint(2, "freed %s\n", sc->dir);
+ if(0) fprint(2, "freed %s\n", sc->dir);
scdecref(sc);
return;
}