Example #1
0
int main()
{
  static const char *fname="main";
  hashItr_t itr;
  void * data;

  addhash(0x01010001,0x1234);
  addhash(0x01060001,0x4567);
  addhash(0x01060002,0x9324);
  addhash(0x01070002,0x4321);
  addhash(0x01070004,0x2134);
  addhash(0x01080005,0x1324);
  addhash(0x01030001,0x1243);
  hashstats(7);

  hashItrInit(&itr);
  while ( data = hashItrNext(&itr) ) {
    CCAPPDEBUG(DEB_F_PREFIX"Itr found %lx", DEB_F_PREFIX_ARGS(SIP_SES_HASH, fname), data);
  }

  CCAPPDEBUG(DEB_F_PREFIX"%lx", DEB_F_PREFIX_ARGS(SIP_SES_HASH, fname), findhash(0x01010001));
  CCAPPDEBUG(DEB_F_PREFIX"%lx", DEB_F_PREFIX_ARGS(SIP_SES_HASH, fname), findhash(0x01060001));
  CCAPPDEBUG(DEB_F_PREFIX"%lx", DEB_F_PREFIX_ARGS(SIP_SES_HASH, fname), findhash(0x01060002));
  CCAPPDEBUG(DEB_F_PREFIX"%lx", DEB_F_PREFIX_ARGS(SIP_SES_HASH, fname), findhash(0x01070002));
  CCAPPDEBUG(DEB_F_PREFIX"%lx", DEB_F_PREFIX_ARGS(SIP_SES_HASH, fname), findhash(0x01070004));
  CCAPPDEBUG(DEB_F_PREFIX"%lx", DEB_F_PREFIX_ARGS(SIP_SES_HASH, fname), findhash(0x01080005));
  CCAPPDEBUG(DEB_F_PREFIX"%lx", DEB_F_PREFIX_ARGS(SIP_SES_HASH, fname), findhash(0x01030001));

  delhash(0x01030001);
  delhash(0x01060001);
  hashstats(7);

  hashItrInit(&itr);
  while ( data = hashItrNext(&itr) ) {
    CCAPPDEBUG(DEB_F_PREFIX"Itr found %lx", DEB_F_PREFIX_ARGS(SIP_SES_HAS, fname), data);
  }

  CCAPPDEBUG(DEB_F_PREFIX"%lx", DEB_F_PREFIX_ARGS(SIP_SES_HASH, fname), findhash(0x01010001));
  CCAPPDEBUG(DEB_F_PREFIX"%lx", DEB_F_PREFIX_ARGS(SIP_SES_HASH, fname), findhash(0x01060001));
  CCAPPDEBUG(DEB_F_PREFIX"%lx", DEB_F_PREFIX_ARGS(SIP_SES_HASH, fname), findhash(0x01060002));
  CCAPPDEBUG(DEB_F_PREFIX"%lx", DEB_F_PREFIX_ARGS(SIP_SES_HASH, fname), findhash(0x01070002));
  CCAPPDEBUG(DEB_F_PREFIX"%lx", DEB_F_PREFIX_ARGS(SIP_SES_HASH, fname), findhash(0x01070004));
  CCAPPDEBUG(DEB_F_PREFIX"%lx", DEB_F_PREFIX_ARGS(SIP_SES_HASH, fname), findhash(0x01080005));
  CCAPPDEBUG(DEB_F_PREFIX"%lx", DEB_F_PREFIX_ARGS(SIP_SES_HASH, fname), findhash(0x01030001));
}
Example #2
0
int
xopenfd(Msg *m)
{
	char errs[ERRMAX];
	int n, p[2];
	Conn *nc;

	if(pipe(p) < 0){
		rerrstr(errs, sizeof errs);
		err(m, errs);
		/* XXX return here? */
	}
	if(verbose) fprint(2, "%T xopen pipe %d %d...", p[0], p[1]);

	/* now we're committed. */

	/* a new connection for this fid */
	nc = emalloc(sizeof(Conn));
	nc->internal = chancreate(sizeof(void*), 0);

	/* a ref for us */
	nc->fdfid = m->fid;
	m->fid->ref++;
	nc->fdfid->openfd++;
	nc->fdmode = m->tx.mode;
	nc->fd = p[0];

	/* a thread to tend the pipe */
	threadcreate(openfdthread, nc, STACK);

	/* if mode is ORDWR, that openfdthread will write; start a reader */
	if((m->tx.mode&3) == ORDWR){
		nc = emalloc(sizeof(Conn));
		nc->internal = chancreate(sizeof(void*), 0);
		nc->fdfid = m->fid;
		m->fid->ref++;
		nc->fdfid->openfd++;
		nc->fdmode = OREAD;
		nc->fd = dup(p[0], -1);
		threadcreate(openfdthread, nc, STACK);
	}

	/* steal fid from other connection */
	if(delhash(m->c->fid, m->fid->cfid, m->fid) == 0)
		fidput(m->fid);

	/* rewrite as Ropenfd */
	m->rx.type = Ropenfd;
	n = GBIT32(m->rpkt);
	m->rpkt = erealloc(m->rpkt, n+4);
	PBIT32(m->rpkt+n, p[1]);
	n += 4;
	PBIT32(m->rpkt, n);
	m->rpkt[4] = Ropenfd;
	m->rx.unixfd = p[1];
	return 0;
}
Example #3
0
void
connoutthread(void *arg)
{
	int err;
	Conn *c;
	Msg *m, *om;
	Ioproc *io;

	c = arg;
	io = ioproc();
	threadsetname("connout %s", c->dir);
	while((m = recvq(c->outq)) != nil){
		err = m->tx.type+1 != m->rx.type;
		if(!err && m->isopenfd)
			if(xopenfd(m) < 0)
				continue;
		switch(m->tx.type){
		case Tflush:
			om = m->oldm;
			if(om)
				if(delhash(om->c->tag, om->ctag, om) == 0)
					msgput(om);
			break;
		case Tclunk:
		case Tremove:
			if(m->fid)
				if(delhash(m->c->fid, m->fid->cfid, m->fid) == 0)
					fidput(m->fid);
			break;
		case Tauth:
			if(err && m->afid){
				if(verbose) fprint(2, "%T auth error\n");
				if(delhash(m->c->fid, m->afid->cfid, m->afid) == 0)
					fidput(m->afid);
			}
			break;
		case Tattach:
			if(err && m->fid)
				if(delhash(m->c->fid, m->fid->cfid, m->fid) == 0)
					fidput(m->fid);
			break;
		case Twalk:
			if(err || m->rx.nwqid < m->tx.nwname)
			if(m->tx.fid != m->tx.newfid && m->newfid)
				if(delhash(m->c->fid, m->newfid->cfid, m->newfid) == 0)
					fidput(m->newfid);
			break;
		case Tread:
			break;
		case Tstat:
			break;
		case Topen:
		case Tcreate:
			m->fid->isdir = (m->rx.qid.type & QTDIR);
			break;
		}
		if(delhash(m->c->tag, m->ctag, m) == 0)
			msgput(m);
		if(verbose > 1) fprint(2, "%T fd#%d <- %F\n", c->fd, &m->rx);
		rewritehdr(&m->rx, m->rpkt);
		if(mwrite9p(io, c->fd, m->rpkt) < 0)
			if(verbose) fprint(2, "%T write error: %r\n");
		msgput(m);
		if(c->inputstalled && c->nmsg < MAXMSG)
			nbsendp(c->inc, 0);
	}
	closeioproc(io);
	free(c->outq);
	c->outq = nil;
	sendp(c->outqdead, nil);
}
Example #4
0
void
connthread(void *arg)
{
	int i, fd;
	Conn *c;
	Hash *h, *hnext;
	Msg *m, *om, *mm, sync;
	Fid *f;
	Ioproc *io;

	c = arg;
	threadsetname("conn %s", c->dir);
	io = ioproc();
	fd = ioaccept(io, c->fd, c->dir);
	if(fd < 0){
		if(verbose) fprint(2, "%T accept %s: %r\n", c->dir);
		goto out;
	}
	close(c->fd);
	c->fd = fd;
	threadcreate(connoutthread, c, STACK);
	while((m = mread9p(io, c->fd)) != nil){
		if(verbose > 1) fprint(2, "%T fd#%d -> %F\n", c->fd, &m->tx);
		m->c = c;
		m->ctag = m->tx.tag;
		c->nmsg++;
		if(verbose > 1) fprint(2, "%T fd#%d: new msg %p\n", c->fd, m);
		if(puthash(c->tag, m->tx.tag, m) < 0){
			err(m, "duplicate tag");
			continue;
		}
		msgincref(m);
		switch(m->tx.type){
		case Tversion:
			m->rx.tag = m->tx.tag;
			m->rx.msize = m->tx.msize;
			if(m->rx.msize > msize)
				m->rx.msize = msize;
			m->rx.version = "9P2000";
			m->rx.type = Rversion;
			send9pmsg(m);
			continue;
		case Tflush:
			if((m->oldm = gethash(c->tag, m->tx.oldtag)) == nil){
				m->rx.tag = m->tx.tag;
				m->rx.type = Rflush;
				send9pmsg(m);
				continue;
			}
			msgincref(m->oldm);
			break;
		case Tattach:
			m->afid = nil;
			if(m->tx.afid != NOFID
			&& (m->afid = gethash(c->fid, m->tx.afid)) == nil){
				err(m, "unknown fid");
				continue;
			}
			if(m->afid)
				m->afid->ref++;
			m->fid = fidnew(m->tx.fid);
			if(puthash(c->fid, m->tx.fid, m->fid) < 0){
				err(m, "duplicate fid");
				continue;
			}
			m->fid->ref++;
			if(attached && m->afid==nil){
				if(m->tx.aname[0] && strcmp(xaname, m->tx.aname) != 0){
					err(m, "invalid attach name");
					continue;
				}
				m->tx.afid = xafid;
				m->tx.aname = xaname;
				m->tx.uname = getuser();	/* what srv.c used */
				repack(&m->tx, &m->tpkt);
			}
			break;
		case Twalk:
			if((m->fid = gethash(c->fid, m->tx.fid)) == nil){
				err(m, "unknown fid");
				continue;
			}
			m->fid->ref++;
			if(m->tx.newfid == m->tx.fid){
				m->fid->ref++;
				m->newfid = m->fid;
			}else{
				m->newfid = fidnew(m->tx.newfid);
				if(puthash(c->fid, m->tx.newfid, m->newfid) < 0){
					err(m, "duplicate fid");
					continue;
				}
				m->newfid->ref++;
			}
			break;
		case Tauth:
			if(attached){
				err(m, "authentication not required");
				continue;
			}
			if(noauth){
				err(m, "authentication rejected");
				continue;
			}
			m->afid = fidnew(m->tx.afid);
			if(puthash(c->fid, m->tx.afid, m->afid) < 0){
				err(m, "duplicate fid");
				continue;
			}
			m->afid->ref++;
			break;
		case Tcreate:
			if(m->tx.perm&(DMSYMLINK|DMDEVICE|DMNAMEDPIPE|DMSOCKET)){
				err(m, "unsupported file type");
				continue;
			}
			goto caseTopen;
		case Topenfd:
			if(m->tx.mode&~(OTRUNC|3)){
				err(m, "bad openfd mode");
				continue;
			}
			m->isopenfd = 1;
			m->tx.type = Topen;
			m->tpkt[4] = Topen;
			/* fall through */
		caseTopen:
		case Topen:
		case Tclunk:
		case Tread:
		case Twrite:
		case Tremove:
		case Tstat:
		case Twstat:
			if((m->fid = gethash(c->fid, m->tx.fid)) == nil){
				err(m, "unknown fid");
				continue;
			}
			m->fid->ref++;
			break;
		}

		/* have everything - translate and send */
		m->c = c;
		m->ctag = m->tx.tag;
		m->tx.tag = m->tag;
		if(m->fid)
			m->tx.fid = m->fid->fid;
		if(m->newfid)
			m->tx.newfid = m->newfid->fid;
		if(m->afid)
			m->tx.afid = m->afid->fid;
		if(m->oldm)
			m->tx.oldtag = m->oldm->tag;
		/* reference passes to outq */
		sendq(outq, m);
		while(c->nmsg >= MAXMSG){
			c->inputstalled = 1;
			recvp(c->inc);
		}
	}

	if(verbose) fprint(2, "%T fd#%d eof; flushing conn\n", c->fd);

	/* flush all outstanding messages */
	for(i=0; i<NHASH; i++){
		while((h = c->tag[i]) != nil){
			om = h->v;
			msgincref(om); /* for us */
			m = msgnew(0);
			m->internal = 1;
			m->c = c;
			c->nmsg++;
			m->tx.type = Tflush;
			m->tx.tag = m->tag;
			m->tx.oldtag = om->tag;
			m->oldm = om;
			msgincref(om);
			msgincref(m);	/* for outq */
			sendomsg(m);
			mm = recvp(c->internal);
			assert(mm == m);
			msgput(m);	/* got from recvp */
			msgput(m);	/* got from msgnew */
			if(delhash(c->tag, om->ctag, om) == 0)
				msgput(om);	/* got from hash table */
			msgput(om);	/* got from msgincref */
		}
	}

	/*
	 * outputthread has written all its messages
	 * to the remote connection (because we've gotten all the replies!),
	 * but it might not have gotten a chance to msgput
	 * the very last one.  sync up to make sure.
	 */
	memset(&sync, 0, sizeof sync);
	sync.sync = 1;
	sync.c = c;
	sendq(outq, &sync);
	recvp(c->outqdead);

	/* everything is quiet; can close the local output queue. */
	sendq(c->outq, nil);
	recvp(c->outqdead);

	/* should be no messages left anywhere. */
	assert(c->nmsg == 0);

	/* clunk all outstanding fids */
	for(i=0; i<NHASH; i++){
		for(h=c->fid[i]; h; h=hnext){
			f = h->v;
			m = msgnew(0);
			m->internal = 1;
			m->c = c;
			c->nmsg++;
			m->tx.type = Tclunk;
			m->tx.tag = m->tag;
			m->tx.fid = f->fid;
			m->fid = f;
			f->ref++;
			msgincref(m);
			sendomsg(m);
			mm = recvp(c->internal);
			assert(mm == m);
			msgclear(m);
			msgput(m);	/* got from recvp */
			msgput(m);	/* got from msgnew */
			fidput(f);	/* got from hash table */
			hnext = h->next;
			free(h);
		}
	}

out:
	closeioproc(io);
	assert(c->nmsg == 0);
	assert(c->nfid == 0);
	close(c->fd);
	chanfree(c->internal);
	c->internal = 0;
	chanfree(c->inc);
	c->inc = 0;
	free(c->inq);
	c->inq = 0;
	free(c);
}